PHP seçeneği 'cgi.fix_pathinfo' Nginx + PHP-FPM ile gerçekten tehlikeli mi?


51

Olmuştur bir sürü ait konuşurken bir güvenlik sorunu akrabası hakkında cgi.fix_pathinfoNginx (genellikle PHP FPM, hızlı CGI) ile kullanıldığında PHP seçeneği.

Sonuç olarak, varsayılan nginx yapılandırma dosyası şöyle derdi:

# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

Bununla birlikte, şimdi, "resmi" Nginx wiki , yukarıdaki PHP seçeneğini devre dışı bırakmadan PATH_INFO'nun doğru bir şekilde kullanılabileceğini belirtir . Ne olmuş yani?

Sorular

  • Ne yaptığını açıkça açıklayabilir misin cgi.fix_pathinfo? ( resmi doktor sadece şöyle der : "PATH_INFO hakkında daha fazla bilgi için, CGI teknik özelliklerine bakın")
  • PHP bu PATH_INFOve SCRIPT_FILENAMEdeğişkenlerle gerçekten ne yapacak ?
  • Nginx ile neden ve nasıl tehlikeli olabilir? ( ayrıntılı örnekler)
  • Sorun, bu programların son sürümlerinde hala mevcut mu?
  • Apache savunmasız mıdır?

Her adımda konuyu anlamaya çalışıyorum. Örneğin, php-fpm Unix soketini kullanmanın neden bu sorunu önleyebileceğini anlamıyorum .


1
PATH_INFO ve PATH_TRANSLATED arasındaki farkı anlayarak kendi sorunuzu cevaplayabilirsiniz: blogs.msdn.com/b/david.wang/archive/2005/08/04/…
Giovanni Tirloni

Yanıtlar:


79

TL; DR - Düzeltme (ihtiyacınız olmayabilir) ÇOK BASİT ve bu cevabın sonunda.

Özel sorularınızı ele almaya çalışacağım, ancak PATH_INFO'nun ne olduğu hakkındaki yanlış anlamalarınız soruları biraz yanlış yapar.

  • İlk soru "Bu yol bilgisi işi nedir?" Olmalı.

  • Bir sonraki sorunuz olmalı: "PHP neyi PATH_INFOve ne olduğunu nasıl belirler SCRIPT_FILENAME?"

    • PHP'nin daha önceki sürümleri saftı ve teknik olarak bile desteklemediler PATH_INFO, bu nedenle olması gereken PATH_INFOşey SCRIPT_FILENAME, çoğu durumda kırıldığı şeydi . Test etmek için yeterince eski bir PHP sürümüne sahip değilim, ancak SCRIPT_FILENAMEyukarıdaki örnekte "/path/to/script.php/THIS/IS/PATH/INFO" (önceden eklenmiş olarak) her zamanki gibi docroot).
    • Cgi.fix_pathinfo etkinken, PHP şimdi yukarıdaki örnekte "/ THIS / IS / PATH / INFO" yu doğru bir şekilde bulur PATH_INFOve SCRIPT_FILENAMEistenen betiğe işaret eden kısmı alır (elbette docroot ile eklenmiş).
    • Not: PHP gerçekten destek olmak üzereyken PATH_INFO, yeni özellik için bir yapılandırma ayarı eklemek zorunda kaldılar, böylece eski davranışa bağlı komut dosyalarını çalıştıran insanlar yeni PHP sürümleri çalıştırabilirdi. Bu yüzden bunun için bir yapılandırma anahtarı bile var. En başından beri ("tehlikeli" davranışla) yerleşik olmalıdır.
  • Fakat PHP betiğin hangi kısmının ve yol bilgisinin ne olduğunu nasıl biliyor? Ya URI şöyle bir şeyse:

    http://example.com/path/to/script.php/THIS/IS/PATH/INFO.php?q=foo

    • Bu, bazı ortamlarda karmaşık bir soru olabilir. PHP’de olan, URI yolunun sunucunun dokümanı altındaki hiçbir şeye karşılık gelmeyen ilk bölümünü bulmasıdır. Bu örnekte, sunucunuzda "/docroot/path/to/script.php/THIS" olmadığını ancak kesinlikle "/docroot/path/to/script.php" 'a sahip olduğunuzu görüyor. SCRIPT_FILENAMEtespit edildi ve PATH_INFOgerisini aldı.
    • Bu yüzden şimdi Nginx belgelerinde ve Hrvoje Špoljar’ın cevabında (böylesi açık bir örnek hakkında titiz olamazsınız) ayrıntılı olarak verilen tehlikenin iyi bir örneği daha da netleşiyor: Hrvoje’nin örneği (" http: // örnek. com / foo.jpg / nonexistent.php /foo.jpg ") PHP sizin DOCROOT bir dosyayı görür '' ama o denilen şey görmez '/foo.jpg/nonexistent.php' so SCRIPT_FILENAME/foo.jpg 'alır' (yine, PATH_INFOdocroot ile öneki) ve "/nonexistent.php" alır.
  • Neden ve nasıl tehlikeli olabileceği şimdi açık olmalıdır:

    • Web sunucusu gerçekten hatalı değil - sadece "foo.jpg" ifadesinin aslında PHP içeriğini içerdiğini tespit eden, PHP'ye URI'yi proksiye ediyor, bu yüzden çalıştırıyor (şimdi pwned!). Bu DEĞİL Nginx başına özel.
  • GERÇEK sorun güvenilmeyen içerik sterilize etmeden bir yere yüklenebilir ve bunu yapabilirsiniz PHP mutlu yürütür aynı yerde, başka keyfi isteklere izin izin olmasıdır.
  • Nginx ve Apache, bu numarayı kullanan istekleri engellemek için inşa edilebilir veya yapılandırılabilir ve kullanıcı2372674'ün cevabı da dahil olmak üzere bunun nasıl yapılabileceğine dair pek çok örnek vardır . Bu blog makalesi sorunu güzelce açıklıyor, ancak doğru çözümü bulamıyor.

  • Bununla birlikte, en iyi çözüm PHP-FPM'nin ".php" ile bitmediği sürece asla bir dosyayı çalıştırmayacak şekilde yapılandırıldığından emin olmaktır. PHP-FPM'nin (~ 5.3.9 +?) Son sürümlerinin varsayılan olarak bu olduğuna dikkat çekiyor, bu nedenle bu tehlike artık çok fazla sorun değil.

Çözüm

PHP-FPM'nin yeni bir sürümüne sahipseniz (~ 5.3.9 +?), Aşağıdaki güvenli davranış zaten varsayılan olduğundan, hiçbir şey yapmamanız gerekir.

Aksi takdirde, php-fpm www.confdosyasının dosyasını bulun (belki de /etc/php-fpm.d/www.confsisteminize göre değişir). Şunlara sahip olduğunuzdan emin olun:

security.limit_extensions = .php

Yine, bugünlerde birçok yerde bu varsayılandır.

Bunun bir saldırganın WordPress dosyalarına ".php" dosyası yüklemesini engellemediğini ve aynı tekniği kullanarak çalıştırdığını engellemediğini unutmayın. Uygulamalarınız için hala iyi bir güvenceye sahip olmanız gerekir.


5
Güzel cevap! Netleştirmek için: eğer söylediğiniz gibi, PHP ne SCRIPT_FILENAMEolduğunu belirlerse , neden fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;benim kafamda bir satır var nginx? PHP'nin değerini keşfetme çabasını geçersiz kılıyor mu SCRIPT_FILENAME?
Totor,

Değerini almak için bir işlev var mı security.limit_extensions? Denedim phpinfo(), ini_get(security.limit_extensions)ve ini_get_all()başarılı olamadım.
elbowlobstercowstand

PHP-FPM'nin (~ 5.3.9 +?) Son sürümleri varsayılan olarak varsa, neden php7.1 gerekli? Yoksa bu makale yanlış mı?
Yevgeniy Afanasyev

14

Bu olmadan, özünde 'foo.jpg' adlı php kodunu içeren dosyayı web sunucusuna yükleyebilirsiniz; sonra http: //domain.tld/foo.jpg/nonexistent.php ve web sunucusu yığını yanlışlıkla oh diyecektir; bu bir PHP; Bunu işlemeye ihtiyacım var, foo.jpg / nonexistent.php dosyasını bulamayacak, foo.jpg dosyasına geri dönecek ve foo.jpg dosyasını php kodu olarak işleyecektir. Bu, çok kolay müdahaleye sistemi açtığından tehlikelidir; örneğin resim yüklemesine izin veren herhangi bir web uygulaması arka kapıyı yüklemek için bir araç haline gelir.

Önlemek için unix soketli php-fpm kullanımı ile ilgili olarak; IMO sorunu çözmeyecek.


Sadece verdiğim bağlantılarda okunabilecekleri tekrarlıyorsunuz. Gerçek mekanizmayı açıklamıyorsun. Cevabınız IMHO katma değer ister.
Totor,

6
Bu doğru olabilir, ancak başlığınızda bu soruya bir cevap ve cevap var cevabımda. Açıkça istiyorsanız; evet tehlikelidir; çok tehlikeli.
Hrvoje Špoljar

1 / Cevabım sadece unvanıyla sınırlı değil: bir organı var. 2 / user109322 sizi yanlış olduğu kanıtlanmıştır: kullanılan her türlü değer cgi.fix_pathinfoolduğunu değil varsayılan conf çünkü tehlikeli php-fpm(yalnızca dosyaları çalıştırır güvenlidir .phpuzatma).
Totor,

2

In Nginx wiki güvenlik tedbiri olarak

if (!-f $document_root$fastcgi_script_name) {
    return 404;
}

konum bloğuna dahil edilir. Diğer derslerde

try_files $uri =404;

aynı şeyi yapması gerekir, ancak Nginx wiki'sine göre problemler verebilir. Bu seçeneklerle cgi.fix_pathinfo=1artık bir sorun olmamalı. Daha fazla bilgi burada bulunabilir .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.