It seems that Bug 66488 was never really fixed. Because we saw several occastion where the request URL was overwritten by other Header data like User agent (or parts of the URL were deleted) like in these two instances: using Tomcat Embedded 9.0.83 java.lang.IllegalStateException: Unable to find match between the canonical context path [/app1] and the URI presented by the user agent [f=70d24a53-fe99-4f9c-a512-5f5abd5bce3] or using the Standalone Tomcat 9.0.85 java.lang.IllegalStateException: Unable to find match between the canonical context path [/app2] and the URI presented by the user agent [--WebKitFormBoundaryMVjw2B39oX3x4Oii] The exception is thrown when a POST request was sent by the browser after the session timed out. Workaround: Downgrade to Tomcat 9.0.35 (we didn't check later Versions in between the affected ones, yet).
Are you using any sort of monitoring agent? There have been multiple issues around how these access MessageByte instances.
No response after a week. If the requested information is not provided, the issue will be closed as WORKSFORME.
Closing as WORKSFORME due to lack of response from OP. If you still experience this issue and wish to re-open this bug please provide the minimum steps necessary - including any web application with source - to reproduce this issue.
Also encountering this bug on upgrading from Tomcat 9.0.73 to 9.0.85 After the upgrade I can replicate by logging in, bringing up a page, letting my session expire and then submitting a POST. It brings up the login page and then after logging in throws a server error 500. Downgrading back to 9.0.73 worked to fix it. I am not running any sort of monitoring agent. It looks like the POST is getting mangled into a broken GET somehow? From the access log: 10.64.249.226 - AN00040 [29/Feb/2024:13:53:24 -0600] "POST e=ryan&fname=ryan&bed=&ssn=&idnum=&topNavSearc HTTP/1.1" 500 1891 Error thrown: Feb 29, 2024 1:53:24 PM org.apache.catalina.core.StandardHostValve custom SEVERE: Exception Processing ErrorPage[errorCode=500, location=/error/ServletError.jsp] java.lang.IllegalStateException: Unable to find match between the canonical context path [/conline] and the URI presented by the user agent [e=ryan&fname=ryan&bed=&ssn=&idnum=&topNavSearc] We are running tomcat using Java 8 on a RHEL 7 machine.
No reproducible test case provided as required in comment #3 - returning to WORKSFORME
Lol, I'll try to get you the test case tomorrow. I assure you that this is a bug.
Created attachment 39607 [details] Sample web application to reproduce bug I am attaching a very simple web application that reliably reproduces this bug. To create this, I started with the "Hello World" Tomcat sample war and modified only hello.jsp, web.xml and added a Login.jsp. This application is expecting an authentication realm named "cortrac-login". You could change this in web.xml. We are using Active Directory for authentication, but I wouldn't think that would matter. To reproduce the bug: 1) Navigate to sample/hello.jsp. It should prompt you to login. 2) After logging in, let the session expire. I set the session timeout to 1 minute for easy testing 3) Click the button on the page. If your session expired, you should be prompted to login again and after you do, you will see the error. Note the 2 lines in the hello.jsp <%= request.getParameter("navCurrentRid") %> <%= request.getContextPath() %> These 2 lines appear to be the core of the bug. The request.getParameter seems to be corrupting the URI causing the request.getContextPath to error. Please let me know if you need more information. -Noah Error returned: Type Exception Report Message An exception occurred processing [/hello.jsp] at line [21] Description The server encountered an unexpected condition that prevented it from fulfilling the request. Exception org.apache.jasper.JasperException: An exception occurred processing [/hello.jsp] at line [21] 18: </table> 19: 20: <%= request.getParameter("navCurrentRid") %> 21: <%= request.getContextPath() %> 22: 23: <form action="" method="post" id="quicksearchform" name="quicksearchform"> 24: <input id="lname" name="lname" type="hidden"><input id="fname" name="fname" type="hidden"><input id="bed" name="bed" type="hidden"><input id="ssn" name="ssn" type="hidden"><input id="idnum" name="idnum" type="hidden"><input id="topNavSearch" name="topNavSearch" type="hidden" value="true"> Stacktrace: org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:610) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:489) org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:379) org.apache.jasper.servlet.JspServlet.service(JspServlet.java:327) javax.servlet.http.HttpServlet.service(HttpServlet.java:623) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter(HttpHeaderSecurityFilter.java:129) Root Cause java.lang.IllegalStateException: Unable to find match between the canonical context path [/sample] and the URI presented by the user agent [e=&fname=&bed=&ss] org.apache.catalina.connector.Request.getContextPath(Request.java:2136) org.apache.catalina.connector.RequestFacade.getContextPath(RequestFacade.java:583) org.apache.jsp.hello_jsp._jspService(hello_jsp.java:139) org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) javax.servlet.http.HttpServlet.service(HttpServlet.java:623) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:466) org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:379) org.apache.jasper.servlet.JspServlet.service(JspServlet.java:327) javax.servlet.http.HttpServlet.service(HttpServlet.java:623) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter(HttpHeaderSecurityFilter.java:129) Note The full stack trace of the root cause is available in the server logs.
Reopening the ticket based on providing a test case as requested.
Before you ask, I just replicated this on a clean install of 9.0.85 RHEL 9 JDK 8 I only edited tomcat_users.xml to uncomment the admin user and change the password Note that to get the sample app to work with the UserDatabase realm, I had to edit the web.xml to change: <auth-constraint> <role-name>*</role-name> </auth-constraint> to: <auth-constraint> <role-name>manager-gui</role-name> </auth-constraint> The cortrac-login realm name that I mentioned above doesn't seem to matter. After this, the same steps as above replicate 1) Navigate to sample/hello.jsp. It should prompt you to login. 2) After logging in, let the session expire. I set the session timeout to 1 minute for easy testing 3) Click the button on the page. If your session expired, you should be prompted to login again and after you do, you will see the error.
I was able to reproduce the problem on 9.0.85, but not on 9.0.86 (nor on 11.0.0-M17). Looks like something fixed it recently, but there's nothing obvious to me in the changelog for 9.0.86.
Ok so maybe there's still something with the query string then.
Thanks for the test case. I am able recreate the issue now. The root cause is a combination of this code in the FormAuthenticator: https://github.com/apache/tomcat/blob/9.0.x/java/org/apache/catalina/authenticator/FormAuthenticator.java#L637 and the changes to MessageBytes back in 9.0.0-M5 and the fix for bug 66627 in 9.0.77. This has been partially fix in 9.0.86 as a side-effect of bug 68026 but it looks as if query string is still affected. I have a more robust fix in mind that I want to test before committing. Assuming all goes well this should be fixed later today and included in the next release round.
I was planning to do: public String getQueryString() { return coyoteRequest.queryString().toStringType(); } Since the idea from the FormAuthenticator is to change the MessageBytes type to String and toString no longer does it (but toStringType does).
That was my first thought but: 1. I didn't want correct behaviour of the FormAuthenticator to depend on caching decisions in Request that could - in theory - change over time 2. I didn't cache query string when I last looked at it as there were some usage patterns that could trigger conversion back to byte My plan (which looks to work) is to call toStringType() directly from FormAuthenticator
Fixed in: - 11.0.x for 11.0.0-M18 onwards - 10.1.x for 10.1.20 onwards - 9.0.x for 9.0.87 onwards - 8.5.x for 8.5.100 onwards