200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > java rfc3986_tomcat对URL合法字符的判断(RFC 7230 and RFC 3986 异常排查)

java rfc3986_tomcat对URL合法字符的判断(RFC 7230 and RFC 3986 异常排查)

时间:2022-04-04 13:01:48

相关推荐

java rfc3986_tomcat对URL合法字符的判断(RFC 7230 and RFC 3986 异常排查)

起因

有一个数据上报接口,之前在物理机上部署,数据上报正常。

最近将项目迁移到 docker 中,结果出现了异常如下:

Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.

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.InternalInputBuffer.parseRequestLine(InternalInputBuffer.java:192)

at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1028)

at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)

at org.apache..JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)

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)

问题原因

问题排查过程:略

原因:请求中出现了字符"{"(示例请求)

https://127.0.0.1:8080/metric?data=[{%22app

在不更改接口数据的前提下,解决方案为:在tomcat的cataline.properties追加配置

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

官方文档链接:/tomcat-8.0-doc/config/systemprops.html#Other

tomcat.util.http.parser.HttpParser. requestTargetAllow

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 will expose the server to CVE--6816.

If not specified, the default value ofnullwill be used.

问题来源

那么为什么之前接口不会出现异常呢?是tomcat版本不同导致的。

查看源码后发现:org.apache.tomcat.util.http.parser.HttpParser

tomcat 8.2.3 版本及 tomcat 7.0.82 ,都有如下代码,读取配置

String prop = System.getProperty("tomcat.util.http.parser.HttpParser.requestTargetAllow");

if (prop != null) {

for (int i = 0; i < prop.length(); i++) {

char c = prop.charAt(i);

if (c == '{' || c == '}' || c == '|') {

REQUEST_TARGET_ALLOW[c] = true;

} else {

log.warn(sm.getString("httpparser.invalidRequestTargetCharacter",

Character.valueOf(c)));

}

}

}

而tomcat 8.0.14 版本中并没有读取配置,对 |{}的处理,而是默认为合法字符。

static {

// Setup the flag arrays

for (int i = 0; i < 128; i++) {

if (i < 32) {

isToken[i] = false;

} else if (i == '(' || i == ')' || i == '' || i == '@' ||

i == ',' || i == ';' || i == ':' || i == '\\' || i == '\"' ||

i == '/' || i == '[' || i == ']' || i == '?' || i == '=' ||

i == '{' || i == '}' || i == ' ' || i == '\t') {

isToken[i] = false;

} else {

isToken[i] = true;

}

if (i >= '0' && i <= '9' || i >= 'A' && i <= 'F' ||

i >= 'a' && i <= 'f') {

isHex[i] = true;

} else {

isHex[i] = false;

}

}

}

虽然没有进行全面的比对,但可以看出在 8.0.x 左右的一些版本中,tomcat.util.http.parser.HttpParser. requestTargetAllow这个配置是没有生效的,即 |{}这3个符号认为是合法的。

结论:

tomcat.util.http.parser.HttpParser. requestTargetAllow这个字段可以解决URL中存在 |{}字符的问题。

tomcat自tomcat 8.0.35版本之后对URL参数做了比较规范的限制,必须遵循RFC 7230 and RFC 3986规范,对于非保留字字符(json格式的请求参数)必须做转义操作。

转载至链接:/pding/blog/1794176

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。