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?
Thanks,
James

Reply via email to