Les bugs d’URL encoding commencent souvent par un détail: un espace, un ampersand, une barre oblique ou un signe plus. Pourtant, ce détail peut modifier le sens complet d’un lien. Une valeur de filtre devient deux paramètres, un identifiant devient deux segments de chemin, une signature ne correspond plus ou un redirect accepte un domaine inattendu. Le problème vient du fait qu’une URL utilise les mêmes caractères pour les données et la syntaxe.

Path et query n’ont pas les mêmes règles

Dans un segment de chemin, / sépare la hiérarchie. Dans une query, & sépare les paramètres et = sépare nom et valeur. Dans un formulaire, + peut représenter un espace. Une fonction unique appliquée partout produira tôt ou tard un mauvais encodage.

Les bibliothèques sérieuses distinguent path segment, query parameter et URL complète. Cette séparation reflète la grammaire réelle. Elle évite de deviner à la main quels caractères sont réservés.

Le double encodage rend les valeurs étranges

Si %20 est encodé une seconde fois, il devient %2520. Le destinataire qui décode une fois obtient la chaîne %20, pas un espace. S’il décode deux fois, il peut transformer une donnée en syntaxe. Les signatures, caches et routes détestent cette ambiguïté.

Le système doit savoir si une valeur est brute ou déjà encodée. Le modèle le plus sûr conserve des valeurs brutes en interne et encode uniquement lors de la construction finale de l’URL.

Concaténer une query est fragile

Un département nommé “R&D” contient un ampersand. Une recherche avec un signe égal ou un texte accentué contient d’autres caractères à traiter. La concaténation ?q=... fonctionne en démonstration, puis casse avec de vraies données utilisateur.

Une API de paramètres encode les valeurs, gère les tableaux et clarifie ce qui est structure ou donnée. Le code devient plus lisible et plus sûr.

Les signatures exigent une canonicalisation exacte

Beaucoup d’API signent méthode, chemin, query et corps avec HMAC. Changer l’ordre des paramètres, la casse du percent-encoding ou la façon de représenter les espaces suffit à invalider la signature. Le contenu logique peut être identique; les octets signés ne le sont pas.

Le protocole doit définir tri, encodage, normalisation et concaténation. Producteur et consommateur ont besoin de vectors de test partagés.

Décoder avant d’autoriser peut être dangereux

Un proxy, un framework et un routeur peuvent décoder à des moments différents. Une barre encodée peut être donnée dans une couche et séparateur dans une autre. Si l’autorisation s’applique à une forme et l’accès à une autre, la sécurité se fissure.

Les couches doivent partager une politique sur les encodages ambigus, les segments .. et la forme normalisée utilisée pour décider.

Unicode ajoute une couche

Les caractères non ASCII deviennent des octets, généralement UTF-8, avant percent-encoding. Si producteur et consommateur ne s’accordent pas, le texte reconstitué diffère. Certains caractères se ressemblent visuellement tout en ayant des code points différents.

Les noms de domaine internationalisés obéissent à IDNA et punycode. Une validation visuelle ne suffit pas pour autoriser des hôtes.

Les redirects amplifient les erreurs

Un paramètre returnUrl ou next doit valider la destination, pas seulement l’encodage. Une URL parfaitement encodée peut pointer vers un domaine externe ou un schéma dangereux. Le double encodage peut aussi cacher le sens réel jusqu’à une seconde étape.

Autorisez des chemins relatifs ou une liste fermée d’hôtes. Ensuite seulement, construisez la réponse avec un encodage correct.

Les logs peuvent montrer une autre forme

Certains outils affichent les URLs décodées pour être lisibles; d’autres gardent la forme brute. Comparer des logs sans connaître cette différence mène à de mauvais diagnostics. Une valeur peut sembler changer alors que seule la présentation a changé.

Pour les incidents, conserver la cible brute, la forme parsée et la forme normalisée peut être précieux, tant que les données sensibles sont protégées.

La prévention est dans la construction

Les erreurs diminuent lorsque le code manipule des objets URL, des segments et des paramètres, pas des chaînes collées. Ajoutez des tests avec caractères réservés, limites de taille, Unicode et valeurs presque valides.

Les tests doivent couvrir les vraies données

Les exemples artificiels comme abc et 123 ne révèlent pas les problèmes. Utilisez des noms avec espaces, accents, esperluettes, barres, signes plus, emoji et valeurs déjà encodées. Testez aussi les cas interdits: hôte externe, chemin traversant, paramètre vide et valeur très longue.

Ces tests protègent le comportement lorsque le framework HTTP, le reverse proxy ou la bibliothèque d’URL change.

Les limites doivent être contrôlées avant parsing coûteux

Une URL extrêmement longue peut fatiguer logs, proxies et parseurs. Les applications devraient fixer des limites de longueur et de nombre de paramètres adaptées à leur usage. Un refus clair est préférable à un comportement différent selon la couche qui reçoit la requête.

Cette règle réduit aussi les attaques qui cherchent à saturer le serveur avec des milliers de paramètres ou des encodages volontairement ambigus.

Une URL correcte n’est pas celle qui “a l’air” correcte. C’est une structure où chaque caractère réservé garde le rôle prévu.