最近项目tomcat升级,从6升到9,碰到了一系列问题。其中,拼特殊字符串时,会报错。报错显示
java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:468)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:294)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol
C
o
n
n
e
c
t
i
o
n
H
a
n
d
l
e
r
.
p
r
o
c
e
s
s
(
A
b
s
t
r
a
c
t
P
r
o
t
o
c
o
l
.
j
a
v
a
:
853
)
o
r
g
.
a
p
a
c
h
e
.
t
o
m
c
a
t
.
u
t
i
l
.
n
e
t
.
N
i
o
E
n
d
p
o
i
n
t
ConnectionHandler.process(AbstractProtocol.java:853) org.apache.tomcat.util.net.NioEndpoint
ConnectionHandler.process(AbstractProtocol.java:853)org.apache.tomcat.util.net.NioEndpointSocketProcessor.doRun(NioEndpoint.java:1587)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor
W
o
r
k
e
r
.
r
u
n
(
T
h
r
e
a
d
P
o
o
l
E
x
e
c
u
t
o
r
.
j
a
v
a
:
624
)
o
r
g
.
a
p
a
c
h
e
.
t
o
m
c
a
t
.
u
t
i
l
.
t
h
r
e
a
d
s
.
T
a
s
k
T
h
r
e
a
d
Worker.run(ThreadPoolExecutor.java:624) org.apache.tomcat.util.threads.TaskThread
Worker.run(ThreadPoolExecutor.java:624)org.apache.tomcat.util.threads.TaskThreadWrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)
Note The full stack trace of the root cause is available in the server logs.
出现这种问题的原因是在低版本中存在安全漏洞代号CVE-2016-6816
在高版本被修复,高版本默认不允许在访问路径后边追加不符合RFC 3986文档规定的字符(注意有些字符虽然符合文档规范,但是可能不安全存在歧义,也会被拦截,比如 [])
根据网上查的资料,解决思路有几种。降级tomcat,配属性文件等。
先分析将tomcat降级的情况,这是不合理的,升级tomcat是为了项目运行更流畅。tomcat6用的是bio,tomcat9用的是nio,很显然nio比bio更流畅,而且也能解决tomcat漏洞。
配属性文件这种方法,在tomcat8.5,tomcat7里面可行,解决办法如下:
tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
这行配置在属性文件中是注释掉的,需要放开注释
其中,属性文件value值的配置,只能配置| { }这三个值,如果要配置[ ] \ 这种值是不起作用的
而且,这种办法对9.0.22一系列tomcat9的版本是不起作用的,因为属性文件中没有这些注释,配置了也没有用。根据文档,直接说解决办法。
在server.xml文件的Connector连接器中,增加这两个属性配置,key值为属性名,value值是要过滤的字符串的值,配置如下:
relaxedPathChars="|{}[]^" relaxedQueryChars="|{}[]^"
配置完成后,重新启动服务,经过验证,是可行的
有一点需要注意:这两个属性值,如果你需要配置,千万注意 <> 的配置,配置不对,tomcat启动不起来。这两个属性是全局的属性配置,在tomcat7、tomcat8中也可以配置
属性文件的文档资料链接地址:https://tomcat.apache.org/tomcat-9.0-doc/config/http.html