Tomcat 8无法使用"|"处理get请求 在查询参数?

ash*_*ram 55 java tomcat tomcat8 tomcat8.5

我正在使用Tomcat 8.在一种情况下,我需要处理来自外部源的外部请求,其中请求具有由其分隔的参数|.

请求看起来像这样:

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

在这种情况下,我得到以下错误.

java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and 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)
Run Code Online (Sandbox Code Playgroud)

编辑1

它适用于Apache Tomcat 8.0.30但不适用于Tomcat 8.5

Pio*_*ski 61

所有主要Tomcat版本中都引入了此行为:

  • Tomcat的7.0.73,8.0.39,8.5.7

要修复,请执行以下操作之一:


根据更改日志,这些更改可能会影响此行为:

Tomcat 8.5.3:

确保具有非令牌的HTTP方法名称(根据RFC 7231要求)的请求被400响应拒绝

Tomcat 8.5.7:

将有效字符的附加检查添加到HTTP请求行解析,以便更快地拒绝无效的请求行.


最佳选择(遵循标准) - 您希望在客户端上对您的URL进行编码:

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

或只是查询字符串:

encodeURIComponent("msg=name|id|")
> msg%3Dname%7Cid%7C
Run Code Online (Sandbox Code Playgroud)

它将保护您免受其他有问题的字符(无效URI字符列表).

  • @BhuwanGautam我不建议降级tomcat,因为最新的tomcat版本具有所有必要的CVE补丁,这些补丁可能已经影响了你的降级版本.编码URI参数将是一个修复 - 或使用`relaxedQueryChars` - 从长远来看,使用保留的RFC 3986字符的代码中的任何地方都应该重构. (3认同)
  • 谢谢,我刚刚将我的 ``apache-tomcat-8.5.11`` 降级到 ``apache-tomcat-8.0.30`` 并且它的效果非常好。 (2认同)

Jér*_*age 49

由于Tomcat的7.0.76,8.0.42,8.5.12可以定义属性requestTargetAllow,让禁伐字符.

在你的.添加这一行 catalina.properties

tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
Run Code Online (Sandbox Code Playgroud)


小智 11

tomcat.util.http.parser.HttpParser.requestTargetAllow自Tomcat 8.5以来,该参数已被弃用:tomcat官方文档.

您可以relaxedQueryChars / relaxedPathChars在连接器定义中使用以允许这些字符:tomcat官方文档.


小智 11

我们发现了同样的问题.在分析问题后,找到了解决方案.以下是问题和解决方案的详细信息.

问题:Tomcat(7.0.88)抛出异常导致400 - Bad Request.java.lang.IllegalArgumentException:在请求目标中找到无效字符.RFC 7230和RFC 3986中定义了有效字符.从7.0.88开始,大多数tomcat版本都会出现此问题.

解决方案:(由Apache团队建议):

Tomcat增加了安全性,不再允许在查询字符串中使用原始方括号.在请求中我们有[,](方括号),因此酒店请求不由服务器处理.
作为下面的解决方案,需要合并步骤以使其按预期工作.1.我们需要在server.xml下的标签下添加relaxedQueryChars属性(%TOMCAT_HOME%/ conf)

java.lang.IllegalArgumentException: Invalid character found in the request target. 
The valid characters are defined in RFC 7230 and RFC 3986.
Run Code Online (Sandbox Code Playgroud)
  1. 如果应用程序需要更多特殊字符,默认情况下tomcat不支持,那么我们需要在relaxQueryChars属性中添加这些特殊字符,并使用逗号分隔,如上所述.


小智 5

逃离它。管道符号是一种随着时间的推移和浏览器之间的不同处理方式。例如,Chrome 和 Firefox 在复制/粘贴 URL 时以不同的方式转换带有管道的 URL。然而,似乎与 Tomcat 8.5 最兼容和最必要的是逃避它:

http://localhost:8080/app/handleResponse?msg=name%7Cid%7C


小智 5

URI编码为UTF-8,但Tomcat将其解码为ISO-8859-1.您需要编辑server.xml中的连接器设置并添加URIEncoding ="UTF-8"属性.

或在application.properties上编辑此参数

server.tomcat.uri编码= UTF-8