No describiría este cambio como "crítico" per se, pero todavía tiene implicaciones de seguridad. No tengo conocimiento de nada que haya cambiado fundamentalmente desde que el consejo se volvió relevante: el comportamiento de PHP tiende fuertemente hacia la compatibilidad hacia atrás, incluso cuando eso tiene implicaciones de seguridad. Imagine que tiene un servidor que permite a las personas cargar archivos en el servidor, por ejemplo, en un directorio llamado upload
. Ahora, su secuencia de comandos de carga tiene cuidado de permitir solo los archivos con ciertas extensiones (por ejemplo, solo .png
) para garantizar que nadie cargue un archivo PHP malicioso.
Ahora, como atacante, intentaré escribir un shell PHP en un archivo, nombrar el archivo evil.png
y subirlo. Cuando se cargue, visitaré http://example.com/upload/evil.png
, pero descubriré que esto simplemente me descarga el archivo: nginx nunca envió la solicitud a php-fcgi para que se procese como php, porque el nombre del archivo termina en .png
.
Si soy un atacante que conoce PATH_INFO
, a continuación intentaré con http://example.com/upload/evil.png/index.php
. Si su servidor está configurado de este modo, esto resultará en la ejecución de PHP (porque nginx ve el index.php
al final) y PHP recorrerá la ruta hasta que encuentre un componente que sea un archivo, no un directorio ( evil.png
) y tratar de ejecutarlo. Entonces mi shell se ejecuta y gano.
Dicho esto, hay mejores maneras de lidiar con esto haciendo que la configuración de NGINX divida la ruta de antemano, por lo que PHP no está caminando por el sistema de archivos.
De excelente de Neal Poole publicación de blog sobre el problema :
# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ \.php$ {
# Zero-day exploit defense.
# http://forum.nginx.org/read.php?2,88845,page=3
# Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
# Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine. And then cross your fingers that you won't get hacked.
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass php;
}