Ha habido un montón de hablar sobre un problema de seguridad con respecto a la cgi.fix_pathinfo
opción de PHP se utiliza con Nginx (generalmente PHP-FPM, Fast CGI).
Como resultado, el archivo de configuración nginx predeterminado solía decir:
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
Sin embargo, ahora, el wiki "oficial" de Nginx establece que PATH_INFO puede manejarse correctamente sin deshabilitar la opción PHP anterior. ¿Y qué?
Preguntas
- ¿Puedes explicar claramente qué hace
cgi.fix_pathinfo
? (el documento oficial solo dice : "Para obtener más información sobre PATH_INFO, consulte las especificaciones de CGI") - ¿Qué hará realmente PHP con estas
PATH_INFO
ySCRIPT_FILENAME
variables? - ¿Por qué y cómo puede ser peligroso con Nginx? ( ejemplos detallados )
- ¿Existe el problema en versiones recientes de estos programas?
- ¿Apache es vulnerable?
Estoy tratando de entender el problema en cada paso. Por ejemplo, no entiendo por qué usar el socket php-fpm Unix podría evitar este problema.
Respuestas:
TL; DR: la solución (que quizás ni siquiera necesites) es MUY SENCILLA y al final de esta respuesta.
Intentaré responder a sus preguntas específicas, pero su malentendido de lo que es PATH_INFO hace que las preguntas en sí mismas sean un poco incorrectas.
La primera pregunta debería ser "¿Qué es este negocio de información de ruta?"
La información de la ruta es algo después del script en un URI (debe comenzar con una barra diagonal, pero termina antes de los argumentos de consulta, que comienzan con a
?
). El último párrafo en la sección de resumen del artículo de Wikipedia sobre CGI lo resume muy bien. Debajo dePATH_INFO
"/ THIS / IS / PATH / INFO":http://example.com/path/to/script.php/THIS/IS/PATH/INFO?query_args=foo
Su siguiente pregunta debería haber sido: "¿Cómo determina PHP qué
PATH_INFO
y quéSCRIPT_FILENAME
son?"PATH_INFO
, por lo que lo que se suponía que debía serPATH_INFO
se utilizó en loSCRIPT_FILENAME
que, sí, se rompe en muchos casos. No tengo una versión suficientemente antigua de PHP para probar, pero creo que vioSCRIPT_FILENAME
todo el shebang: "/path/to/script.php/THIS/IS/PATH/INFO" en el ejemplo anterior (con el prefijo el docroot como siempre).PATH_INFO
ySCRIPT_FILENAME
obtiene solo la parte que apunta al script que se solicita (prefijado con el docroot, por supuesto).PATH_INFO
, tuvieron que agregar una configuración de configuración para la nueva característica para que las personas que ejecutaban scripts que dependían del comportamiento anterior pudieran ejecutar nuevas versiones de PHP. Es por eso que incluso hay un interruptor de configuración para ello. Debería haber sido incorporado (con el comportamiento "peligroso") desde el principio.Pero, ¿cómo sabe PHP qué parte es el script y cuál es la información de ruta? ¿Qué pasa si el URI es algo así como:
http://example.com/path/to/script.php/THIS/IS/PATH/INFO.php?q=foo
SCRIPT_FILENAME
ha sido determinado yPATH_INFO
obtiene el resto.SCRIPT_FILENAME
obtiene" /foo.jpg " (de nuevo, con el prefijo docroot) yPATH_INFO
obtiene "/nonexistent.php".Por qué y cómo puede ser peligroso ahora debería quedar claro:
Nginx y Apache podrían construirse o configurarse para evitar solicitudes utilizando este truco, y hay muchos ejemplos de cómo hacerlo, incluida la respuesta del usuario2372674 . Este artículo de blog explica muy bien el problema, pero le falta la solución correcta.
Sin embargo, la mejor solución es asegurarse de que PHP-FPM esté configurado correctamente para que nunca ejecute un archivo a menos que termine con ".php". Vale la pena señalar que las versiones recientes de PHP-FPM (~ 5.3.9 +?) Tienen esto por defecto, por lo que este peligro ya no es un problema.
La solución
Si tiene una versión reciente de PHP-FPM (~ 5.3.9 +?), Entonces no necesita hacer nada, ya que el comportamiento seguro a continuación ya es el predeterminado.
De lo contrario, busque el
www.conf
archivo php-fpm (tal vez/etc/php-fpm.d/www.conf
, depende de su sistema). Asegúrate de tener esto:Nuevamente, eso es predeterminado en muchos lugares en estos días.
Tenga en cuenta que esto no impide que un atacante suba un archivo ".php" a una carpeta de carga de WordPress y lo ejecute utilizando la misma técnica. Aún necesita tener una buena seguridad para sus aplicaciones.
fuente
SCRIPT_FILENAME
es, ¿por qué hay unafastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
línea en minginx
conf? ¿Anula el esfuerzo de PHP para descubrir el valor deSCRIPT_FILENAME
sí mismo?security.limit_extensions
? Lo intentéphpinfo()
,ini_get(security.limit_extensions)
yini_get_all()
sin éxito.En esencia, sin esto, puede cargar un archivo con código php llamado 'foo.jpg' al servidor web; luego solicítelo como http: //domain.tld/foo.jpg/nonexistent.php y la pila del servidor web dirá erróneamente oh; esto es un PHP; Necesito procesar esto, no podrá encontrar foo.jpg / nonexistent.php, por lo que volverá a foo.jpg y procesará foo.jpg como código php. Eso es peligroso ya que abre el sistema a intrusiones muy fáciles; cualquier aplicación web que permita la carga de imágenes, por ejemplo, se convierte en una herramienta para cargar la puerta trasera.
Con respecto al uso de php-fpm con unix socket para evitarlo; OMI no resolverá el problema.
fuente
cgi.fix_pathinfo
es peligroso, porque la configuración predeterminada es segura (solo ejecutará archivos con la extensión).php-fpm
.php
En la wiki de Nginx como medida de seguridad
está incluido en el bloque de ubicación. En otros tutoriales
se usa, lo que debería hacer lo mismo, pero puede generar problemas según el wiki de Nginx. Con estas opciones,
cgi.fix_pathinfo=1
ya no debería ser un problema. Más información se puede encontrar aquí .fuente