74 votes

Tomcat 8 n'est pas capable de gérer la requête get avec '|' dans les paramètres de la requête?

Je suis en train d'utiliser Tomcat 8. Dans un cas, j'ai besoin de gérer une demande externe en provenance d'une source externe où la demande comporte des paramètres séparés par |.

La demande ressemble à ceci :

http://localhost:8080/app/handleResponse?msg=name|id|

Dans ce cas, je reçois l'erreur suivante.

java.lang.IllegalArgumentException: Caractère invalide trouvé dans la cible de la demande. Les caractères valides sont définis dans les RFC 7230 et  RFC 3986
    at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:467)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:667)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:789)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

ÉDITION 1

Cela fonctionne avec Apache Tomcat 8.0.30 mais pas avec Tomcat 8.5

5 votes

D'accord, je suppose que vous devrez l'échapper

0 votes

Avez-vous consulté le RFC référencé?

0 votes

Les RFC sont censées être améliorées.

77voto

Piotr Lewandowski Points 2603

Ce comportement est introduit dans toutes les versions majeures de Tomcat :

  • Tomcat 7.0.73, 8.0.39, 8.5.7

Pour corriger, faites l'une des choses suivantes :

  • définissez relaxedQueryChars pour permettre ce caractère (recommandé, voir réponse de Lincoln)
  • définissez l'option requestTargetAllow (obsolète dans Tomcat 8.5) (voir réponse de Jérémie).
  • vous pouvez rétrograder vers l'une des anciennes versions (non recommandé - sécurité)

Basé sur le journal des modifications, ces changements pourraient affecter ce comportement :

Tomcat 8.5.3:

S'assurer que les requêtes avec des noms de méthode HTTP qui ne sont pas des jetons (comme requis par RFC 7231) sont rejetées avec une réponse 400

Tomcat 8.5.7:

Ajouter des vérifications supplémentaires pour les caractères valides à l'analyse de ligne de requête HTTP afin que les lignes de requête invalides soient rejetées plus tôt.


La meilleure option (en suivant la norme) - vous voulez encoder votre URL côté client :

encodeURI("http://localhost:8080/app/handleResponse?msg=name|id|")
> http://localhost:8080/app/handleResponse?msg=name%7Cid%7C

ou juste la chaîne de requête :

encodeURIComponent("msg=name|id|")
> msg%3Dname%7Cid%7C

Cela vous protégera des autres caractères problématiques (liste des caractères d'URI invalides).

3 votes

Merci, je viens de rétrograder mon apache-tomcat-8.5.11 en apache-tomcat-8.0.30 et ça a fonctionné à merveille.

4 votes

@BhuwanGautam Je ne recommanderais pas de rétrograder Tomcat car les dernières versions de Tomcat comportent toutes les correctifs nécessaires pour les CVE qui pourraient avoir affecté vos versions rétrogradées. L'encodage des paramètres d'URI serait une solution - ou l'utilisation de relaxedQueryChars - À long terme, n'importe où dans le code qui utilise des caractères réservés RFC 3986 devrait être refactorisé.

0 votes

Il semble que relaxedQueryChars soit toujours vulnérable. Y a-t-il une solution appropriée fournie par Apache ?

53voto

Jérémie Lesage Points 540

Depuis Tomcat 7.0.76, 8.0.42, 8.5.12 vous pouvez définir la propriété requestTargetAllow pour autoriser les caractères interdits.

Ajoutez cette ligne dans votre fichier catalina.properties

tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}

1 votes

À partir de tomcat 8.5 # ATTENTION : L'utilisation de cette option peut exposer le serveur à la CVE-2016-6816 # tomcat.util.http.parser.HttpParser.requestTargetAllow=|

17voto

Problème : Tomcat (7.0.88) lance l'exception ci-dessous qui conduit à une 400 - Mauvaise requête.

java.lang.IllegalArgumentException: Caractère non valide trouvé dans la cible de la requête. 
Les caractères valides sont définis dans les RFC 7230 et RFC 3986.

Ce problème se produit sur la plupart des versions de tomcat à partir de la version 7.0.88.

Solution : (Suggérée par l'équipe Apache) :

Tomcat a renforcé sa sécurité et n'autorise plus les crochets carrés bruts dans la chaîne de requête. Dans la requête, nous avons [,] (crochets carrés) donc la requête n'est pas traitée par le serveur.

Ajoutez l'attribut relaxedQueryChars sous la balise Connector dans le fichier server.xml (%TOMCAT_HOME%/conf) :

Si l'application a besoin de plus de caractères spéciaux qui ne sont pas pris en charge par tomcat par défaut, ajoutez ces caractères spéciaux dans l'attribut relaxedQueryChars, séparés par des virgules comme ci-dessus.

1 votes

Fonctionne pour moi avec la dernière version de Tomcat 8 pour DHIS2, car cela aide quelqu'un !!!

16voto

Lincoln Points 71

Le paramètre tomcat.util.http.parser.HttpParser.requestTargetAllow est obsolète depuis Tomcat 8.5: documentation officielle de Tomcat.

Vous pouvez utiliser relaxedQueryChars / relaxedPathChars dans la définition des connecteurs pour autoriser ces caractères : documentation officielle de Tomcat.

0 votes

Dans 8.5 j'ai essayé ces éléments et cela n'a eu aucun effet. La meilleure option est toujours de coder vos URL.

7voto

L'URI est encodé en UTF-8, mais Tomcat les décode en ISO-8859-1. Vous devez modifier les paramètres du connecteur dans le fichier server.xml et ajouter l'attribut URIEncoding="UTF-8".

ou modifier ce paramètre dans votre application.properties

server.tomcat.uri-encoding=utf-8

0 votes

L'attribut URIEncoding sur l'élément dans server.xml doit être défini sur quelque chose de spécifique (par exemple, URIEncoding="UTF-8") (wiki.apache.org/tomcat/FAQ/CharacterEncoding)

0 votes

@hwak votre lien est cassé

0 votes

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