Bug 66068 - Asynchronous request processing changes IP behind RemoteIpValve
Summary: Asynchronous request processing changes IP behind RemoteIpValve
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 9
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 9.0.62
Hardware: All All
: P2 major (vote)
Target Milestone: -----
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-05-17 12:56 UTC by Igor Tymoshchuk
Modified: 2022-05-26 16:57 UTC (History)
0 users



Attachments
example project (4.74 KB, application/x-7z-compressed)
2022-05-17 12:56 UTC, Igor Tymoshchuk
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Igor Tymoshchuk 2022-05-17 12:56:27 UTC
Created attachment 38287 [details]
example project

Hi guys

Request that is made to the Tomcat 9 server that is behind load balancer and with RemoteIpValve enabled.

RemoteIpValve is configured in server.xml exactly before access log valve as follows:
   <Valve className="org.apache.catalina.valves.RemoteIpValve"
       remoteIpHeader="x-forwarded-for"
       protocolHeader="x-forwarded-proto"
   />

In the case request is processed in synchronous way the right ip of caller is received from request.getRemoteAddr()

In the case request is moved to asynchronous mode by request.startAsync( request, response ) and is processed on the same thread the right ip of client is received from asyncContext.getRequest().getRemoteAddr()

In the case request is moved to asynchronous mode by request.startAsync( request, response ) and is processed on the OTHER thread the ip of client is NOT received from asyncContext.getRequest().getRemoteAddr(), but ip of proxy server.

In all cases access log prints right client ip.

Example source code is attached both with compiled .war file.
Example request is made to:
   http://localhost/remoteipvalve-bug-example/
with the following headers:
   X-Forwarded-For: 1.2.3.4
   X-Forwarded-Proto: 443

Example logger result:
17-May-2022 15:47:19.623 WARNING [http-nio-80-exec-53] RootServlet.doGet Request ip before async start: 1.2.3.4
17-May-2022 15:47:19.623 WARNING [http-nio-80-exec-53] RootServlet.doGet Request ip after async started: 1.2.3.4)
17-May-2022 15:47:19.625 WARNING [Thread-67] RootServlet$1.run Request ip after async started: 127.0.0.1)
Comment 1 Mark Thomas 2022-05-19 15:44:05 UTC
I think the fix for this is fairly simple. If the request is in async mode, we don't reset the request in the finally block after calling the next Valve in the pipeline.

Assuming there are no objections to this approach, I'll apply a patch to that effect in a couple of days.
Comment 2 Mark Thomas 2022-05-26 16:57:06 UTC
Fixed in:
- 10.1.x for 10.1.0-M16 onwards
- 10.0.x for 10.0.22 onwards
- 9.0.x for 9.0.64 onwards
- 8.5.x for 8.5.80 onwards