JCH Optimize 9.4.0 Fixes Six High-Rated Security Issues in the Joomla Extension

JCH Optimize is a page speed extension for Joomla: it combines and minifies CSS and JavaScript, rewrites HTML, optimises images and serves a page cache. This morning its developer, Samuel Marshall, released JCH Optimize 9.4.0 and called it “a security and maintenance release”. The changelog rates six of the fixes HIGH, including a cross-site scripting issue, an unauthenticated Page Cache endpoint and administrator tasks that ran without a security token.
Every version before 9.4.0 is affected, in both the Free and Pro editions. No CVE has been published and the release credits no finder. Three days later the vendor shipped a second security release, 9.4.2, which fixes a file read and a server-side request forgery that 9.4.0 and 9.4.1 still have. The vendor withdrew that 9.4.2 build later the same day and published a rebuilt 9.4.2 with the same security fixes. If a Joomla site you manage runs JCH Optimize, update it to 9.4.2 today, even if you updated it this week.
Update, later on 10 October 2026: 9.4.2 withdrawn and rebuilt
Later the same day, the vendor pulled the 9.4.2 release described in the next section. Its release page now returns “403 Access forbidden”. In its place is a second release also numbered 9.4.2, with its own release page, and the Free and Pro update feeds now point at it. The vendor has not said why the first build was withdrawn.
We downloaded the first 9.4.2 Free package the morning it came out, so we compared it with the rebuild. The security fixes are identical: the file combining code that closes the encoded-slash file read and the SSRF did not change by a byte. Everything in the next section still applies, and the advice is the same: update to 9.4.2.
The rebuild differs in five ways:
- The component reports its version as plain
9.4.2. The first build reported9.4.2-dev202610101433-revbbe49222. - A new HIGH-rated fix for tag pages. Since 9.4.0, with Page Cache on, guests saw an error page after a tag page’s content and the page was never cached, because the reworked hit counter did not accept the list of tag IDs a tag page passes. It now counts the hit on the first tag, as Joomla does, and an error while storing a page skips caching instead of being added to the page.
- Save Changes in the Critical JavaScript Configure Helper works again. It had failed with a server error since 9.4.0.
- Recache’s default concurrency drops from 10 to 5, so a recache leaves PHP workers free for visitors, and errors from a recache started in a web request are now logged.
- Joomla 4.4 is gone from the compatibility list. The update feed now lists Joomla 5.0 and later for 9.4.0, 9.4.1 and 9.4.2, where it previously offered all three to Joomla 4.4.
If a site installed the first build, its component shows the -dev version in the extension manager. That site has every security fix, and Joomla’s update manager offers it the rebuild, because it ranks a plain 9.4.2 above a -dev build of the same number. Install it for the tag page fix. mySites.guru treats both builds as fixed.
Joomla 4.4 sites are now in a harder spot. None of them is offered any 9.4.x release now, so the security fixes from both rounds wait on the Joomla 5 upgrade, or on removing JCH Optimize until then. mySites.guru keeps flagging those sites.
Update, 10 October 2026: 9.4.2 fixes a file read and an SSRF in file combining
JCH Optimize 9.4.2 is out, and the vendor calls it “a security and maintenance release”. (This is the first 9.4.2 build, which the vendor later withdrew and rebuilt with the same security fixes; see the update above.) Update to it now, including any site you moved to 9.4.0 or 9.4.1 after our earlier advice: both versions have the issues below.
The fix the vendor rates HIGH is in file combining. An encoded slash (..%2F) in the URL of a CSS or JavaScript file could reach files outside the site root, and the combined file is then served to visitors. We compared the 9.4.1 and 9.4.2 Free packages: 9.4.1 removed ../ segments from the URL before decoding it, so ..%2F passed that step and only became ../ afterwards. 9.4.2 rejects any decoded path that still climbs out of the root.
The MEDIUM-rated fixes stop the combiner fetching files from private network addresses or following redirects to them (a server-side request forgery), escape script URLs in the Critical JavaScript Configure Helper, keep the Download ID out of settings exports, make the request that starts a Recache usable only once, and hold the post-update .htaccess changes and plugin ordering until an administrator signs in. Going by the code, both combining issues work through the URL of a file the page links to, so an attacker first needs a way to put a link into a page JCH Optimize optimises. That makes them harder to reach than the 9.4.0 issues. The fix is the same update either way.
Two practical notes. Sites that connect to Redis through a Unix socket have been silently falling back to filesystem storage since 9.4.0, and 9.4.2 fixes that too. And in the extension manager the first 9.4.2 build’s component reported its version as 9.4.2-dev202610101433-revbbe49222: that was the build the vendor published as stable, the plugins reported plain 9.4.2, and mySites.guru treats it as up to date. The rebuilt 9.4.2 reports plain 9.4.2 throughout.
How fast sites took up 9.4.0
On release day, 1% of the current-line JCH Optimize installs on connected Joomla sites were on 9.4.0. These figures are from the same sites three days later, on the day 9.4.2 shipped:
Most of the movement came in the first day, and it slowed sharply after that. That is the usual shape: the sites someone is actively watching update quickly, and the rest wait for whoever looks after them to notice. Every site in that 56% now needs a single update to 9.4.2, which covers both rounds of fixes.
Update, 7 October 2026: 9.4.1 fixes the Redis and APCu fatal error
JCH Optimize 9.4.1 is out, released the same day as 9.4.0, and it resolves this. If a Pro site uses Redis or APCu storage, update straight to 9.4.1: it includes every security fix from 9.4.0 and restores the cache classes that 9.4.0 dropped. Anyone who updated to 9.4.0 and switched storage to Filesystem as a stopgap can move to 9.4.1 and turn Redis or APCu back on.
What happened: a JCH Optimize Pro user reported this afternoon that 9.4.0 took down sites using Redis as the cache store, with a fatal “Redis\Metadata is not available” error on every page. We confirmed it in the 9.4.0 Pro package. 9.4.0 upgraded its bundled Laminas Redis adapter from 2.2 to 3.1.0, whose Redis class depends on a Redis\Metadata class in a src/Redis/ folder. The 9.4.0 Pro package shipped none of the four files in that folder, Metadata.php included, and its class map did not list them. The vendor’s 9.4.1 changelog says APCu storage was missing classes in the same way. The Free edition has no Redis adapter at all, so it was not affected, and sites on the default Filesystem storage were not affected either.
If a site is still on 9.4.0 and cannot update this minute, the earlier workaround holds: set JCH Optimize’s Storage Adapter (in the Cache Storage settings) to Filesystem, because the setting’s own fallback does not help once a missing class stops PHP before JCH Optimize can catch it. If a site is already down, renaming the plugins/system/jchoptimize and plugins/system/jchpagecache folders over FTP brings the front end back. The clean fix is to update to 9.4.1.
How mySites.guru flags JCH Optimize below 9.4.2
mySites.guru records the exact version of every extension on every connected Joomla site twice a day. We added JCH Optimize 9.4.0 to our Joomla vulnerability database the afternoon it was released, so any connected site running the component or its system plugin below 9.4.0 is flagged on its own site card and in its audit, with the version that resolves it. On 10 October we added a second rule for the 9.4.2 fixes, which flags everything below 9.4.2, so sites on 9.4.0 and 9.4.1 are flagged again until they update. Both 9.4.2 builds count as fixed, since their security code is the same.
The rule matches the component and the system plugin separately. JCH Optimize installs several plugins that share the element name jchoptimize (a console plugin and, from 9.4.0, a scheduler task plugin), and those are versioned alongside the main extension, but the rule is pinned to the component and the system plugin so that a stray row cannot flag a site that has already updated.
What the mySites.guru database shows
JCH Optimize is one of the more common third-party extensions we see. These figures are from the Joomla sites connected to mySites.guru that reported in during the last 30 days, taken the afternoon 9.4.0 was released:
The second figure is normal for the first day of any release. The third will not change by itself, because the old line has no patch to wait for.
The cross-site scripting issue in the JCH Optimize optimiser
The first HIGH item in the changelog is “a cross-site scripting vulnerability where encoded characters in URLs, such as search query links, were decoded during optimization”. JCH Optimize rewrites the HTML of every page it serves. Going by the vendor’s description, when Joomla or another extension has already escaped a value inside a link, for example a search term echoed into a “search again” URL, the optimiser’s rewriting step could turn the encoded characters back into live ones.
The rest of the site did nothing wrong here. Joomla escaped the value correctly; the extension sitting between Joomla and the browser undid it. An attacker only has to get a visitor, or an administrator, to open a crafted search link, and the script runs in the context of the site.
This is the one to worry about first on a busy public site, because it needs no account and it reaches any visitor who follows the link.
The Page Cache hit counter ran any component’s model
When JCH Optimize serves a page from its own page cache, Joomla never runs the component that built the page, so article hit counters would stop moving. To fix that, the Page Cache plugin adds a small script to cached pages that calls back to the site and records the hit.
We compared the 9.3.1 and 9.4.0 Free packages to see what the vendor’s description, “allowing a request to run any component’s model”, means in practice. In 9.3.1 the callback is a com_ajax endpoint in plg_system_jchpagecache that answers anonymous requests. It reads a component name (hitoption) and a model name (hitview) from the request, boots that component, builds the named site model and calls its hit() method with an ID from the request. If anything throws, the exception message is sent back in the response.
So any visitor could choose which component and which model to run, and drive hit counters on content the page cache never served, including unpublished items and content behind access levels. We have not shown it reaching anything worse than hit(), and the vendor does not say it does. 9.4.0 replaces the endpoint’s logic with a fixed list of supported pages (articles, categories, contacts, news feeds and tags) and checks that the item is published and visible to the visitor before counting it.
Admin tasks ran without a token or the core.admin permission
The 9.4.0 changelog says administrator tasks that change settings or files now “require a valid form token and administrator permissions”. The diff shows where the check went in. JCH Optimize 9.4.0 adds a guard to its administrator dispatcher: anything other than a read-only dashboard view now needs the core.admin permission on the component and a valid Joomla session token.
In 9.3.1 neither check was there, which allowed:
- Cross-site request forgery: a logged-in administrator who opened a crafted link or page could be made to change JCH Optimize settings or run its file tasks without knowing it.
- Weaker permissions than the job needs: a backend user who could open the component, but who should not be configuring it, could change settings that alter every page the site serves.
The same release stops settings exports from including the Cloudflare API token and the Redis password, and keeps a site’s existing token and password when an import file leaves them out. An old export file sitting in a downloads folder or a support ticket still holds both.
Image paths, the open redirect and the jchbackend switch
The remaining HIGH items are narrower:
- Image optimisation paths: the image optimisation service returns URLs and file paths for the optimised images. 9.4.0 validates those and keeps image folders inside the site root, where earlier versions trusted what came back.
- Open redirect: the Mode Switcher and Utility tasks redirected to whatever URL was passed, base64 encoded, in the
returnparameter. 9.4.0 only follows a return URL on the site itself. The controllers sit on the administrator side, so the link has to be followed by someone logged in there, which is exactly who a phishing redirect wants. - The jchbackend parameter: adding
jchbackend=1to any front-end URL told JCH Optimize to skip optimisation for that request, for any visitor. 9.4.0 removes the parameter.
The MEDIUM items harden the page cache against malformed Host headers and unsafe characters in Capture Cache file paths, and escape file and folder names in the Optimize Images file tree. One small fix shows how these things slip through: in 9.3.1 the check for the jchnooptimize parameter reads get('jchnooptimize' == '1'), comparing the string to '1' before asking for it, so that parameter never worked at all.
Which JCH Optimize versions are fixed?
| Line | Joomla element | Joomla versions | Status |
|---|---|---|---|
| 9.4.2 (rebuild) | com_jchoptimize | 5.0 to 6.1 | Current release, fixes the file read and SSRF in file combining |
| 9.4.2-dev202610101433-revbbe49222 | com_jchoptimize | 4.4 to 6.1 when it shipped | First 9.4.2 build, withdrawn the same day. Same security fixes; update to the rebuild for the tag page fix |
| 9.4.1 | com_jchoptimize | 5.0 to 6.1 in the update feed now | Has the 9.4.0 fixes, but affected by the 9.4.2 issues; update to 9.4.2 |
| 9.4.0 | com_jchoptimize | 5.0 to 6.1 in the update feed now | Affected by the 9.4.2 issues, and a fatal error on Redis or APCu Pro sites; update to 9.4.2 |
| 9.x before 9.4.0, 8.x, 7.x | com_jchoptimize | Varies by release | Affected, update to 9.4.2 |
| 6.5.0 and earlier | com_jch_optimize | Almost entirely Joomla 3 | Affected as far as anyone has said, no fix |
Joomla 4.4 sites: the fix now needs Joomla 5
The 9.4.x release notes always said Joomla 5.0 or later, but until 10 October the vendor’s update feed offered 9.4.x to Joomla 4.4 anyway. It no longer does, for any 9.4.x release, so a Joomla 4.4 site below 9.4.2 will not be offered the fix. Upgrade the site to Joomla 5 first, or disable JCH Optimize until you can. mySites.guru flags those sites below 9.4.2 either way.
What does this mean for Joomla 3 sites?
The old JCH Optimize line, version 6.5.0 and earlier, installs under a different element, com_jch_optimize, and nearly every site still running it is on Joomla 3. The vendor has said nothing about whether that code has the same flaws, and it has no fix. We have not added a rule for it, because we do not flag a version on a guess.
An optimiser that rewrites every page is a high-value place for a bug, and the old line gets no more security fixes. On a Joomla 3 site the practical choices are to uninstall JCH Optimize, or to make the move to a supported Joomla version that has been waiting. Our Joomla 3 extension vulnerabilities list tracks the other extensions in the same position.
What to do today
- Update JCH Optimize to 9.4.2 on each site running Joomla 5.0 or later, after confirming the site runs PHP 8.1 or later, including sites you already moved to 9.4.0 or 9.4.1. 9.4.2 includes every earlier security fix and the Redis and APCu fix.
- Check the component, the
systemplugin and the Page Cache plugin all report 9.4.2. A partly applied update leaves old code in place, and a component on9.4.2-dev202610101433-revbbe49222is the withdrawn first build, which the update manager will move to the rebuild. - On Joomla 4.4 sites, plan the Joomla 5 upgrade, because the vendor no longer offers 9.4.x to Joomla 4.4.
- Delete any JCH Optimize settings export you have saved, and rotate the Cloudflare API token, the Redis password and the Download ID if an export ever left your hands.
- On Joomla 3 sites, uninstall the old JCH Optimize line or plan the migration.
- If you cannot update a site today, turn off the Page Cache plugin, which closes the unauthenticated endpoint.
Beyond the version flag
A flag on a site card says a site is exposed. It does not tell you whether anyone used the hole first, and an XSS aimed at administrators is usually the first step towards an account an attacker should not have.
mySites.guru runs the follow-up checks as part of the subscription, unattended, on every connected site. The rogue admin check lists Super Users added outside the normal flow across your whole account in one view. The Joomla malware scanner looks for code dropped on the server. And the vulnerable extension list explains how version flags like this one work for every Joomla and WordPress extension we track.
If one of your sites already shows signs of compromise, work through our Joomla hacked-site guide or have us fix it for you.
If you manage Joomla sites for clients, mySites.guru flags every connected site the day a fix like this ships, and the free audit shows what it finds on your own sites first.
Timeline
JCH Optimize 9.4.0 ships with six HIGH-rated security fixes
Cross-site scripting through encoded URL characters, an unauthenticated Page Cache hit counter endpoint, admin tasks without a token or core.admin, an open redirect, unvalidated image optimisation paths and the jchbackend switch. The release notes ask for Joomla 5.0, but the update feed offers it to Joomla 4.4. mySites.guru flags every site below 9.4.0 the same afternoon.
9.4.0 takes down Pro sites using Redis or APCu storage
A fatal error on every page, because the bundled Laminas cache library shipped without classes the adapters need. JCH Optimize 9.4.1 restores them later the same day.
JCH Optimize 9.4.2 ships with a second round of security fixes
A HIGH-rated read of CSS and JavaScript files outside the site root through ..%2F when combining files, and a MEDIUM-rated SSRF in the same code. The component reports 9.4.2-dev202610101433-revbbe49222, and the release page lists Joomla 4.4 as compatible. mySites.guru flags everything below 9.4.2, including 9.4.0 and 9.4.1.
The vendor withdraws the first 9.4.2 build
Its release page starts returning 403 Access forbidden. No reason has been published.
A rebuilt 9.4.2 replaces it, for Joomla 5.0 and later only
Same version number, new release page, and the Free and Pro update feeds point at it. The security fixes are identical to the first build. It reports plain 9.4.2, fixes tag pages that showed an error page to guests under Page Cache, and every 9.4.x entry in the update feed now drops Joomla 4.4.
Further Reading
- JCH Optimize 9.4.2 release notes - the rebuilt second security release, with the file read and SSRF fixes. The first 9.4.2 release page has been withdrawn.
- JCH Optimize 9.4.0 release notes - the vendor's full changelog, with each fix rated HIGH, MEDIUM or LOW.
- OWASP Cross Site Scripting Prevention Cheat Sheet - output encoding, the rule an HTML optimiser has to respect when it rewrites a page.
- OWASP Cross-Site Request Forgery Prevention Cheat Sheet - why every state-changing admin request needs a token.
- Joomla 3 extension vulnerabilities - the Joomla 3 extensions with known holes and no vendor fix.


