spring boot 处理请求参数的非法字符
问题描述
spring boot 版本为 2.2.2.RELEASE,项目内嵌了默认的tomcat ,当GET请求的url包含特殊符号“[”时(如:http://localhost:8080/getArticle?id=1&data=test[123]),出现http 400状态,具体异常信息如下:
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:468)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:260)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1591)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
异常的原因
高版本的tomcat,对url中特殊符号进行了限制。
解决方案
客户端将特殊符号编码,再发送到服务器
比如 javascript,使用encodeURIComponent对参数编码,避免出现特殊符号。
var url = "http://localhost:8080/getArticle?id=1&data=";
console.log(url + "test[123]");
// http://localhost:8080/getArticle?id=1&data=test[123]
console.log(url + encodeURIComponent("test[123]"));
// http://localhost:8080/getArticle?id=1&data=test%5B123%5D
- 使用 relaxedPathChars 和 relaxedQueryChars,修改tomcat支持请求参数的特殊符号
参考 https://tomcat.apache.org/tomcat-8.5-doc/config/systemprops.html,tomcat.util.http.parser.HttpParser.requestTargetAllow的描述
This system property is deprecated. Use the
relaxedPathChars
andrelaxedQueryChars
attributes of the Connector instead. These attributes permit a wider range of characters to be configured as valid.A string comprised of characters the server should allow even when they are not encoded. These characters would normally result in a 400 status.
The acceptable characters for this property are:
|
,{
, and}
WARNING: Use of this option may expose the server to CVE-2016-6816.
If not specified, the default value of
null
will be used.
tomcat.util.http.parser.HttpParser.requestTargetAllow的系统属性在新版的tomcat中已经弃用,使用relaxedPathChars 和 relaxedQueryChars。可以在spring boot中添加 ConfigurableServletWebServerFactory Bean。
@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addConnectorCustomizers(connector -> {
connector.setProperty("relaxedPathChars", "[]|"); // 添加需要的特殊符号
connector.setProperty("relaxedQueryChars", "|{}[]"); // 添加需要的特殊符号
});
return factory;
}