spring boot 处理请求参数的非法字符

Java 2019-12-17 阅读 629 评论 0

问题描述

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 and relaxedQueryChars 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;
}
最后更新 2019-12-17