Treat a CSRF token as a login and you have built a front door anyone can walk through. That is the mistake behind CVE-2026-48907, a remote-code-execution hole in JCE, the editor add-on that runs on a large share of Joomla sites. CISA marked it actively exploited on June 16, 2026 and set a June 19 deadline. If your servers host Joomla, the clock is already running.
The rating is as bad as it goes: CVSS 10.0. No login, no clicking, no social engineering. An outsider turns a normal Joomla install into a server they control. JCE, the Joomla Content Editor from Widget Factory, is among the most widely installed extensions Joomla has, which is what turns one bug into a fleet problem. The full teardown is on YesWeHack.
How a token check became a webshell
The damage lives in JCE's profile-import handler, the profiles.import task inside the com_jce component. Three small gaps stack into one unauthenticated upload.
- Identity was never checked. The endpoint wanted a valid CSRF token and nothing else. A token only says a request came from a page on the site; it says nothing about who sent it, and it is printed in the homepage HTML for anyone to copy. Proof of origin got mistaken for proof of identity.
- The filter read the wrong half of the filename. JCE stripped unsafe characters but never pinned the allowed type, so a name ending
.xml.phpslipped by. Apache hands that file tomod_php, which cares only that the final piece is.php, and runs it. - The last catch was switched off. The write happened with Joomla's built-in dangerous-extension blocklist disabled, so the PHP file reached disk instead of being refused.
Stacked together, the break-in is three plain web requests: read the homepage to lift the token, post a booby-trapped profile that drops a .php file into the site's /tmp folder, then open that file in a browser so the server runs it. Nothing about it needs an account.
The safe build is 2.9.99.6 (mind the version trap)
Here the two best writeups split, and the gap matters in practice. YesWeHack places the fix at 2.9.99.5, with extra hardening arriving in 2.9.99.6. mySites.guru disagrees, calling 2.9.99.5 incomplete and naming 2.9.99.6 as the first build it trusts. When advisories disagree on the fixed release, round up and do not stop at .5. Anything 2.9.99.4 or older is exposed. Sites stuck on the 2.7 to 2.9 line that cannot jump have a vendor backport that closes the hole, but treat that as breathing room, not a destination.
Assume breach, then go look
With exploitation already in the wild and the effort near zero, checking beats hoping. Three places to look, strongest signal first.
- Editor profiles you did not create. Under
Components > JCE Editor > Editor Profiles, an entry auto-namedJplus six digits, often with a gloating label, is the calling card. Straight from the database:SELECT id, name FROM _wf_profiles WHERE name REGEXP '^J[0-9]{6}$'. What makes one hostile is permission to upload PHP or PHTML. - Files that should not be there. Comb the writable directories,
/images,/media/system/js,/libraries/joomla, and/tmp, for.xml.phpdroppers, base64-packedevalpayloads, andshell_execcommand shells. - The log fingerprint. A POST to
profiles.importtrailed within the same second by aplugin.rpcupload POST, both answered 200, is the chain running end to end.
If you find something, sequence the cleanup carefully, because the obvious order is backwards. Pull the rogue profile and the shell first, then upgrade. Patch a still-infected site and you only lock the backdoor inside; clean a still-vulnerable one and it gets reowned by the next scan. Once both are done, rotate Joomla secrets and admin credentials and kill live sessions, because whoever ran code saw whatever the web user could.
The real lesson: extensions, not core
JCE has starred in this movie before. Years ago its upload handling drove one of the biggest waves of Joomla compromises on record, and the 2026 bug repeats the plot: the editor add-on, not Joomla itself, is the way in. At hosting scale the takeaway stings. Your real attack surface is not the platform you can audit centrally, it is the sprawl of third-party extensions every tenant bolts on. The same shape played out on cPanel in the LiteSpeed plugin escalation and on WordPress in the Awesome Motive backdoor.
One host-level rule would have blunted all of it: refuse to run PHP out of writable upload paths. A server that will not execute code from /tmp or /images turns this RCE into an inert file on disk. Add file-integrity watching on those directories, the approach behind why we build on host telemetry, and the same guardrail catches whatever extension breaks next. The CVE number is disposable. The habit that beats it is not.