On Thu, Feb 26, 2026 at 12:55 AM Mark Thomas via dev <[email protected]> wrote:
> 25 Feb 2026 23:29:29 Dimitris Soumis <[email protected]>: > > > On Wed, Feb 25, 2026 at 11:31 AM Mark Thomas <[email protected]> wrote: > > > >> 25 Feb 2026 07:32:00 Dimitris Soumis <[email protected]>: > >> > >>> On Thu, Feb 19, 2026 at 5:56 PM Christopher Schultz < > >>> [email protected]> wrote: > >>> > >>>> All, > >>>> > >>>> I recently made a change to the CSRF prevention filter in > >>>> 98187ffef4cec6043a602b500a2e3dfd5ef71c20 that removed duplicate csrf > >>>> tokens in URLs in case they were being repeatedly run through > >>>> HttpServletResponse.encode(). > >>>> > >>>> It's possible there is a bug hiding in there but I'd like some > >>>> feedback. > >>>> > >>>> I'm using Velocity Tools to generate URLs and there is a tool class > >>>> called LinkTool. It generates links with a builder-style interface > >>>> with > >>>> a base URL, parameters, and so on. > >>>> > >>>> After upgrading to 9.0.115, I'm finding that a very small number of > >>>> these links are being broken due to an interaction between LinkTool, > >>>> my > >>>> code, and the CsrfPreventionFilter's massaging of the URLs its > >>>> producing. > >>>> > >>>> The LinkTool is configured to produce HTML5-style URLs where the & > >>>> characters are encoded as &. I did triple-check to confirm that > >>>> this > >>>> was both expected and a reasonable reading of the HTML standard, > >>>> which > >>>> it appears to be. That is, use of & is actually recommended in > >>>> HTML > >>>> pages. RFC 6068 and WHATWG agree on this point whi, frankly, is > >>>> amazing > >>>> enough that I'll go ahead and call it a Law. > >>>> > >>>> Anyway, it looks like the original URL is being produced something > >>>> like > >>>> this: > >>>> > >>>> /context/path?csrf=C076D4BC8A49A67BE4EE7517C3A0129D > >>>> > >>>> So far so good. Note that the URL has already gone through > >>>> response.encodeURL() because it's got a csrf parameter in it. > >>>> > >>>> Then another parameter is added by parsing the URL above (because > >>>> #reasons, this is where my code comes in) and the URL then becomes: > >>>> > >>>> /context/path?amp;id=4&csrf=C076D4BC8A49A67BE4EE7517C3A0129D > >>>> > >>>> I haven't traced through the code, but I believe what's happening is > >>>> this: > >>>> > >>>> 1. My code, through LinkTool, adds the "id" = "4" parameter > >>>> 2. LinkTool re-generates the URL String including an & parameter > >>>> separator > >>>> 3. LinkTool runs the result through response.encodeURL > >>>> 4. CsrfPreventionFilter removes any existing CSRF query parameters; > >>>> it > >>>> finds one at the beginning of the URL and removes everything up to > >>>> the > >>>> next & character > >>>> 5. CsrfPreventionFilter adds its csrf token to the end of the URL > >>>> > >>>> The URL is now rendered and it's broken. :/ > >>>> > >>>> I think plausible arguments could be made that this is a bug in any > >>>> of > >>>> these 3 products: mine, VelocityTools, or Tomcat. > >>>> > >>>> I'm primarily interested in getting this fixed in *my* product, but > >>>> I > >>>> wonder how many other products it might effect for similar reasons. > >>>> > >>>> So, the topic here is only Tomcat-related: do we think that the > >>>> CsrfPreventionFilter should consider & to be a request parameter > >>>> separator for the purposes of removing its own duplicates? > >>>> > >>>> My reading of a few specs suggests that looking for "&" should > >>>> be > >>>> safe since ; is a reserved character and ought to be escaped if the > >>>> user > >>>> actually intends for there to be an honest-to-goodness semicolon in > >>>> their request parameter name or value. Thus, & must mean that a > >>>> literal & was intended. > >>>> > >>>> So I think it's safe (and proper) for Tomcat to consume "&" and > >>>> not > >>>> just "&" in this case. > >>>> > >>>> Opinions? > >>>> > >>>> -chris > >>>> > >>>> > >>>> > >>>> --------------------------------------------------------------------- > >>>> To unsubscribe, e-mail: [email protected] > >>>> For additional commands, e-mail: [email protected] > >>>> > >>>> > >>> I agree, Tomcat should be fixed to consume "&", since it > >>> currently > >>> breaks valid urls. > >>> > >>> Kind regards, > >>> Dimitris > >> > >> I disagree. > >> > >> Something LinkTool ? is confusing HTML encoding and URL encoding. > >> > >> A literal & is encoded as & in HTML (and XML). > >> > >> A literal & is encoded as %26 if it needs to be encoded in a URI. > >> > >> I think you need to get to the bottom of why a URI is being encoded > >> using > >> HTML encoding and fix that. Once that has been addressed then you can > >> look at the URI and see if any further work is required. > >> > >> Mark > >> > >> --------------------------------------------------------------------- > >> To unsubscribe, e-mail: [email protected] > >> For additional commands, e-mail: [email protected] > >> > >> > > Still, I believe removeQueryParameters() should be modified to handle > > "%26" > > and other possible encodings. > > %26 shouldn't need any special handling. It should pass through unaltered > - as should any %nn encoding. > > > Although "&" is HTML encoding and seems that LinkTool is > > misbehaving, > > the result is still a valid URL. Thus, why not to catch that case? > > Two reasons. > > If the URI is valid Tomcat can't tell if it is actually what the user > wanted or if it is because LinkTool is being used and LinkTool is > misbehaving. > > Unless there is a very strong case to do so (think major browser vendor > not following the RFCs and having a long history of ignoring bug reports > causing breakage that affects lots of Tomcat users) we don't provide > workarounds for other people's broken code. > > Mark > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > > It makes total sense, thanks for the explanation. Dimitris
