[
https://issues.redhat.com/browse/WFLY-14269?page=com.atlassian.jira.plugi...
]
Marton Csukas updated WFLY-14269:
---------------------------------
Description:
I have a _Wildfly 21.0.0.Final_ running a Spring Boot REST application and I encountered a
strange behaviour with {{GET}} requests containing {{|}} (pipe) character in the query
parameters.
{{|}} (pipe) character is unsafe according to the RFC1738 specification of HTTP, while
RFC3986 allows for the encoding of Unicode characters.
However, Wildfly (Undertow) has an option
on {{http-listener}} and {{https-listener}} entries
to {{allow-unescaped-characters-in-url}}.
Full {{standalone.xml}} [here|https://gist.github.com/martoncsukas/746695...
masked sensitive info.
The application is running on {{127.0.0.1:443}}, and is exposed to the outside world
as [https://myappname.company.com|https://myappname.company.com/] via a PulseSecure load
balancer, where {{myappname}} is a CNAME registered on {{company.com}} DNS, pointing to
the load balancers VIP.
The {{allow-unescaped-characters-in-url="true"}} bit works fine in these cases
(so when the request containing {{|}} _doesn't_ go through the Windows {{hosts}} file,
but goes through the load balancer).
However, when I add an entry to the Windows {{hosts}} file to bypass the load balancer,
such as:
127.0.0.1
myappname.company.com
…then the {{GET}} request containing {{|}} in its query parameter won't work - in
fact it looks like it is not even hitting the server, as if
Wildfly/Undertow's {{allow-unescaped-characters-in-url="true"}} setting
wouldn't even be there.
Now this causes issues with our local testing. Is there any change we can make so
that {{allow-unescaped-characters-in-url="true"}} would be always respected?
We know that ideally {{|}} should be encoded to {{%7D}}, but we would be interested in a
solution (ideally on Wildfly level) that would
make {{allow-unescaped-characters-in-url="true"}} work every time, irrespective
whether the requests is going through {{hosts}} file or the load balancer.
The very strange this is that it was working fine in _Wildfly 20.0.0.Final_, even
without {{allow-unescaped-characters-in-url="true"}} being
in {{standalone.xml}}.
Full request source:
{code:java}
GET /rest/v3/news/_lite?mql=customerId=1212090,caseId=1078841||caseId=null
HTTP/1.1
Host:
myappname.company.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
sec-ch-ua: "Google Chrome";v="87", " Not;A
Brand";v="99", "Chromium";v="87"
Accept: application/json, text/plain, */*
Authorization: Bearer masked
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/87.0.4280.88 Safari/537.36
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer:
https://myappname.company.com/anotherPage
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9
Cookie: JSESSIONID=masked; _ga=GA1.2.1926489359.1609961117; _gid=masked;
_gat_gtag_UA_112487518_3=1{code}
Server log excerpt with TRACE level logging attached. The faulty request
is */rest/v3/news/_lite* - it can be seen in one of the TRACE logs with | (pipe) symbol in
its query string, but then it doesn't get "deeper", doesn't get
processed at all, doesn't get logged by {{io.undertow.request.dump}} either.
The error I get on DEBUG level:
{code:java}
2021-01-08 01:32:20,660 DEBUG [io.undertow.request.io] (default I/O-7) Sending rststream
on channel Http2Channel peer /127.0.0.1:50355 local /127.0.0.1:443[ No Receiver [] -- []
-- []] stream 1: java.nio.channels.ClosedChannelException
at
io.undertow.core@2.2.2.Final//io.undertow.protocols.http2.Http2Channel.sendRstStream(Http2Channel.java:1059)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.http2.Http2ReceiveListener.handleRequests(Http2ReceiveListener.java:135)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.http2.Http2ReceiveListener.handleEvent(Http2ReceiveListener.java:115)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.http2.Http2ReceiveListener.handleEvent(Http2ReceiveListener.java:73)
at
org.jboss.xnio@3.8.2.Final//org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:952)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:932)
at
org.jboss.xnio@3.8.2.Final//org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener$1.run(AbstractFramedChannel.java:963)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:939)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:932)
at
org.jboss.xnio@3.8.2.Final//org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at
org.jboss.xnio@3.8.2.Final//org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
at
io.undertow.core@2.2.2.Final//io.undertow.protocols.ssl.SslConduit$SslReadReadyHandler.readReady(SslConduit.java:1211)
at
io.undertow.core@2.2.2.Final//io.undertow.protocols.ssl.SslConduit$1.run(SslConduit.java:180)
at
io.undertow.core@2.2.2.Final//io.undertow.protocols.ssl.SslConduit$2.run(SslConduit.java:195)
at
org.jboss.xnio.nio@3.8.2.Final//org.xnio.nio.WorkerThread.safeRun(WorkerThread.java:612)
at
org.jboss.xnio.nio@3.8.2.Final//org.xnio.nio.WorkerThread.run(WorkerThread.java:479){code}
was:
I have a _Wildfly 21.0.0.Final_ running a Spring Boot REST application and I encountered a
strange behaviour with {{GET}} requests containing {{|}} (pipe) character in the query
parameters.
{{|}} (pipe) character is unsafe according to the RFC1738 specification of HTTP, while
RFC3986 allows for the encoding of Unicode characters.
However, Wildfly (Undertow) has an option
on {{http-listener}} and {{https-listener}} entries
to {{allow-unescaped-characters-in-url}}.
Full {{standalone.xml}} [here|https://gist.github.com/martoncsukas/746695...
masked sensitive info.
The application is running on {{127.0.0.1:443}}, and is exposed to the outside world
as [https://myappname.company.com|https://myappname.company.com/] via a PulseSecure load
balancer, where {{myappname}} is a CNAME registered on {{company.com}} DNS, pointing to
the load balancers VIP.
The {{allow-unescaped-characters-in-url="true"}} bit works fine in these cases
(so when the request containing {{|}} _doesn't_ go through the Windows {{hosts}} file,
but goes through the load balancer).
However, when I add an entry to the Windows {{hosts}} file to bypass the load balancer,
such as:
127.0.0.1
myappname.company.com
…then the {{GET}} request containing {{|}} in its query parameter won't work - in
fact it looks like it is not even hitting the server, as if
Wildfly/Undertow's {{allow-unescaped-characters-in-url="true"}} setting
wouldn't even be there.
Now this causes issues with our local testing. Is there any change we can make so
that {{allow-unescaped-characters-in-url="true"}} would be always respected?
We know that ideally {{|}} should be encoded to {{%7D}}, but we would be interested in a
solution (ideally on Wildfly level) that would
make {{allow-unescaped-characters-in-url="true"}} work every time, irrespective
whether the requests is going through {{hosts}} file or the load balancer.
The very strange this is that it was working fine in _Wildfly 20.0.0.Final_, even
without {{allow-unescaped-characters-in-url="true"}} being
in {{standalone.xml}}.
Full request source:
{code:java}
GET /rest/v3/news/_lite?mql=customerId=1212090,caseId=1078841||caseId=null
HTTP/1.1
Host:
myappname.company.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
sec-ch-ua: "Google Chrome";v="87", " Not;A
Brand";v="99", "Chromium";v="87"
Accept: application/json, text/plain, */*
Authorization: Bearer masked
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/87.0.4280.88 Safari/537.36
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer:
https://myappname.company.com/anotherPage
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9
Cookie: JSESSIONID=masked; _ga=GA1.2.1926489359.1609961117; _gid=masked;
_gat_gtag_UA_112487518_3=1{code}
Server log excerpt with TRACE level logging attached. The faulty request
is */rest/v3/news/_lite* - it can be seen in one of the TRACE logs with | (pipe) symbol in
its query string, but then it doesn't get "deeper", doesn't get
processed at all.
The error I get on DEBUG level:
{code:java}
2021-01-08 01:32:20,660 DEBUG [io.undertow.request.io] (default I/O-7) Sending rststream
on channel Http2Channel peer /127.0.0.1:50355 local /127.0.0.1:443[ No Receiver [] -- []
-- []] stream 1: java.nio.channels.ClosedChannelException
at
io.undertow.core@2.2.2.Final//io.undertow.protocols.http2.Http2Channel.sendRstStream(Http2Channel.java:1059)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.http2.Http2ReceiveListener.handleRequests(Http2ReceiveListener.java:135)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.http2.Http2ReceiveListener.handleEvent(Http2ReceiveListener.java:115)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.http2.Http2ReceiveListener.handleEvent(Http2ReceiveListener.java:73)
at
org.jboss.xnio@3.8.2.Final//org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:952)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:932)
at
org.jboss.xnio@3.8.2.Final//org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener$1.run(AbstractFramedChannel.java:963)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:939)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:932)
at
org.jboss.xnio@3.8.2.Final//org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at
org.jboss.xnio@3.8.2.Final//org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
at
io.undertow.core@2.2.2.Final//io.undertow.protocols.ssl.SslConduit$SslReadReadyHandler.readReady(SslConduit.java:1211)
at
io.undertow.core@2.2.2.Final//io.undertow.protocols.ssl.SslConduit$1.run(SslConduit.java:180)
at
io.undertow.core@2.2.2.Final//io.undertow.protocols.ssl.SslConduit$2.run(SslConduit.java:195)
at
org.jboss.xnio.nio@3.8.2.Final//org.xnio.nio.WorkerThread.safeRun(WorkerThread.java:612)
at
org.jboss.xnio.nio@3.8.2.Final//org.xnio.nio.WorkerThread.run(WorkerThread.java:479){code}
Wildfly 21's “allow-unescaped-characters-in-url” ignored when
HTTP2 request going through Windows hosts file
------------------------------------------------------------------------------------------------------------
Key: WFLY-14269
URL:
https://issues.redhat.com/browse/WFLY-14269
Project: WildFly
Issue Type: Bug
Components: Web (Undertow)
Affects Versions: 21.0.0.Final, 21.0.1.Final, 21.0.2.Final
Reporter: Marton Csukas
Assignee: Flavia Rainone
Priority: Major
Attachments: server log (trace).txt
I have a _Wildfly 21.0.0.Final_ running a Spring Boot REST application and I encountered
a strange behaviour with {{GET}} requests containing {{|}} (pipe) character in the query
parameters.
{{|}} (pipe) character is unsafe according to the RFC1738 specification of HTTP, while
RFC3986 allows for the encoding of Unicode characters.
However, Wildfly (Undertow) has an option
on {{http-listener}} and {{https-listener}} entries
to {{allow-unescaped-characters-in-url}}.
Full {{standalone.xml}} [here|https://gist.github.com/martoncsukas/746695...
masked sensitive info.
The application is running on {{127.0.0.1:443}}, and is exposed to the outside world
as [https://myappname.company.com|https://myappname.company.com/] via a PulseSecure load
balancer, where {{myappname}} is a CNAME registered on {{company.com}} DNS, pointing to
the load balancers VIP.
The {{allow-unescaped-characters-in-url="true"}} bit works fine in these cases
(so when the request containing {{|}} _doesn't_ go through the Windows {{hosts}} file,
but goes through the load balancer).
However, when I add an entry to the Windows {{hosts}} file to bypass the load balancer,
such as:
127.0.0.1
myappname.company.com
…then the {{GET}} request containing {{|}} in its query parameter won't work - in
fact it looks like it is not even hitting the server, as if
Wildfly/Undertow's {{allow-unescaped-characters-in-url="true"}} setting
wouldn't even be there.
Now this causes issues with our local testing. Is there any change we can make so
that {{allow-unescaped-characters-in-url="true"}} would be always respected?
We know that ideally {{|}} should be encoded to {{%7D}}, but we would be interested in a
solution (ideally on Wildfly level) that would
make {{allow-unescaped-characters-in-url="true"}} work every time, irrespective
whether the requests is going through {{hosts}} file or the load balancer.
The very strange this is that it was working fine in _Wildfly 20.0.0.Final_, even
without {{allow-unescaped-characters-in-url="true"}} being
in {{standalone.xml}}.
Full request source:
{code:java}
GET /rest/v3/news/_lite?mql=customerId=1212090,caseId=1078841||caseId=null
HTTP/1.1
Host:
myappname.company.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
sec-ch-ua: "Google Chrome";v="87", " Not;A
Brand";v="99", "Chromium";v="87"
Accept: application/json, text/plain, */*
Authorization: Bearer masked
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/87.0.4280.88 Safari/537.36
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer:
https://myappname.company.com/anotherPage
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9
Cookie: JSESSIONID=masked; _ga=GA1.2.1926489359.1609961117; _gid=masked;
_gat_gtag_UA_112487518_3=1{code}
Server log excerpt with TRACE level logging attached. The faulty request
is */rest/v3/news/_lite* - it can be seen in one of the TRACE logs with | (pipe) symbol in
its query string, but then it doesn't get "deeper", doesn't get
processed at all, doesn't get logged by {{io.undertow.request.dump}} either.
The error I get on DEBUG level:
{code:java}
2021-01-08 01:32:20,660 DEBUG [io.undertow.request.io] (default I/O-7) Sending rststream
on channel Http2Channel peer /127.0.0.1:50355 local /127.0.0.1:443[ No Receiver [] -- []
-- []] stream 1: java.nio.channels.ClosedChannelException
at
io.undertow.core@2.2.2.Final//io.undertow.protocols.http2.Http2Channel.sendRstStream(Http2Channel.java:1059)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.http2.Http2ReceiveListener.handleRequests(Http2ReceiveListener.java:135)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.http2.Http2ReceiveListener.handleEvent(Http2ReceiveListener.java:115)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.http2.Http2ReceiveListener.handleEvent(Http2ReceiveListener.java:73)
at
org.jboss.xnio@3.8.2.Final//org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:952)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:932)
at
org.jboss.xnio@3.8.2.Final//org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener$1.run(AbstractFramedChannel.java:963)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:939)
at
io.undertow.core@2.2.2.Final//io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:932)
at
org.jboss.xnio@3.8.2.Final//org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at
org.jboss.xnio@3.8.2.Final//org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
at
io.undertow.core@2.2.2.Final//io.undertow.protocols.ssl.SslConduit$SslReadReadyHandler.readReady(SslConduit.java:1211)
at
io.undertow.core@2.2.2.Final//io.undertow.protocols.ssl.SslConduit$1.run(SslConduit.java:180)
at
io.undertow.core@2.2.2.Final//io.undertow.protocols.ssl.SslConduit$2.run(SslConduit.java:195)
at
org.jboss.xnio.nio@3.8.2.Final//org.xnio.nio.WorkerThread.safeRun(WorkerThread.java:612)
at
org.jboss.xnio.nio@3.8.2.Final//org.xnio.nio.WorkerThread.run(WorkerThread.java:479){code}
--
This message was sent by Atlassian Jira
(v8.13.1#813001)