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. Although "&" is HTML encoding and seems that LinkTool is misbehaving, the result is still a valid URL. Thus, why not to catch that case? Dimitris
