Slash encodé en URL dans l’URL

Ma carte est:

routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with params new { controller = "Home", action = "Index", id = "" } // Param defaults ); 

Si j’utilise l’URL http://localhost:5000/Home/About/100%2f200 il n’y a pas de route correspondante. Je change l’URL à http://localhost:5000/Home/About/100 puis l’itinéraire est à nouveau mis en correspondance.

Existe-t-il un moyen facile de travailler avec des parameters contenant des barres obliques? D’autres valeurs échappées (espace %20 ) semblent fonctionner.

MODIFIER:

Pour encoder Base64 fonctionne pour moi. Cela rend l’URL moche, mais ça va pour le moment.

 public class UrlEncoder { public ssortingng URLDecode(ssortingng decode) { if (decode == null) return null; if (decode.StartsWith("=")) { return FromBase64(decode.TrimStart('=')); } else { return HttpUtility.UrlDecode( decode) ; } } public ssortingng UrlEncode(ssortingng encode) { if (encode == null) return null; ssortingng encoded = HttpUtility.PathEncode(encode); if (encoded.Replace("%20", "") == encode.Replace(" ", "")) { return encoded; } else { return "=" + ToBase64(encode); } } public ssortingng ToBase64(ssortingng encode) { Byte[] btByteArray = null; UTF8Encoding encoding = new UTF8Encoding(); btByteArray = encoding.GetBytes(encode); ssortingng sResult = System.Convert.ToBase64Ssortingng(btByteArray, 0, btByteArray.Length); sResult = sResult.Replace("+", "-").Replace("/", "_"); return sResult; } public ssortingng FromBase64(ssortingng decode) { decode = decode.Replace("-", "+").Replace("_", "/"); UTF8Encoding encoding = new UTF8Encoding(); return encoding.GetSsortingng(Convert.FromBase64Ssortingng(decode)); } } 

EDIT1:

À la fin, il est apparu que le meilleur moyen était de sauvegarder une chaîne bien formulée pour chaque élément que je devais sélectionner. C’est beaucoup mieux car maintenant je ne code que des valeurs et je ne les décode jamais. Tous les caractères spéciaux deviennent “-“. Beaucoup de mes tables de firebase database ont maintenant cette colonne supplémentaire “URL”. Les données sont assez stables, c’est pourquoi je peux aller dans ce sens. Je peux même vérifier si les données dans “URL” sont uniques.

EDIT2:

Surveillez également le caractère de l’espace. Il semble correct sur le serveur Web intégré de VS mais est différent sur iis7

Si ce n’est que votre dernier paramètre, vous pouvez faire:

 routes.MapRoute( "Default", // Route name "{controller}/{action}/{*id}", // URL with parameters new { controller = "Home", action = "Index", id = "" }); // Parameter defaults 

Dans .NET 4.0 beta 2, l’équipe CLR a proposé une solution de contournement.

Ajoutez ceci à votre fichier web.config:

      

Cela provoque le comportement de la classe Uri conformément à la RFC décrivant les URI, permettant aux barres obliques de s’échapper dans le chemin sans être échappées. L’équipe CLR signale qu’elle diffère des spécifications pour des raisons de sécurité, et la définition de ce paramètre dans votre fichier .config vous permet de prendre en charge les considérations de sécurité supplémentaires liées à l’absence de neutralisation des barres obliques.

Voici une explication simple de la solution et un résumé de ce qui a déjà été dit.

Côté demande:

  1. UrlEncode votre chemin
  2. Remplacez le ‘%’ par ‘!’
  3. Faites la demande

Côté réponse:

  1. Remplace le ‘!’ avec ‘%’.
  2. UrlDecode votre chemin
  3. Utilisez les parameters comme ils étaient prévus.

Rincez, répétez, profitez-en.

Une autre option consiste à utiliser une valeur de chaîne de requête. Très boiteux, mais plus simple que l’encodage personnalisé.

 http://localhost:5000/Home/About?100%2f200 

Idem pour Java / Tomcat.

Il y a toujours un problème si vous avez un “/” (% 2F) encodé dans votre URL.

RFC 3986 – Section 2.2 dit: “Si les données d’un composant URI entraient en conflit avec le but d’un caractère réservé en tant que délimiteur, alors les données en conflit doivent être codées en pourcentage avant la formation de l’URI.” (RFC 3986 – Section 2.2)

Mais il y a un problème avec Tomcat:

http://tomcat.apache.org/security-6.html – Résolu dans Apache Tomcat 6.0.10

important: traversée de répertoire CVE-2007-0450

Tomcat autorise ‘\’, ‘% 2F’ et ‘% 5C’ […].

Les propriétés système Java suivantes ont été ajoutées à Tomcat pour fournir un contrôle supplémentaire sur la gestion des délimiteurs de chemin dans les URL (les deux options par défaut sont fausses):

  • org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH: true | false
  • org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH: true | false

En raison de l’impossibilité de garantir que toutes les URL sont gérées par Tomcat comme elles le sont dans les serveurs proxy, Tomcat devrait toujours être sécurisé comme si aucun access de contexte de ressortingction de proxy n’était utilisé.

Affecte: 6.0.0-6.0.9

Donc, si vous avez une URL avec le caractère% 2F, Tomcat renvoie: “400 URI non valide: noSlash”

Vous pouvez basculer du correctif dans le script de démarrage Tomcat:

 set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG% -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true 

Vous pouvez éviter les suggestions de codage / décodage doubles ci-dessus et simplement utiliser HttpServerUtility.UrlTokenEncode et le code UrlTokenDecode correspondant.

C’est intéressant à propos de .NET 4. Quoi qu’il en soit, ce lien décrit la RFC 1738 et indique quels caractères doivent être encodés et quels sont ceux qui sont “dangereux”. texte du lien

Si je veux une URL SEO friendly, (comme lorsque vous souhaitez placer un sujet de forum dans l’URL), ignorez l’encodage et remplacez tout ce qui n’est pas AZ, az, 0-9.

 public static ssortingng CreateSubjectSEO(ssortingng str) { int ci; char[] arr = str.ToCharArray(); for (int i = 0; i < arr.Length; i++) { ci = Convert.ToInt32(arr[i]); if (!((ci > 47 && ci < 58) || (ci > 64 && ci < 91) || (ci > 96 && ci < 123))) { arr[i] = '-'; } } return new string(arr); } 

Comme suggéré ici lorsque le problème a été rencontré par les développeurs Symfony 1.x (+ suggéré dans les commentaires PHP pour urlencode() ):

  • Encoder ‘/’ à ‘% 2F’ avant urlencode()
  • Décodez ‘% 2F’ en ‘/’ après (si nécessaire) urldecode()

Note: vous pouvez utiliser rawurlencode() , mais vous devrez toujours encoder deux fois ‘/’.

Avantages:

  • Évite le besoin de processus d’échappement supplémentaires (si vous remplacez ‘/’ par un caractère spécial comme ‘!’ Ou ‘_’)
  • Ne vous fiez à aucun paramètre de serveur tel que AllowEncodedSlashes pour Apache

Utilisez simplement Server.UrlDecode . Ça va marcher, j’ai testé.