Nastąpił wiele od mówienia o występowanie problemu dotyczącego zabezpieczeń w stosunku do możliwości używanego PHP z Nginx (zwykle PHP-FPM, szybko CGI). cgi.fix_pathinfo
W rezultacie domyślny plik konfiguracyjny nginx powiedział:
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
Jednak teraz „oficjalna” wiki Nginx stwierdza, że PATH_INFO może być poprawnie obsługiwane bez wyłączania powyższej opcji PHP. Więc co?
pytania
- Czy możesz wyjaśnić jasno, co robi
cgi.fix_pathinfo
? ( oficjalny dokument mówi po prostu : „Aby uzyskać więcej informacji na temat PATH_INFO, zobacz specyfikacje CGI”) - Co PHP naprawdę zrobi z tymi
PATH_INFO
iSCRIPT_FILENAME
zmiennymi? - Dlaczego i jak może być niebezpiecznie z Nginx? ( szczegółowe przykłady)
- Czy problem nadal występuje w najnowszych wersjach tych programów?
- Czy Apache jest zagrożony?
Staram się zrozumieć problem na każdym kroku. Na przykład nie rozumiem, dlaczego użycie uniksowego gniazda php-fpm może uniknąć tego problemu.
Odpowiedzi:
TL; DR - poprawka (której możesz nawet nie potrzebować) jest BARDZO PROSTA i na końcu tej odpowiedzi.
Spróbuję odpowiedzieć na twoje konkretne pytania, ale twoje niezrozumienie, czym jest PATH_INFO, sprawia, że same pytania są trochę błędne.
Pierwsze pytanie powinno brzmieć: „Co to za biznes informacji o ścieżce?”
Informacje o ścieżce są wstawiane po skrypcie w URI (powinny zaczynać się od ukośnika, ale kończą się przed argumentami zapytania, które zaczynają się od a
?
). Ostatni akapit w sekcji przeglądu artykułu w Wikipedii na temat CGI ładnie podsumowuje. PoniżejPATH_INFO
znajduje się „/ THIS / IS / PATH / INFO”:http://example.com/path/to/script.php/THIS/IS/PATH/INFO?query_args=foo
Twoje następne pytanie powinno brzmieć: „W jaki sposób PHP określa, co
PATH_INFO
i czymSCRIPT_FILENAME
jest?”PATH_INFO
, więc to, co miało być,PATH_INFO
zostało zmutowane, naSCRIPT_FILENAME
którym tak jest w wielu przypadkach zepsute. Nie mam wystarczająco starej wersji PHP do testowania, ale uważam, że widziałem jąSCRIPT_FILENAME
jako cały shebang: „/path/to/script.php/THIS/IS/PATH/INFO” w powyższym przykładzie (z prefiksem docroot jak zwykle).PATH_INFO
iSCRIPT_FILENAME
pobiera tylko część wskazującą na żądany skrypt (oczywiście poprzedzony plikiem docroot).PATH_INFO
, musieli dodać ustawienie konfiguracyjne dla nowej funkcji, aby osoby uruchamiające skrypty zależne od starego zachowania mogły uruchamiać nowe wersje PHP. Dlatego jest nawet przełącznik konfiguracji. Powinien był być wbudowany (z „niebezpiecznym” zachowaniem) od samego początku.Ale skąd PHP wie, jaką częścią jest skrypt i jakie informacje o ścieżce? Co jeśli URI jest podobny do:
http://example.com/path/to/script.php/THIS/IS/PATH/INFO.php?q=foo
SCRIPT_FILENAME
został ustalony iPATH_INFO
dostaje resztę.SCRIPT_FILENAME
dostaje„ /foo.jpg ” (ponownie z prefiksem docroot) iPATH_INFO
otrzymuje „/nonexistent.php”.Dlaczego i jak może być niebezpieczne, powinno być teraz jasne:
Nginx i Apache mogą zostać zbudowane lub skonfigurowane, aby zapobiegać żądaniom przy użyciu tej sztuczki, i istnieje wiele przykładów, jak to zrobić, w tym w odpowiedzi user2372674 . Ten artykuł na blogu ładnie wyjaśnia problem, ale brakuje w nim właściwego rozwiązania.
Jednak najlepszym rozwiązaniem jest upewnienie się, że PHP-FPM jest poprawnie skonfigurowany, aby nigdy nie wykonywał pliku, dopóki nie zakończy się na „.php”. Warto zauważyć, że najnowsze wersje PHP-FPM (~ 5.3.9 +?) Mają to ustawienie domyślne, więc to niebezpieczeństwo nie stanowi już większego problemu.
Rozwiązanie
Jeśli masz najnowszą wersję PHP-FPM (~ 5.3.9 +?), Nie musisz nic robić, ponieważ poniższe zachowanie jest już domyślne.
W przeciwnym razie znajdź
www.conf
plik php-fpm (może to/etc/php-fpm.d/www.conf
zależeć od twojego systemu). Upewnij się, że masz to:Ponownie, w dzisiejszych czasach jest to domyślne.
Pamiętaj, że nie uniemożliwia to atakującemu przesłania pliku „.php” do folderu przesyłania WordPress i wykonania go przy użyciu tej samej techniki. Nadal potrzebujesz dobrego bezpieczeństwa dla swoich aplikacji.
źródło
SCRIPT_FILENAME
jest, dlaczegofastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
w moimnginx
conf jest linia ? Czy zastępuje wysiłki PHP mające na celu odkrycie wartościSCRIPT_FILENAME
samej w sobie?security.limit_extensions
? Próbowałemphpinfo()
,ini_get(security.limit_extensions)
iini_get_all()
bez powodzenia.W zasadzie bez tego możesz przesłać plik z kodem php o nazwie „foo.jpg” na serwer; następnie poproś o to tak, jak http: //domain.tld/foo.jpg/nonexistent.php, a stos serwera sieciowego omyłkowo powie: och; to jest PHP; Muszę to przetworzyć, nie uda się znaleźć foo.jpg / nonexistent.php, więc wróci do foo.jpg i przetworzy foo.jpg jako kod php. Jest to niebezpieczne, ponieważ otwiera system na bardzo łatwą ingerencję; każda aplikacja internetowa umożliwiająca na przykład przesyłanie obrazu staje się narzędziem do przesyłania backdoora.
Odnośnie używania php-fpm z gniazdem uniksowym, aby tego uniknąć; IMO nie rozwiąże problemu.
źródło
cgi.fix_pathinfo
jest niebezpieczna, ponieważ domyślna konf jest bezpieczna (będzie wykonywać tylko pliki z rozszerzeniem).php-fpm
.php
Na wiki Nginx jako środek bezpieczeństwa
jest zawarty w bloku lokalizacji. W innych samouczkach
jest używany, co powinno zrobić to samo, ale może powodować problemy zgodnie z wiki Nginx. Dzięki tym opcjom
cgi.fix_pathinfo=1
nie powinno już stanowić problemu. Więcej informacji można znaleźć tutaj .źródło