Outils de développement · Encodeur et décodeur d'URL
Double encodage d'URL : comment %2520 se produit et comment le détecter et l'annuler
· Comment ça marche
encodage d'URL javascript flux de travail du développeur débogage
Un %2520 dans une URL signifie qu'un espace a été codé deux fois. Cet article explique les erreurs de pipeline qui en sont la cause, comment reconnaître la signature et combien de passes de décodage sont sûres.
Double encodage d'URL : lorsque %2520 signifie qu'un espace est passé par deux encodeurs
Un nom de fichier arrivant sous la forme "mon%20fichier.pdf" au lieu de "mon fichier.pdf" signale un double encodage : un espace a été codé en %20, puis le signe de pourcentage lui-même a été codé en %25, produisant %2520 dans l'URL finale. Chaque couche d'un système, telle que le code client, le framework Web ou le proxy inverse, peut être codée une fois. Lorsque deux couches distinctes encodent, un seul caractère est mutilé.
Surfaces de codage doubles le plus souvent dans les chaînes de redirection complexes et les systèmes de modèles. Un développeur peut générer une URL codée dans un framework qui code lui-même toutes les sorties par défaut. Un proxy inverse ou un réseau de diffusion de contenu peut réencoder les URL déjà arrivées codées depuis le système backend. Un paramètre contenant une valeur déjà encodée est à nouveau encodé avant d'être imbriqué dans une autre structure d'URL.
Pourquoi %25 est le témoin – le signe de pourcentage lui-même est codé, donc %20 devient %2520 et %C3%A9 devient %25C3%25A9
Le signe révélateur d'un double encodage est %25 qui apparaît là où vous vous attendez normalement à voir un seul signe de pourcentage dans l'URL ou les données. Dans une URL normalement codée, vous ne verrez jamais %25 à moins d'envoyer le littéral "%25". Si un espace codé comme %20 est à nouveau codé, il devient %2520.
Un caractère accentué comme é, qui code normalement en %C3%A9, devient %25C3%25A9 lorsqu'il est codé deux fois par deux systèmes différents en séquence. Apprendre à repérer le modèle %25 dans les barres d'URL, les journaux et les messages d'erreur permet d'économiser d'innombrables heures de travail de débogage frustrant dans les environnements de production où les données circulent via plusieurs services.
Où le double encodage est introduit : code client plus framework, redirections, proxys et assistants de modèles
Le double codage détruit à la fois la lisibilité et la capacité des systèmes côté serveur à analyser correctement l'URL. Un fichier nommé "mon fichier.pdf" devient "mon%20fichier.pdf" lorsqu'il est correctement encodé. Si la chaîne encodée est réencodée, peut-être par un formulaire, elle devient « mon%2520file.pdf ».
Lorsque le serveur reçoit ceci et le décode une fois, il voit « mon%20fichier.pdf » comme un nom de fichier littéral plutôt que de le reconnaître comme « mon fichier.pdf ». Toutes les applications qui s'attendent à recevoir une seule passe de décodage recevront un résultat mutilé. Pire encore, un développeur qui décode deux fois pour résoudre des problèmes sur des valeurs qui n'ont été codées qu'une seule fois corrompt les données légitimes avec la passe de décodage supplémentaire.
Exemple concret : décoder une URL doublement codée, une passe à la fois – ce que chaque passe révèle et quand s'arrêter
Le code JavaScript côté client et les valeurs par défaut du framework côté serveur sont les sources les plus courantes de double codage accidentel dans les systèmes de production. Une application JavaScript peut utiliser encodeURIComponent sur une valeur, puis la transmettre directement à un framework qui encode toutes les chaînes de sortie par défaut, codant ainsi le signe de pourcentage une seconde fois. Une couche de proxy inverse destinée à nettoyer les URL peut réencoder des paramètres déjà pré-encodés depuis l'application backend.
Une URL de redirection créée en concaténant l'entrée fournie par l'utilisateur avec une fonction d'assistance du framework peut encoder simultanément aux deux étapes. Exemple concret : un utilisateur soumet "test&value" via un formulaire HTML, le navigateur l'encode comme "test%26value". Le framework voit le texte en pourcentage littéral et l'encode, produisant "test%2526value". Un décodage donne "test%26value", toujours faux.
Lorsque le double encodage est délibéré : une URL contenue dans le paramètre de requête d'une autre URL
Le double encodage délibéré est valable dans un cas spécifique : lorsqu'une URL doit voyager à l'intérieur du paramètre de requête d'une autre URL. Les flux OAuth et les liens de retour de connexion nécessitent parfois d'imbriquer une URL complète dans une autre. L'URL interne doit d'abord être entièrement codée en pourcentage, puis la chaîne entière codée doit être à nouveau codée en tant que valeur de paramètre pour l'URL externe.
Ce double codage est délibéré et absolument nécessaire dans ces cas. L'analyseur de paramètres externes décode une fois, produisant l'URL interne toujours codée. Le système interne décode ensuite à nouveau, récupérant l’URL d’origine. La clé essentielle est de comprendre l'intention et de la documenter clairement dans les commentaires de code pour les futurs responsables.
Erreurs courantes : décodage jusqu'à ce que rien ne change, ce qui corrompt les valeurs qui contiennent légitimement %25
L'erreur classique et dangereuse consiste à décoder à plusieurs reprises jusqu'à ce que rien ne change, ce qui corrompt les valeurs qui contiennent légitimement des signes de pourcentage dans les données réelles. Un paramètre comme "remise%2525" (représentant un littéral "%25" codé comme valeur de paramètre, puis codé à nouveau pour le transport) est tout à fait correct de par sa conception. Le décoder une fois donne "remise%25", ce qui est toujours correct. Le décoder une seconde fois donne "remise%", ce qui est erroné et fait perdre des informations.
Un développeur peut supposer que "%25" est une erreur et décoder à plusieurs reprises, perdant ainsi le signe de pourcentage. Au lieu de cela, décodez exactement autant de fois que votre architecture l'exige : une fois pour un paramètre, deux fois imbriquée. Comptez les couches pour connaître les bonnes opérations de décodage.
Ce que cela ne couvre pas : encodage d'entité HTML superposé aux URL, que gère l'échappement d'entité HTML
Les erreurs courantes incluent l'encodage d'une URL entière avec encodeURIComponent, puis l'attente que les barres obliques et les deux-points fonctionnent comme délimiteurs structurels, ce qu'ils ne peuvent pas faire après l'encodage. Une autre erreur fréquente consiste à mélanger différentes normes de codage : certains codes utilisent un codage en pourcentage selon la RFC 3986 et d'autres codes utilisent un codage de formulaire avec des signes plus représentant des espaces. Une valeur telle que « mon+fichier » devient véritablement ambiguë : elle peut signifier « mon fichier » ou le texte littéral « mon+fichier » avec un plus.
Si l'encodage en pourcentage touche d'abord "mon+fichier", il devient "mon%2Bfichier". Si le décodage de forme suit, en attendant un plus comme espace, il reste faux. La cohérence entre les couches est essentielle. Chaque système doit utiliser la même norme de codage, ou chaque couche doit être explicitement documentée.
À retenir : encodez exactement une fois par couche – comment l'encodeur et le décodeur d'URL vous permettent de décoder une passe à la fois et de voir chaque résultat intermédiaire
Une fois que vous avez identifié avec succès le double codage se produisant dans les systèmes de production, le correctif dépend entièrement de l'endroit où la duplication se produit dans le pipeline. Si le code client et un framework sont codés, supprimez complètement le codage de l’un d’eux. Si un paramètre traverse plusieurs services backend, tracez le chemin complet à travers chaque service et recherchez quel service code alors qu'il ne devrait pas le faire.
Testez minutieusement le correctif en transmettant des exemples de données via le pipeline complet de bout en bout et vérifiez que les données arrivent complètement inchangées à la destination. Documentez clairement l'hypothèse de codage à chaque limite : "ce point de terminaison renvoie des paramètres codés en pourcentage" ou "ce middleware attend du UTF-8 brut et lui applique le codage". Incluez le nombre de passes de décodage attendues dans cette documentation pour les futurs développeurs.