Werkzeug: Werkzeug non conforme à la RFC2616

Créé le 26 mai 2016  ·  6Commentaires  ·  Source: pallets/werkzeug

En particulier, Werkzeug convertit en interne les en-têtes de type "Transfer-Encoding" ou "X-PoweredBy" en "HTTP_TRANSFER_ENCODING" et "X_POWERED_BY" respectivement. Cependant, si deux en-têtes "App-Header-1" et "App_Header_1" étaient tous deux présents dans la requête - ou même simplement "App_Header_1" - les deux seront stockés de la même manière en interne, de plus Werkzeug ne fait pas de distinction entre les deux . Ce comportement n'est pas conforme à la spécification RFC2616 HTTP 1.1, où le nom d'en-tête peut être n'importe quel jeton valide sans caractères de contrôle ou de séparation. Cela pose de nombreux problèmes, car si une demande arrivait avec "App_Header_1", elle sera ensuite convertie en "HTTP_APP_HEADER_1", désormais des frameworks comme Flask l'interpréteront comme "App-Header-1", ce qui n'est pas le même, et transmettant ces valeurs sur les systèmes qui dépendent du comportement correct échouera en tant que "App_Header_1" != "App-Header-1" dans n'importe quelle stratégie de comparaison saine.

Commentaire le plus utile

Le comportement n'est pas causé par la spécification WSGI, si vous faites référence à PEP 3333.
Le PEP 3333 stipule que :
HTTP_ Variables
Variables correspondant aux en-têtes de requête HTTP fournis par le client (c'est-à-dire les variables dont les noms commencent par "HTTP_" ). La présence ou l'absence de ces variables doit correspondre à la présence ou à l'absence de l'en-tête HTTP approprié dans la demande.

Il n'y a rien dans la spécification sur le traitement différent des traits de soulignement. En fait, vous n'êtes pas non plus conforme au PEP 3333 car je ne peux pas savoir quel en-tête est présent ou absent, c'est-à-dire si "App_H" ou "App-H" est présent.

Tous les 6 commentaires

Ce comportement est causé par la spécification WSGI elle-même, et il est impossible pour Werkzeug de faire une distinction entre ces deux en-têtes tout en respectant la spécification WSGI. Je ne connais aucune situation où cela a été un problème dans la pratique.

La RFC 2616 est d'ailleurs obsolète, mais les nouvelles RFC ne changent rien à cet égard de toute façon.

De plus, Werkzeug n'est pas responsable de l'analyse ou de l'écriture de requêtes ou de réponses HTTP au niveau syntaxique. Ceci est fait par le serveur WSGI que vous choisissez. Werkzeug a un serveur intégré, mais qui étend uniquement le serveur WSGI à partir de la bibliothèque standard.

Le comportement n'est pas causé par la spécification WSGI, si vous faites référence à PEP 3333.
Le PEP 3333 stipule que :
HTTP_ Variables
Variables correspondant aux en-têtes de requête HTTP fournis par le client (c'est-à-dire les variables dont les noms commencent par "HTTP_" ). La présence ou l'absence de ces variables doit correspondre à la présence ou à l'absence de l'en-tête HTTP approprié dans la demande.

Il n'y a rien dans la spécification sur le traitement différent des traits de soulignement. En fait, vous n'êtes pas non plus conforme au PEP 3333 car je ne peux pas savoir quel en-tête est présent ou absent, c'est-à-dire si "App_H" ou "App-H" est présent.

WSGI est un portage spécifique à Python de CGI. PEP 0333 fait référence à la spécification CGI pour la définition des "variables d'environnement CGI", qui indique :

The HTTP header field name is converted to upper case, has all occurrences of "-" replaced with "_" and has `HTTP_' prepended to give the meta-variable name.

Voir https://tools.ietf.org/html/rfc3875#section -4.1.18

Tout cela n'est pas pertinent car Werkzeug, pour la plupart, n'analyse pas les requêtes HTTP brutes et ne produit pas l'environnement WSGI. Il analyse l'environnement WSGI. Je ne vois pas pourquoi vous déposez ce problème contre cette implémentation particulière. Ne tirez pas sur le messager.

Fondamentalement, il y a beaucoup d'héritage de CGI ici, qui est hérité par WSGI, ce que Werkzeug essaie de mettre en œuvre.

Je ne veux vraiment pas commencer un combat ; Mais c'est un problème avec les implications de sécurité, en particulier pour les serveurs Web qui se trouvent derrière des passerelles d'applications "héritées" qui transmettent des informations sensibles / spécifiques à l'application dans des en-têtes contenant des traits de soulignement sans filtrer d'autres en-têtes (j'ai des exemples concrets, c'est-à-dire en fait un problème dans la pratique, que vous avez écarté par votre commentaire initial). CGI a plus de 20 ans, c'est pourquoi les spécifications WSGI et HTTP doivent avoir la priorité.

En ce qui concerne l'analyse brute :
https://github.com/pallets/werkzeug/blob/03faf0569861e9d8c8c94785ad5560f735ba72da/werkzeug/serving.py#L123

(J'ai des exemples concrets, c'est-à-dire qu'il s'agit en fait d'un problème en pratique, que vous avez écarté par votre commentaire initial)

Alors tout ce que je peux dire, c'est que je suis désolé que vous ayez un serveur comme ça. Werkzeug n'y peut rien. L'extrait que vous avez montré était précisément la raison pour laquelle j'ai dit "pour la plupart". Werkzeug inclut également un serveur de test simple qui peut être utilisé en développement (pour éviter d'avoir à configurer Gunicorn + Nginx/Apache, par exemple). Mais si vous exposez ce serveur à Internet, le problème potentiel que vous mentionnez sera le moindre de vos problèmes (de sécurité).

WSGI a été conçu pour être compatible avec CGI dans la mesure du possible. WSGI ne remplace ni ne remplace CGI. WSGI _is_ CGI. Il y a très peu de travail à faire pour faire d'une application WSGI une application CGI valide. os.environ d'un script Python CGI ressemble principalement à l'environnement WSGI équivalent. Il y a beaucoup d'héritage à prendre en compte lorsque l'on change quoi que ce soit à ce sujet. Werkzeug en tant que projet n'a pas son mot à dire, et surtout pas moi.

Encore une fois, cette question pour ce projet est inutile. Werkzeug n'est pas seul dans ce comportement. La dernière fois que j'ai vérifié, nginx bloque les en-têtes HTTP avec des traits de soulignement par défaut, en raison de tout le problème d'ambiguïté. La plupart des autres outils ne font probablement que les amalgamer. Si la plupart des outils ne peuvent pas faire la différence entre un tiret et un trait de soulignement, cela n'a plus d'importance quand la norme dit qu'il y en a un. Tout le monde est obligé de jouer le jeu, et finalement l'outil émettant des en-têtes avec des traits de soulignement est à blâmer.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

davidism picture davidism  ·  9Commentaires

KangOl picture KangOl  ·  16Commentaires

ngaya-ll picture ngaya-ll  ·  8Commentaires

taion picture taion  ·  7Commentaires

SimonSapin picture SimonSapin  ·  12Commentaires