Skip to main content
CVE-2026-48907 Critical Patch Available

CVE-2026-48907: Joomla Content Editor — Unauthenticated RCE via File Upload

CVE Details

CVE ID CVE-2026-48907
CVSS Score 10
Severity Critical
Vendor Widget Factory
Product Joomla Content Editor (JCE)
Patch Status Available
Published June 17, 2026
EPSS Score 0.8%
CISA Patch Deadline July 8, 2026

Executive Summary

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).

Affected Versions

All JCE versions from 1.0.0 through 2.9.99.4 are vulnerable. This encompasses the entire history of the plugin.

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.

Vulnerability Details

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.

Exploitation in the Wild

Exploit Chain (step by step):

  1. Token extraction: Attacker sends GET / and extracts the CSRF token from the HTML response.
  2. Webshell upload: Attacker sends POST /index.php?option=com_jce&task=profiles.import as a multipart/form-data request with a PHP webshell embedded in a file named nuclei-<hash>.xml.php. The file lands in the Joomla /tmp/ directory by default.
  3. 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.

Timeline:

DateEvent
June 3, 2026JCE 2.9.99.5 patch released
June 5, 2026CVE-2026-48907 assigned by Joomla! Project CNA
June 8, 2026JCE 2.9.99.6 hardening release
June 9, 2026Public PoC documented (GitHub, Sploitus)
June 12–16, 2026Active exploitation confirmed by vendor and external researchers
June 16, 2026Added to CISA KEV catalog

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.

Patch and Remediation

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+:

  1. Added $user->authorise('core.manage', 'com_jce') authentication check on the import endpoint — unauthenticated requests are now rejected before any file handling occurs.
  2. Extension allowlist: only .xml extensions are accepted, validated via pathinfo($filename, PATHINFO_EXTENSION).
  3. Removed the $allow_unsafe=true parameter — Joomla’s built-in extension blacklist is now active for all uploads.
  4. Upload size cap: 512 KB maximum.
  5. XXE protection: external entity loading disabled in the XML parser handling profile imports.
  6. 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

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/*.php or /tmp/*.xml.php — primary drop location
  • /images/jce/*.php
  • /media/*.php
  • Any file matching nuclei-*.xml.php under 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.import or /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/
}

References: