Il y a eu un grand nombre de parler d'un problème de sécurité par rapport à l' cgi.fix_pathinfo
option PHP utilisé avec Nginx (habituellement 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, le wiki "officiel" de Nginx stipule que PATH_INFO peut être géré correctement sans désactiver l’option PHP ci-dessus. Et alors?
Des questions
- Pouvez-vous expliquer clairement ce que
cgi.fix_pathinfo
fait? (La documentation officielle indique simplement : "Pour plus d'informations sur PATH_INFO, voir les spécifications CGI") - Qu'est - ce que PHP est vraiment avec ces
PATH_INFO
et lesSCRIPT_FILENAME
variables? - Pourquoi et comment cela peut-il être dangereux avec Nginx? ( exemples détaillés )
- Le problème existe-t-il toujours dans les versions récentes de ces programmes?
- Apache est-il vulnérable?
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.
Réponses:
TL; DR - le correctif (dont vous n’avez peut-être même pas besoin) est TRÈS SIMPLE et se trouve à la fin de cette réponse.
Je vais essayer de répondre à vos questions spécifiques, mais votre incompréhension de PATH_INFO rend les questions elles-mêmes un peu fausses.
La première question devrait être "Quelle est cette entreprise de chemin d’information?"
Les informations de chemin sont placées après le script dans un URI (devrait commencer par une barre oblique, mais se terminer avant les arguments de la requête, qui commencent par a
?
). Le dernier paragraphe de la section d'aperçu de l'article de Wikipédia sur CGI le résume bien. Ci-dessous lePATH_INFO
"/ THIS / IS / PATH / 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-
PATH_INFO
il quoi et quiSCRIPT_FILENAME
sont?"PATH_INFO
. Par conséquent, ce qui était supposé êtrePATH_INFO
était connu , ce qui est effectivementSCRIPT_FILENAME
cassé dans de nombreux cas. Je ne dispose pas d’une version suffisamment ancienne de PHP pour effectuer des tests, mais j’aiSCRIPT_FILENAME
pensé qu’elle se présentait comme suit: "/path/to/script.php/THIS/IS/PATH/INFO" dans l’exemple ci-dessus (préfixé par la docroot comme d’habitude).PATH_INFO
etSCRIPT_FILENAME
obtient juste la partie qui pointe vers le script étant demandé (préfixé avec le docroot bien sûr).PATH_INFO
, il a fallu ajouter un paramètre de configuration pour la nouvelle fonctionnalité afin que les personnes utilisant des scripts dépendant de l'ancien comportement puissent exécuter les nouvelles versions de PHP. C'est pourquoi il existe même un commutateur de configuration pour cela. Il aurait dû être intégré (avec le comportement "dangereux") depuis le début.Mais comment PHP sait-il quelle partie est le script et quelle est son information de 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é etPATH_INFO
obtient le reste.SCRIPT_FILENAME
obtient" /foo.jpg " (encore une fois, préfixé par docroot) etPATH_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 astuce, et il existe de nombreux exemples sur la façon de procéder, y compris dans la 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 configuré correctement pour qu'il ne puisse jamais exécuter un fichier s'il ne se termine pas par ".php". Il est à noter que les versions récentes de PHP-FPM (~ 5.3.9 +?) Ont ceci par défaut, ce danger n’est donc plus un problème.
La solution
Si vous avez une version récente de PHP-FPM (~ 5.3.9 +?), Vous ne devez rien faire car le comportement sécurisé ci-dessous est déjà le comportement par défaut.
Sinon, trouvez le
www.conf
fichier php-fpm (cela/etc/php-fpm.d/www.conf
dépend de votre système). Assurez-vous d'avoir ceci:Encore une fois, c'est le défaut dans de nombreux endroits ces jours-ci.
Notez que cela n'empêche pas un attaquant de télécharger un fichier ".php" dans un dossier de téléchargement WordPress et de l'exécuter avec la même technique. Vous devez toujours avoir une bonne sécurité pour vos applications.
la source
SCRIPT_FILENAME
est, pourquoi y a-t-il unefastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
ligne dans manginx
conf? Est-ce que cela annule les efforts de PHP pour découvrir la valeur deSCRIPT_FILENAME
lui-même?security.limit_extensions
? J'ai essayéphpinfo()
,ini_get(security.limit_extensions)
etini_get_all()
sans succès.Essentiellement, sans cela, vous pouvez télécharger un fichier avec un code php nommé "foo.jpg" sur le serveur Web; puis demandez-le comme http: //domain.tld/foo.jpg/nonexistent.php et la pile de serveurs Web dira à tort oh; c'est un PHP; J'ai besoin de traiter cela, il ne parviendra pas à trouver foo.jpg / nonexistent.php, donc il retombera sur foo.jpg et traiter 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 par exemple le téléchargement d’images devient un outil de téléchargement de porte dérobée.
En ce qui concerne l'utilisation de php-fpm avec un socket pour l'éviter; OMI cela ne résoudra pas le problème.
la source
cgi.fix_pathinfo
n’est pas dangereuse, car lephp-fpm
fichier conf par défaut est sûr (il n’exécutera que les fichiers portant l’.php
extension).Dans le wiki de Nginx en tant que mesure de sécurité
est inclus dans le bloc emplacement. Dans d'autres tutoriels
est utilisé, ce qui devrait faire la même chose, mais peut donner des problèmes selon le wiki de Nginx. Avec ces options,
cgi.fix_pathinfo=1
ne devrait plus être un problème. Plus d'informations peuvent être trouvées ici .la source