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?"
Su siguiente pregunta debería haber sido: "¿Cómo determina PHP qué PATH_INFO
y qué SCRIPT_FILENAME
son?"
- Las versiones anteriores de PHP eran ingenuas y técnicamente ni siquiera eran compatibles
PATH_INFO
, por lo que lo que se suponía que debía ser PATH_INFO
se utilizó en lo SCRIPT_FILENAME
que, sí, se rompe en muchos casos. No tengo una versión suficientemente antigua de PHP para probar, pero creo que vio SCRIPT_FILENAME
todo el shebang: "/path/to/script.php/THIS/IS/PATH/INFO" en el ejemplo anterior (con el prefijo el docroot como siempre).
- Con cgi.fix_pathinfo habilitado, PHP ahora encuentra correctamente "/ THIS / IS / PATH / INFO" para el ejemplo anterior y lo coloca
PATH_INFO
y SCRIPT_FILENAME
obtiene solo la parte que apunta al script que se solicita (prefijado con el docroot, por supuesto).
- Nota: cuando PHP llegó a admitir realmente
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
- Esa puede ser una pregunta compleja en algunos entornos. Lo que sucede en PHP es que encuentra la primera parte de la ruta de URI que no se corresponde con nada debajo del docroot del servidor. Para este ejemplo, ve que en su servidor no tiene "/docroot/path/to/script.php/THIS" pero ciertamente tiene "/docroot/path/to/script.php", así que ahora el
SCRIPT_FILENAME
ha sido determinado y PATH_INFO
obtiene el resto.
- Así que ahora el buen ejemplo del peligro que se detalla muy bien en los documentos de Nginx y en la respuesta de Hrvoje Špoljar (no puede ser quisquilloso con un ejemplo tan claro) se vuelve aún más claro: dado el ejemplo de Hrvoje (" http: // ejemplo. com / foo.jpg / nonexistent.php "), PHP ve un archivo en su docroot" /foo.jpg "pero no ve nada llamado" /foo.jpg/nonexistent.php "así que
SCRIPT_FILENAME
obtiene" /foo.jpg " (de nuevo, con el prefijo docroot) y PATH_INFO
obtiene "/nonexistent.php".
Por qué y cómo puede ser peligroso ahora debería quedar claro:
- El servidor web realmente no tiene la culpa: simplemente está enviando el URI a PHP, que inocentemente encuentra que "foo.jpg" en realidad contiene contenido PHP, por lo que lo ejecuta (¡ahora ha sido pwned!). Esto NO es particular de Nginx per se.
- El problema REAL es que permite que se cargue contenido no confiable en algún lugar sin desinfectar y permite otras solicitudes arbitrarias en la misma ubicación, que PHP ejecuta felizmente cuando puede.
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:
security.limit_extensions = .php
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.