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 &amp;. 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 &amp; 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 &amp; 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 &amp; to be a request parameter
> separator for the purposes of removing its own duplicates?
>
> My reading of a few specs suggests that looking for "&amp;" 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, &amp; must mean that a
> literal & was intended.
>
> So I think it's safe (and proper) for Tomcat to consume "&amp;" 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  "&amp;", since it currently
breaks valid urls.

Kind regards,
Dimitris

Reply via email to