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_INFO
ve 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_FILENAME
yukarı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_INFO
ve SCRIPT_FILENAME
istenen 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_FILENAME
tespit edildi ve PATH_INFO
gerisini 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_INFO
docroot 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.conf
dosyasının dosyasını bulun (belki de /etc/php-fpm.d/www.conf
sisteminize 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.