An attacker who has never logged in to your Joomla site can leave a working backdoor on it, and the feature they use to do it is one your content team relies on every day. That is CVE-2026-48907, a flaw in the Joomla Content Editor (JCE) - one of the most widely installed extensions in the Joomla ecosystem - that the Widget Factory rated at CVSS 10.0, the top of the scale. CISA added it to the Known Exploited Vulnerabilities catalog on June 16, 2026, with a federal remediation deadline the same week. That listing is the part that matters: it means the agency has confirmed real attacks, not just internet-wide scanning. As The Hacker News reported, working exploit code is public and the attacks are automated.
Here is the relevance verdict, because most of the web does not run Joomla and this one is easy to scope. If your public website runs Joomla and has JCE installed at version 2.9.99.4 or earlier, you are in the blast radius and should treat this as a same-day job. If you run WordPress, Drupal, a static site, or a hosted site builder, this specific CVE is not yours - close the tab. If you are not sure what your marketing agency built your site on, the thirty seconds it takes to check is the most useful thing you will do this week. JCE ships on a large share of Joomla installs because it is the editor most site builders reach for, so "we run Joomla" very often means "we run JCE."
How the editor became an upload server
The attack chains three weaknesses in JCE's profile-import feature, and the published analysis from the researchers who reported it lays the chain out cleanly.
First, the import endpoint - reachable at index.php?option=com_jce&task=profiles.import - never checked whether the request came from an authenticated administrator. The only thing standing in front of it was a CSRF token, and that token can be read off any public page on the same site. An anonymous visitor grabs a valid token from the homepage and replays it against the import handler.
Second, the upload routine sanitized the filename with File::makeSafe(), which strips dangerous characters but does not inspect or restrict the extension. A file named report.xml.php passes through untouched, still carrying its executable .php tail.
Third, the call that actually wrote the file passed allow_unsafe = true, which switches off Joomla's built-in blacklist of executable extensions - the safety check that would otherwise reject a .php upload outright.
Put together, an unauthenticated request imports a rogue editor profile that the attacker has configured to accept arbitrary file types. The profile tells JCE to trust those uploads, the disabled blacklist lets the .php file land in a web-served directory, and a second request executes it. The result is remote code execution, and in the attacks observed so far, a web shell that gives the intruder a persistent foothold on the server. None of the three steps needs a password, a stolen session, or a phishing email. That is why the exploitation is automated: low complexity, no privileges, and a payload that works against any unpatched JCE install on the public internet.
Code execution on the web server is rarely the end goal; it is the start of one. With a shell on the box, the standard playbook is to harvest the database (customer records, form submissions, hashed admin passwords), inject SEO spam or a payment-skimming script into pages real customers see, add the server to a botnet, or pivot toward anything else the host can reach on the internal network. For a small business, the visible damage often arrives later as a Google "this site may be hacked" warning, a blocklisted domain, or a card processor flagging skimmed transactions - days or weeks after the initial drop, when the logs that would explain it have already rotated away.
Who is exposed, and how to confirm in two minutes
The vulnerable range is JCE 1.0.0 through 2.9.99.4. The Widget Factory shipped the fix in 2.9.99.5 on June 3, 2026, and followed it with additional hardening in 2.9.99.6 on June 6. If you cannot move to the current release immediately, the vendor also published free patch packages for the 2.7.x, 2.8.x, and 2.9.x branches that close the hole without the extra hardening.
You do not have to guess which version you are running. The Joomla administrator panel lists it under Extensions, Manage, and you can confirm from a shell by reading the extension manifest:
# Read the installed JCE version straight from its manifest
grep -oE '<version>[^<]+</version>' \
/var/www/administrator/components/com_jce/jce.xml
Anything at or below 2.9.99.4 is exploitable. If a managed-hosting provider or an outside agency runs the site for you, this is the line to send them today: "Confirm our JCE version, and that it is 2.9.99.6 or later." A surprising number of small-business sites are built once by a contractor and never touched again, which is exactly the population automated exploitation finds first.
Patch first, then assume someone got there before you
Patching closes the door. It does nothing about anyone who walked through it while it was open, and with public exploit code and weeks of automated scanning behind us, a Joomla site that has been internet-facing recently should be treated as possibly already touched. The JCE team made the same point in their advisory, relayed by BleepingComputer: updating stops new intrusions, but a site that was hit needs hands-on cleanup, including credential rotation and a malware scan.
Run three checks, in this order.
The compromise checklist
- Read your web access logs for the import task. Any unauthenticated hit to
profiles.importis the signature of an exploitation attempt. - Audit your JCE editor profiles. The attack works by creating a new profile; a profile your team did not make is a strong indicator.
- Look for PHP files that appeared in upload directories. The web server should almost never write a
.phpfile intoimages/,media/, or a temp path.
Here is a starting set of commands for a typical Linux Joomla host:
# 1. Unauthenticated requests to the vulnerable import handler
grep -aiE 'option=com_jce&(amp;)?task=profiles\.import' \
/var/log/apache2/*access* /var/log/nginx/*access* 2>/dev/null
# 2. Editor profiles in the JCE table, newest first - cross-check against
# the profiles your team actually created
mysql -e "SELECT id, name, created FROM joomla.\`#__wf_profiles\` ORDER BY id DESC;"
# 3. PHP files written into web-writable dirs in the last 14 days
find /var/www -type f -name '*.php' -mtime -14 \
\( -path '*/images/*' -o -path '*/media/*' -o -path '*/tmp/*' \) -ls
A hit on the first command does not by itself prove compromise - scanners spray that request at sites that are not even running JCE - but a log hit combined with an unexplained editor profile or a new PHP file in an upload folder means you are cleaning up, not just patching. If you find that, rotate every credential the site can reach (database, administrator accounts, API keys, SMTP) and restore from a known-good backup rather than trying to surgically delete the shell. Webshell operators routinely drop a second, quieter backdoor so that removing the obvious one leaves them in place.
Keep the next editor bug from becoming a breach
The specific flaw is fixed in 2.9.99.6, but the underlying problem - a public website that can be made to execute uploaded code - is one the same site will meet again with the next plugin. Three controls blunt that whole class of bug, and none of them depend on you knowing the next CVE in advance.
Three controls that survive the next CVE
- Stop PHP execution in upload directories. A web-server rule that refuses to run
.phpunderimages/,media/, andtmp/turns most webshell drops into inert files. - Put a web application firewall in front of the site. Even a basic managed WAF would have blocked the unauthenticated
profiles.importrequest, and virtual-patch rules for this CVE are already published. - Keep extensions on a real update schedule. Joomla's update channel announced 2.9.99.5 the day it shipped; the sites that get breached are the ones where nobody is reading that channel.
The PHP-execution rule is a few lines and pays for itself across every future upload bug. On nginx:
# nginx: refuse to execute PHP under Joomla's upload paths
location ~* ^/(images|media|tmp)/.*\.php$ {
deny all;
return 403;
}
Update the editor, then read your own access logs
If you run Joomla, the order is fixed: get JCE to 2.9.99.6 today, then read your access logs for profiles.import before you call it done. The patch is free and takes minutes; the log review is the part that tells you whether this was a near miss or an incident you need to work. A public website is the one asset an attacker can reach with no credentials at all, and a CMS plugin is the piece of it most owners never think about until it becomes the way in. If you want a second set of eyes on what is actually exposed on your public-facing site, that is the kind of review we run.
Is your public website the easiest way into your business?
We assess external-facing websites and the CMS plugins behind them for the flaws attackers exploit without ever logging in. Book a session and we will map what is reachable from the open internet and what to fix first.
