110 votes

Est-ce qu'un slash ("/") est équivalent à un slash encodé ("%2F") dans la partie du chemin d'une URL HTTP

Je possède un site qui traite différemment / et %2F dans la partie chemin (et non dans la chaîne de requête) d'une URL. Est-ce une mauvaise pratique selon le RFC ou le monde réel ?

Je me pose cette question car je suis continuellement confronté à des petites surprises avec le framework web que j'utilise (Ruby on Rails) ainsi qu'avec les couches en dessous (Passenger, Apache, par exemple, j'ai dû autoriser ALLOW_ENCODED_SLASHES pour Apache). Je commence à penser à supprimer complètement les slashes encodés, mais je me demande si je devrais signaler des bugs là où je remarque un comportement étrange impliquant des slashes encodés.

Pourquoi ai-je des slashes encodés en premier lieu, voici les routes que j'ai :

:controller/:foo/:bar

:foo est quelque chose comme un chemin pouvant contenir des slashes. J'ai pensé que la chose la plus simple à faire serait d'URL-encoder foo pour que les slashes soient ignorés par le mécanisme de routage. Maintenant, j'ai des doutes, et il est clair que les frameworks ne supportent pas vraiment cela, mais selon le RFC, est-ce faux de faire cela de cette façon ?

Voici quelques informations que j'ai rassemblées :

RFC 1738 (URLs) :

En général, une URL a la même interprétation qu'un octet représenté par un caractère et qu'un octet encodé. Cependant, cela n'est pas vrai pour les caractères réservés : encoder un caractère réservé pour un schéma particulier peut changer la sémantique d'une URL.

RFC 2396 (URIs) :

Ces caractères sont appelés "réservés", car leur utilisation dans le composant de l'URI est limitée à leur objectif réservé. Si les données pour un composant de l'URI entraient en conflit avec l'objectif réservé, les données en conflit doivent être échappées avant la formation de l'URI.

(est-ce que s'échapper ici signifie autre chose qu'encoder le caractère réservé ?)

RFC 2616 (HTTP/1.1) :

Les caractères autres que ceux des ensembles "réservé" et "non sûr" (voir RFC 2396 [42]) sont équivalents à leur encodage "% HEX HEX".

Il y a aussi ce rapport de bug pour Rails, où ils semblent attendre un comportement différent pour le slash encodé :

Exactement, je m'attends à des résultats différents car ils pointent vers des ressources différentes.

Il cherche le fichier littéral foo/bar dans le répertoire racine. La version non échappée cherche le fichier bar dans le répertoire foo.

Il est clair d'après les RFC que brut vs. encodé est équivalent pour les caractères non réservés, mais quelle est la situation pour les caractères réservés ?

46voto

Zeograd Points 869

À partir des données que vous avez recueillies, je serais porté à dire que les / encodés dans une URI doivent être considérés comme des / à nouveau au niveau de l'application ou de CGI.

Cela veut dire que si vous utilisez Apache avec mod_rewrite par exemple, il ne correspondra pas aux motifs s'attendant à des barres obliques dans une URI contenant des barres obliques encodées. Cependant, une fois que le module/cgi/... approprié est appelé pour gérer la requête, c'est à lui de faire le décryptage et, par exemple, de récupérer un paramètre contenant des barres obliques en tant que premier composant de l'URI.

Si votre application utilise ensuite ces données pour récupérer un fichier (dont le nom de fichier contient une barre oblique), c'est probablement une mauvaise chose.

En résumé, je trouve tout à fait normal de voir une différence de comportement entre / ou %2F car leur interprétation sera faite à des niveaux différents.

34voto

Yury Kirienko Points 539

L'histoire de %2F vs / était que, selon les recommandations initiales du W3C, les slashes «doivent impliquer une structure hiérarchique» :

Le caractère slash ("/", ASCII 2F hex) est réservé pour délimiter des sous-chaînes dont la relation est hiérarchique. Cela permet des formes partielles de l'URI.

Exemple 2

Les URIs

http://www.w3.org/albert/bertram/marie-claude

et

http://www.w3.org/albert/bertram%2Fmarie-claude

ne sont PAS identiques, car dans le second cas, le slash encodé n'a pas de signification hiérarchique.

11voto

Hoytman Points 248

J'ai également un site qui a de nombreuses URL avec des caractères encodés en URL. Je constate que de nombreux API web (y compris les outils pour les webmasters de Google et plusieurs modules Drupal) rencontrent des problèmes avec des caractères encodés en URL. Beaucoup d'API décoderont automatiquement les URL à un moment donné de leur processus et utiliseront ensuite le résultat comme URL ou HTML. Lorsque je trouve un de ces problèmes, j'encode généralement deux fois les résultats (ce qui transforme %2f en %252f) pour cet API. Cependant, cela peut casser d'autres APIs qui ne s'attendent pas à un double encodage, donc ce n'est pas une solution universelle.

Personnellement, j'essaie de me débarrasser autant que possible des caractères spéciaux dans mes URL.

Aussi, j'utilise des numéros d'identification dans mes URL qui ne dépendent pas du décodage d'URL :

exemple.com/blog/mon-super-blog%2fhistoire/hier

devient :

exemple.com/blog/12354/mon-super-blog%2fhistoire/hier

dans ce cas, mon code utilise uniquement 12354 pour trouver l'article, et le reste de l'URL est ignoré par mon système (mais est toujours utilisé pour le référencement). De plus, ce numéro devrait apparaître AVANT les composants d'URL inutilisés. De cette façon, l'URL fonctionnera toujours, même si le %2f est décoder incorrectement.

Assurez-vous également d'utiliser des balises canoniques pour vous assurer que les erreurs d'URL ne se traduisent pas par un contenu dupliqué.

4voto

zhe liu Points 41

Si vous utilisez Tomcat, ajoutez

-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

dans les propriétés VM.

https://tomcat.apache.org/tomcat-7.0-doc/config/systemprops.html#Security

3voto

Dan Farrell Points 1558

Que faire si :foo sous sa forme naturelle contient des barres obliques? Vous ne voudriez pas que ce soit. N'est-ce pas la distinction que la recommandation essaye de préserver? Il note spécifiquement,

La similitude avec Unix et d'autres conventions de noms de fichiers de système d'exploitation de disque devrait être considérée comme purement fortuite, et ne devrait pas être interprétée comme indiquant que les URI devraient être interprétées comme des noms de fichiers.

Si l'on construisait une interface en ligne pour un programme de sauvegarde, et qu'on voulait exprimer le chemin en tant que partie du chemin d'URL, il serait logique d'encoder les barres obliques dans le chemin du fichier, car cela ne fait vraiment pas partie de la hiérarchie de la ressource - et plus important encore, de la route. /sauvegardes/2016-07-28contenu//home/dan/ perd la racine du système de fichiers dans les doubles barres obliques. Échapper aux barres obliques est la manière appropriée de distinguer, tel que je le comprends.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X