Il y a eu alotsuren train de parler à propos d'un problème de sécurité relatif au cgi.fix_pathinfo
PHP utilisée avec Nginx (généralement PHP-FPM, CGI rapide).
En conséquence, le fichier de configuration par défaut de nginx disait:
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
Cependant, maintenant, le wiki "officiel" de Nginx indique que PATH_INFO peut être géré correctement sans désactiver l'option PHP PHP ci-dessus. Alors quoi?
cgi.fix_pathinfo
faire? ( le doc officiel dit juste : "Pour plus d'informations sur PATH_INFO, voir les spécifications CGI")PATH_INFO
et SCRIPT_FILENAME
variables?J'essaie de comprendre le problème à chaque étape. Par exemple, je ne comprends pas pourquoi l'utilisation du socket Unix php-fpm pourrait éviter ce problème.
J'essaierai de répondre à vos questions spécifiques, mais votre mauvaise compréhension de ce qu'est PATH_INFO rend les questions elles-mêmes un peu erronées.
La première question devrait être "Quelle est cette entreprise d'informations sur le chemin?"
Les informations de chemin sont des trucs après le script dans un URI (devraient commencer par une barre oblique, mais se terminent avant les arguments de requête, qui commencent par un ?
). Le dernier paragraphe de la section d'aperçu de article Wikipédia sur CGI le résume bien. Sous PATH_INFO
Se trouve "/ CECI/EST/CHEMIN/INFO":
http://example.com/path/to/script.php/THIS/IS/PATH/INFO?query_args=foo
Votre prochaine question aurait dû être: "Comment PHP détermine-t-il ce que sont PATH_INFO
Et SCRIPT_FILENAME
?"
PATH_INFO
, Donc ce qui était censé être PATH_INFO
A été intégré à SCRIPT_FILENAME
qui, oui, est cassé dans de nombreux cas. Je n'ai pas une version assez ancienne de PHP pour tester, mais je crois qu'il a vu SCRIPT_FILENAME
comme le Shebang entier: "/path/to/script.php/THIS/IS/PATH/INFO" dans l'exemple ci-dessus (préfixé avec le docroot comme d'habitude).PATH_INFO
Et SCRIPT_FILENAME
obtient juste la partie qui pointe vers le script demandé (préfixé avec le docroot bien sûr).PATH_INFO
, Ils ont dû ajouter un paramètre de configuration pour la nouvelle fonctionnalité afin que les personnes exécutant des scripts qui dépendaient de l'ancien comportement puissent exécuter new = PHP versions. C'est pourquoi il y a même un commutateur de configuration pour cela. Il aurait dû être intégré (avec le comportement "dangereux") dès le début.Mais comment PHP sait-il quelle partie est le script et quelles informations sur son chemin? Et si l'URI est quelque chose comme:
http://example.com/path/to/script.php/THIS/IS/PATH/INFO.php?q=foo
SCRIPT_FILENAME
a été déterminé et PATH_INFO
obtient le reste.SCRIPT_FILENAME
obtient "/foo.jpg" (encore une fois, préfixé avec docroot) et PATH_INFO
obtient "/nonexistent.php" .Pourquoi et comment cela peut être dangereux devrait maintenant être clair:
Nginx et Apache pourraient être construits ou configurés pour empêcher les requêtes utilisant cette ruse, et il existe de nombreux exemples pour le faire, y compris dans réponse de user2372674 . Cet article de blog explique bien le problème, mais il manque la bonne solution.
Cependant, la meilleure solution consiste simplement à s'assurer que PHP-FPM est correctement configuré afin qu'il n'exécute jamais un fichier à moins qu'il ne se termine par ".php". Il convient de noter que les versions récentes de PHP-FPM (~ 5.3.9 +?) Ont cela par défaut, donc ce danger n'est plus vraiment un problème.
Si vous avez une version récente de PHP-FPM (~ 5.3.9 +?), Alors vous ne devez rien faire, car le comportement sûr ci-dessous est déjà celui par défaut.
Sinon, trouvez le fichier www.conf
De php-fpm (peut-être que /etc/php-fpm.d/www.conf
Dépend de votre système). Assurez-vous d'avoir ceci:
security.limit_extensions = .php
Encore une fois, c'est le défaut dans de nombreux endroits de nos jours.
Notez que cela n'empêche pas un attaquant de télécharger un fichier ".php" dans un dossier WordPress télécharge et exécute celui-ci en utilisant la même technique. Vous devez toujours avoir une bonne sécurité pour vos applications.
En substance, sans cela, vous pouvez télécharger un fichier avec un code php nommé comme 'foo.jpg' sur le serveur Web; puis demandez-le comme http: //domain.tld/foo.jpg/nonexistent.php et la pile du serveur Web dira par erreur oh; c'est un PHP; J'ai besoin de traiter cela, il ne trouvera pas foo.jpg/nonexistent.php donc il retombera sur foo.jpg et traitera foo.jpg en tant que code php. C'est dangereux car cela ouvre le système à une intrusion très facile; toute application Web permettant le téléchargement d'images par exemple devient un outil pour télécharger une porte dérobée.
Concernant l'utilisation de php-fpm avec un socket Unix pour l'éviter; OMI, il ne résoudra pas le problème.
Dans le wiki Nginx comme mesure de sécurité
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
est inclus dans le bloc de localisation. Dans d'autres tutoriels
try_files $uri =404;
est utilisé, ce qui devrait faire de même, mais peut poser des problèmes selon le wiki Nginx. Avec ces options, cgi.fix_pathinfo=1
ne devrait plus être un problème. Plus d'informations peuvent être trouvées ici .