Pending

User tests: Successful: Unsuccessful:

avatar tadosborn
tadosborn
25 May 2026

Summary of Changes

One-character fix for the bug reported in #47828. Pass xhtml=false to Route::_('index.php') inside Session::checkToken() so the URL written to the HTTP Location: response header contains raw & rather than HTML-encoded &.

Testing Instructions

  1. From a clean session (no cookie jar), hit any front-end URL whose controller calls Session::checkToken('get') without a valid token. A widely-deployed reproducer is JCE Editor's editor.loadlanguages endpoint:
    curl -ski "https://example.test/component/jce/?task=editor.loadlanguages&lang=en&context=1&profile_id=2"
  2. Before this patch, the response is:
    HTTP/1.1 303 See other
    Location: https://example.test/component/jce/?task=editor.loadlanguages&lang=en&context=1&profile_id=2
    
    — note literal & in Location. Each subsequent follow doubles the entity prefix.
  3. After this patch, the response is:
    HTTP/1.1 303 See other
    Location: https://example.test/component/jce/?task=editor.loadlanguages&lang=en&context=1&profile_id=2
    
    — raw &, no chain.

Verified against Joomla 6.1.0 (infinetinc.com production) — XOVI crawler errors for temporaryRedirects and serverErrors on the affected URLs dropped to zero on the next scan after this patch was applied (was 463 errors over 30 days pre-patch).

Documentation Changes

None required — Route::_()'s $xhtml parameter is already documented as "Replace & by & for XML compliance," which makes clear it shouldn't be used for HTTP Location headers.

Background

libraries/src/Session/Session.php::checkToken() redirects when:

  • the expected token is missing from the request, AND
  • the session is new (default state for a crawler request with no cookie).

Route::_($url, $xhtml = true, ...) runs htmlspecialchars() on the URL when $xhtml=true. That output is passed straight to $app->redirect(), which writes it to the Location: header without entity-decoding. Per RFC 3986, ampersands in the URI of a Location header must be raw & — entity encoding belongs in HTML attribute contexts, not response headers.

Crawlers (notably XOVI) that don't decode HTML entities before following Location then GET the literal &-laden URL. PHP's parse_str treats &Itemid=101 as separator-& plus param-name-amp;Itemid. The next redirect rebuilds the query string from the polluted $_GET and re-runs htmlspecialchars() on it, so each hop multiplies the amp; prefix until the URL exceeds server limits and the chain terminates in 502s.

Browsers happen to tolerate this (they decode entities before re-issuing requests), which is likely why this has gone unreported in the 14 years since Session::checkToken was introduced.

This patch is against 5.4-dev per Joomla's lowest-maintained-branch convention; the same single-line change applies cleanly to 6.1-dev, 6.2-dev, and 7.0-dev (verified all four Session.php files still contain the bare Route::_('index.php') call as of 2026-05-25). Happy to open follow-up PRs against the other release branches if upmerge doesn't pick it up.

avatar tadosborn tadosborn - open - 25 May 2026
avatar tadosborn tadosborn - change - 25 May 2026
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 25 May 2026
Category Libraries
avatar richard67
richard67 - comment - 25 May 2026

@tadosborn Please confirm the Generative AI policy at the top of your pull request. That is part of the pull request template which you see when creating a new pull request, and you should not have removed that. Thanks in advance.

avatar CSGoat0
CSGoat0 - comment - 26 May 2026

Hi @tadosborn, thank you for your first time contribution.
Could you please use this template?

Pull Request resolves # .
- [ ] I read the [Generative AI policy](https://developer.joomla.org/generative-ai-policy.html) and my contribution is either not created with the help of AI or is compatible with the policy and GNU/GPL 2 or later.
### Summary of Changes

### Testing Instructions

### Actual result BEFORE applying this Pull Request

### Expected result AFTER applying this Pull Request

### Link to documentations
Please select:
- [ ] Documentation link for guide.joomla.org: <link>
- [ ] No documentation changes for guide.joomla.org needed
- [ ] Pull Request link for manual.joomla.org: <link>
- [ ] No documentation changes for manual.joomla.org needed

You can keep the similar sections, but you should add the missing ones.

avatar richard67
richard67 - comment - 27 May 2026

@tadosborn In addition to the above, please reference your issue #47829 in this pull request with the Pull Request resolves #47829 . line at the top.

Add a Comment

Login with GitHub to post a comment