Thank you for responding, Chris.

An example URL that causes this issue has a format like the following:
http://localhost:8080/group/{groupName}

A URL like this works just fine and is able to set the groupName to
"(ON/QC) LOCAL":
http://localhost:8080/group/%28ON%2FQC%29%20LOCAL
When I call `request.getServletPath()` it returns "/group/(ON%2FQC) LOCAL"

However, this does not work when the '\' character exists. For example,
when expecting the groupName to be set to "(ON\QC) LOCAL":
http://localhost:8080/group/%28ON%5CQC%29%20LOCAL
When I call `request.getServletPath()` it returns "/group/(ON/QC) LOCAL".
This splits the path parameter in 2, causing my application to return a 404.
I would prefer the behavior be similar to the '/' when
encodedSolidusHandling PASS_THROUGH config is set, so calling
`request.getServletPath()` would return "/group/(ON%5CQC) LOCAL"

My use case is only concerned with the path portion of the URL, but I don't
believe the query portion of the URL is impacted by this same issue.
For these tests:
* allowBackslash = true, otherwise the '\' case would generate a 400
* encodeSolidusHandling = PASS_THROUGH, otherwise the '/' case would
generate a 400
* The application is written in Spring WebMVC using the embedded Tomcat, so
I was able to place a breakpoint at the end of
CoyoteAdapter.postParseRequest(...) to interrogate the
org.apache.catalina.connector.Request before passing on to the Spring code
just to be sure Spring didn't muddy the water somehow, though it doesn't
appear to manipulate anything as the results are the same.

>From what I can tell, any work-around to my issue will either need to be
applied at or before the call to CoyoteAdapter.postParseRequest(...).
-James

On Wed, Jan 15, 2025 at 4:26 PM Christopher Schultz <
ch...@christopherschultz.net> wrote:

> James,
>
> On 1/15/25 2:39 PM, James Matlik wrote:
> > I have an API that needs Tomcat to accept both the escaped forward slash
> > '/' (%2F) and escaped backslash '\' (%5C) and pass them through to the
> > servlet (Spring application). This need exists to support path parameters
> > with special URL relevant characters. I've been able to successfully get
> > the forward slash to work by setting encodedSolidusHandling to true as
> this
> > stops the escaped forward slash from becoming unescaped. Unfortunately,
> > this does not have the same effect on the backslash, so the UDecoder
> still
> > converts "%5C" to '\'. Despite this, I was hoping I could work with the
> > decoded '\' if it were passed through without being treated as special,
> but
> > then the URL is normalized. When I set allowBackslash to true, Tomcat's
> > normalization no longer generates a 400 response, but transforms the '\'
> > character to a '/'.
> >
> > To me, this looks like a bug in Tomcat since it treats '\' (when allowed)
> > as an alias for '/' but does not support the same passthrough behavior
> when
> > escaped. Additionally, unless I am missing something, I don't see any
> > reasonable extension points or further configuration to change this
> > behavior.
> >
> > Relevant source files:
> > * UDecoder:
> >
> https://github.com/apache/tomcat/blob/main/java/org/apache/tomcat/util/buf/UDecoder.java#L80-L172
> > * CoyoteAdapter:
> >
> https://github.com/apache/tomcat/blob/main/java/org/apache/catalina/connector/CoyoteAdapter.java#L629-L646
> > and
> >
> https://github.com/apache/tomcat/blob/main/java/org/apache/catalina/connector/CoyoteAdapter.java#L1132-L1144
> >
> > It seems as if the change I need would be best implemented via a 1 line
> > code change to UDecoder on line 133 of the linked file:
> >    if (res == '/') {
> > becomes:
> >    if (res == '/' || res == '\') {
> >
> > Any suggestions on how to work through this issue?
>
> How about some examples of URLs which contain these characters?
>
> It would be great to see examples along with what you expect each kind
> of HttpServletRequest.getFoo call o return.
>
> You mentioned path parameters; are all these issues related to the
> encoding of path parameters specifically, or are some of these
> characters also in other parts of the URL?
>
> -chris
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>

Reply via email to