Background
CVE-2026-48907 is a critical unauthenticated remote code execution vulnerability in the Joomla Content Editor (JCE) plugin, developed by The Widget Factory and Ryan Demmer. JCE is one of the most widely installed Joomla extensions, with installations across a significant proportion of the approximately 2 million active Joomla sites globally.
The vulnerability exists in the plugin’s profile import endpoint. A combination of missing authentication checks, absent file extension validation, and explicitly disabled upload safety controls allows any unauthenticated attacker to upload a PHP webshell and execute it within seconds. The exploit requires only a valid CSRF token, which is trivially obtainable from any public-facing Joomla page.
CISA added CVE-2026-48907 to the Known Exploited Vulnerabilities (KEV) catalog on June 16, 2026, with a remediation deadline of June 19, 2026. The vulnerability is actively exploited by automated botnets performing opportunistic scanning. A public proof-of-concept and Docker-based exploitation environment are available on GitHub.
CVSS 4.0 score: 10.0 (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:A/AU:Y).
Technical Mechanism
The vulnerability is a three-part exploit chain, each weakness individually necessary for full exploitation.
Weakness 1: Missing Authorization on the Profile Import Endpoint
The endpoint index.php?option=com_jce&task=profiles.import performed CSRF token validation only — it did not check whether the requesting user was authenticated or held the core.manage privilege. CSRF tokens in Joomla are embedded in public-facing page HTML and JavaScript metadata. Any unauthenticated client that makes a GET request to the Joomla homepage can harvest a valid CSRF token and replay it in a subsequent POST to the import endpoint. The CSRF check was purely an origin control, not an access control.
Weakness 2: No File Extension Validation
The upload handler called File::makeSafe() to sanitize the uploaded filename. This function sanitizes special characters but does not inspect or restrict file extensions. A file named nuclei-deadbeef.xml.php passes makeSafe() unchanged. The double-extension filename causes the web server to interpret the file as PHP when requested.
Weakness 3: Upload Safety Controls Explicitly Disabled
The upload call used the following invocation:
File::upload($source, $destination, false, true)
The fourth argument ($allow_unsafe) was set to true. This parameter explicitly disables Joomla’s built-in extension blacklist, which would normally reject .php and other executable extension types. The platform’s own defense-in-depth was disabled at the code level.
Combined Attack Surface
The intersection of these three weaknesses produces a complete pre-authentication PHP upload and execution primitive with no technical barriers.
Real-World Exploitation Evidence
Exploit Chain (step by step):
- Token extraction: Attacker sends
GET /and extracts the CSRF token from the HTML response. - Webshell upload: Attacker sends
POST /index.php?option=com_jce&task=profiles.importas amultipart/form-datarequest with a PHP webshell embedded in a file namednuclei-<hash>.xml.php. The file lands in the Joomla/tmp/directory by default. - RCE trigger: Attacker sends
GET /tmp/nuclei-<hash>.xml.php. Because Joomla’s default configuration permits PHP execution from/tmp/, the shell executes immediately.
Full webshell variants also upload to /images/, /media/, or /images/jce/ depending on installation configuration.
The minimal confirmation payload is <?= 45*69 ?>, which returns 3105 on a vulnerable target. The public PoC (github.com/ywh-jfellus/CVE-2026-48907) includes a Docker Compose environment for side-by-side testing of vulnerable (2.9.99.4) and patched (2.9.99.5) versions.
Threat Actor Context:
No specific named threat actor or ransomware group has been attributed to exploitation at this time. Observed exploitation is opportunistic and automated: botnet scanning began within days of public PoC publication. Observed post-exploitation activity includes defacement and cryptocurrency mining implant deployment. The attack is rated automatable (AU:Y) in the CVSS 4.0 vector; at scale, mass exploitation of unpatched Joomla installations is straightforward. The CISA KEV listing with a three-day remediation deadline reflects both the severity and the breadth of active scanning.
Impact Assessment
Successful exploitation gives the attacker arbitrary PHP code execution on the web server with the permissions of the web application process. From that position, an attacker can exfiltrate website databases, deface or replace content, install persistent webshells for ongoing access, and pivot to other services on the hosting server.
Joomla powers approximately 2 million websites globally, and JCE is among the most widely installed extensions. The unauthenticated access requirement means no social engineering or credential compromise is needed — any internet-connected scanner can identify and exploit vulnerable instances automatically. The public PoC, Docker-based exploitation environment, and CISA-mandated three-day remediation deadline reflect both the severity and the pace of mass opportunistic exploitation campaigns already underway at time of publication.
Affected Versions
| Product | Affected Versions | Fixed Version |
|---|---|---|
| Joomla Content Editor (JCE) | 1.0.0 through 2.9.99.4 | 2.9.99.5 (initial fix); 2.9.99.6 (hardened, preferred) |
| JCE for Joomla 3.x | All versions | No patch available — platform incompatibility |
JCE 2.9.99.5 introduces the initial patch (released June 3, 2026, two days before CVE assignment). JCE 2.9.99.6 adds further hardening and codebase-wide security review (released June 8, 2026). The vendor has also released free patch packages for older 2.7.x, 2.8.x, and 2.9.x branches to address sites running non-current major versions.
Joomla 3.x installations cannot receive the current patch due to platform incompatibility and remain exposed. Legacy Joomla 3.x sites running JCE should be treated as compromised-pending-discovery.
Remediation Steps
Immediate action: Update JCE to version 2.9.99.6 or later via the Joomla Extension Manager. Version 2.9.99.5 resolves the core vulnerability; 2.9.99.6 adds additional hardening and is preferred.
For sites unable to update immediately: The vendor has released free patch packages for older 2.7.x, 2.8.x, and 2.9.x branches. Apply the appropriate legacy patch if a version upgrade is not immediately feasible.
For Joomla 3.x sites: No patch is available. Consider these installations unmitigatable and escalate to full assessment and migration planning.
Patches applied in 2.9.99.5+:
- Added
$user->authorise('core.manage', 'com_jce')authentication check on the import endpoint — unauthenticated requests are now rejected before any file handling occurs. - Extension allowlist: only
.xmlextensions are accepted, validated viapathinfo($filename, PATHINFO_EXTENSION). - Removed the
$allow_unsafe=trueparameter — Joomla’s built-in extension blacklist is now active for all uploads. - Upload size cap: 512 KB maximum.
- XXE protection: external entity loading disabled in the XML parser handling profile imports.
- XML field allowlist: only known-safe fields are processed from imported profile documents.
Network-level workaround (temporary, not a substitute for patching):
Block or rate-limit POST requests to paths matching index.php where the query string contains option=com_jce and task=profiles.import at the WAF or reverse proxy layer. This does not remediate the underlying vulnerability but reduces automated exploitation exposure while patching is underway.
Detection Guidance
Web server access logs:
Look for POST requests to /index.php where the query string contains com_jce and task=profiles.import. Any such POST from a session not authenticated as a Joomla admin is suspicious. Volume and IP diversity will indicate automated scanning.
grep "com_jce.*task=profiles.import" /var/log/apache2/access.log | grep "POST"
Filesystem indicators:
Scan for PHP files in locations where no PHP should exist:
/tmp/*.phpor/tmp/*.xml.php— primary drop location/images/jce/*.php/media/*.php- Any file matching
nuclei-*.xml.phpunder the Joomla webroot
find /var/www/html -name "*.php" -newer /var/www/html/configuration.php -not -path "*/libraries/*" -not -path "*/administrator/*"
JCE admin panel:
Rogue profiles created by the exploit appear at the top of the JCE profile list with auto-generated names. A secondary side-effect of exploitation is the removal of toolbar buttons from editor configurations. Sudden disappearance of editor toolbars from the Joomla backend is an indirect indicator.
IOCs:
- Filename pattern:
nuclei-[a-f0-9]+\.xml\.php - POST request URI:
/?option=com_jce&task=profiles.importor/index.php?option=com_jce&task=profiles.import - User-agent pattern: commonly automated (scripted) clients with minimal or absent user-agent strings in exploitation tooling
YARA-compatible file detection:
rule CVE_2026_48907_JCE_Webshell {
strings:
$php_tag = "<?php"
$system = "system(" nocase
$eval = "eval(" nocase
$passthru = "passthru(" nocase
condition:
$php_tag and (1 of ($system, $eval, $passthru))
and filename matches /nuclei-[a-f0-9]+\.xml\.php/
}
Timeline
| Date | Event |
|---|---|
| 2026-06-03 | JCE 2.9.99.5 patch released |
| 2026-06-05 | CVE-2026-48907 assigned by Joomla! Project CNA |
| 2026-06-08 | JCE 2.9.99.6 hardening release |
| 2026-06-09 | Public PoC documented (GitHub, Sploitus) |
| 2026-06-12 | Active exploitation confirmed by vendor and external researchers |
| 2026-06-16 | Added to CISA KEV catalog |