Joomla Page Builder RCE: CVE-2026-48908 and the Web Shell You Already Have
Two CVSS 10.0 file-upload bugs in Joomla page builders (CVE-2026-48908, CVE-2026-56290) are mass-exploited to drop web shells and hidden admins — patching won't evict them.
On 7 July 2026, CISA added two Joomla extension flaws to its Known Exploited Vulnerabilities catalog on the same day, both rated CVSS 10.0, both unauthenticated, both already used in the wild. CVE-2026-48908 is in SP Page Builder; CVE-2026-56290 is in PageBuilder CK. They are different extensions written by different vendors, but they share one bug class — an upload handler with no authentication and no server-side file-type check — and one outcome: a remote attacker writes a PHP file into the web root and runs it. The federal remediation deadline was 10 July. If you run Joomla with either extension and you are reading this after that date, the operative question is no longer "should I patch" — it is "am I already hosting a web shell."
Two Joomla page builders, one file-upload bug
Page builders are drag-and-drop layout components. To let an editor drop a custom icon onto a page, SP Page Builder exposed a controller task, asset.uploadCustomIcon, reachable at:
index.php?option=com_sppagebuilder&task=asset.uploadCustomIcon
The task was meant for a small administrative job. Per the mySites.guru disclosure, it "processed the uploaded file with no authentication check and no server-side restriction on the file type, then wrote it to a folder under the web root" — /media/com_sppagebuilder/assets/iconfont/. It never called Joomla's built-in upload helpers that would have rejected a .php extension. So an anonymous HTTP request uploads x.php, the server stores it under a web-accessible path, and the attacker requests it. Unauthenticated file upload becomes unauthenticated remote code execution. CVE-2026-48908 affects SP Page Builder 1.0.0 through 6.6.1; the fix landed in 6.6.2 on 14 June 2026.
PageBuilder CK is a different codebase with the identical shape of flaw — CWE-284, improper access control on an upload path, CVSS 10.0. Its maintainer, Phil Taylor, disclosed it after his own tooling caught a live web shell:
"Within hours of the fix landing, our suspect content tool flagged a live web shell on a connected Joomla site, planted through this exact flaw."
That is the tell. These are not theoretical CVEs waiting for a proof-of-concept. Exploitation began before most site owners had heard the extension name.
What "Joomla page builder RCE" actually buys the attacker
Code execution on a web server is the beginning of the intrusion, not the end. The observed campaigns do not stop at a shell — they establish persistence that survives the very patch you are about to apply. Two artifacts recur:
- A file-manager backdoor. On SP Page Builder victims, Censys and mySites report copies of a PHP file manager named
users.phpdropped under/media/com_admin/,/media/regularlabs/, andimages/<random>/fonts/. On PageBuilder CK victims the observed shell is/media/com_pagebuilderck/gfonts/bhup.php, a self-contained uploader identifiable by the stringif( $_POST['_upl'] == "Upload" ). - A hidden Super Administrator. The SP Page Builder campaign creates a rogue Joomla Super User whose email always ends in
@secure.local— a hard-coded value that never varies — with a username built from a role word (webeditor,contentmgr,sysadmin,webmaster) plus two random digits.
That second artifact is the one defenders underestimate. The web shell is the loud implant; a security scanner or a re-image will often catch it. The rogue admin account is quiet and legitimate-looking. It lives in the #__users table, authenticates through the normal login form, and grants full control of the CMS — content, extensions, user management — through a supported feature. Delete the shell, update the extension, and the attacker logs back in through the front door with credentials they minted while you were exposed.
This is the pattern behind the headline of this post. The exposure window closes when you patch. The incident does not.
The exposure is not theoretical
Censys observed 194,793 web properties loading the SP Page Builder component at disclosure — Apache (48%), nginx (23%), LiteSpeed (8%), with 31% advertising PHP through X-Powered-By headers. Joomla is the third-most-deployed CMS on the public web, and these two page builders are among its most popular commercial extensions. The internet-facing surface is large, homogeneous, and trivially fingerprinted: the vulnerable component name appears in page source. For a mass-scanning adversary, that is a target list, not a research project. A public proof-of-concept exists on GitHub for the SP Page Builder flaw, which collapses the gap between disclosure and commodity exploitation to hours.
The structural lesson repeats across the CMS ecosystem: the core project is comparatively well audited, but third-party extensions — page builders, form builders, gallery plugins — carry the same execution privileges with a fraction of the review. An unauthenticated upload endpoint in one popular extension is a better bulk-RCE primitive than most memory-corruption bugs, because it needs no exploit development at all. It needs a curl command.
Remediation
The heading is stable at #remediation on purpose — this is the runbook, in order. Verified against the vendor advisories for CVE-2026-48908 and CVE-2026-56290.
1. Am I affected?
Fingerprint the extension and its version. From the server:
# Is SP Page Builder present, and at what version?
find /var/www/html -name "sppagebuilder.xml" -exec grep -i '<version>' {} \;
# PageBuilder CK
find /var/www/html -name "pagebuilderck.xml" -exec grep -i '<version>' {} \;
From outside, the component name leaks in page source (com_sppagebuilder, com_pagebuilderck). Any site advertising either is a candidate. Treat the upload endpoint as reachable unless you have proven otherwise.
2. Patch — exact fixed versions
| Extension | Affected | Fixed | Released |
|---|---|---|---|
| SP Page Builder | 1.0.0 – 6.6.1 | 6.6.2 | 14 Jun 2026 |
| PageBuilder CK (current) | ≤ 3.5.10 | 3.6.0 | 27 Jun 2026 |
| PageBuilder CK (Joomla 4) | < 3.4.10 | 3.4.10 | 27 Jun 2026 |
| PageBuilder CK (Joomla 3) | < 3.1.1 | 3.1.1 | 27 Jun 2026 |
Unpublishing or disabling the component is not sufficient — the vulnerable controller can still be reachable. Update the code.
3. Can't patch this hour? Compensating controls
Buy time at the web tier while you stage the update. Virtual-patch the upload path and forbid PHP execution in upload directories:
# Block unauthenticated hits on the vulnerable components (ModSecurity)
SecRule ARGS:option "@rx (com_sppagebuilder|com_pagebuilderck)" \
"id:100048908,phase:1,chain,deny,status:403,log,\
msg:'Blocked Joomla page-builder upload — CVE-2026-48908/56290'"
SecRule REQUEST_METHOD "@streq POST" \
"chain"
SecRule REQUEST_COOKIES "!@rx [0-9a-f]{32}=" "t:none"
# Never execute PHP written into upload dirs
<DirectoryMatch "/var/www/html/(images|media|tmp)/">
<FilesMatch "\.ph(p[0-9]?|t|tml)quot;>
Require all denied
</FilesMatch>
</DirectoryMatch>
The second rule is the higher-value one: even a successful upload is inert if the directory cannot run PHP.
4. Hunt for compromise (assume breach)
This maps to MITRE ATT&CK T1190 (Exploit Public-Facing Application) → T1505.003 (Web Shell) → T1136 (Create Account). Run every check — the shell without the account, or the account without the shell, is still a full compromise.
cd /var/www/html
# T1505.003 — PHP files where none should ever exist
find images/ media/ tmp/ -type f -name "*.ph*" 2>/dev/null
# Known IOC filenames from these campaigns
find . -type f \( -name "users.php" -o -name "bhup.php" \) \
\( -path "*/media/com_admin/*" -o -path "*/media/regularlabs/*" \
-o -path "*/media/com_pagebuilderck/*" -o -path "*/fonts/*" \) 2>/dev/null
# Web-shell code signatures
grep -rlE '\$_(POST|REQUEST)\[.?_upl.?\]|eval\s*\(\s*(base64_decode|gzinflate)' \
. --include="*.php" 2>/dev/null
# Anything PHP written in the exposure window
find . -name "*.php" -mtime -30 -not -path "*/cache/*" -not -path "*/tmp/*"
# T1136 — the rogue Super Administrator (adjust #__ table prefix)
mysql -u root -p joomla_db -e "
SELECT u.id,u.username,u.email,u.registerDate
FROM jos_users u JOIN jos_user_usergroup_map m ON u.id=m.user_id
WHERE m.group_id=8
AND (u.email LIKE '%@secure.local' OR u.registerDate > '2026-06-01')
ORDER BY u.registerDate DESC;"
The @secure.local email and the _upl POST parameter are the two hard IOCs specific to these campaigns. The date-modified and code-signature sweeps catch variants that changed filenames.
5. Eradicate and verify — after patching
- Remove every web shell and file-manager backdoor found in step 4.
- Delete the rogue Super Administrator, then rotate every remaining admin credential and Joomla secret (
configuration.php$secret), and force-logout all sessions (TRUNCATE jos_session). - Re-scan the
#__userstable and the upload directories after the patch is live — a clean result before patching means nothing if the attacker re-entered through their account. - Confirm the endpoint now rejects anonymous uploads (
curla benign multipart POST toasset.uploadCustomIconand expect 403/401).
A closed CVE is not a closed incident until you can prove the implant and the account are both gone.
Where Zero Hunt fits
The gap this article describes — patched extension, live implant, quiet admin account — is precisely the gap a version scanner cannot see. A scanner reports "SP Page Builder 6.6.2, not vulnerable" and moves on; it has no concept of the users.php dropped last Tuesday or the [email protected] account authenticating through the login form. That is why Zero Hunt runs an assumed-breach validation, not a version check.
The 10-agent AI swarm treats an exposed Joomla site the way the adversary does. The Recon agent maps the internet-facing components and fingerprints the extension. The Exploit agent reconstructs the file-upload chain per target with a locally generated payload — not a canned ExploitDB script — so the test reflects this deployment. Then the Post-Exploit, Credential, and Pivot agents do the work the scanner skips: hunt the planted web shell, enumerate the user table for the rogue Super Admin, and prove whether the closed CVE left a live foothold. Every finding is ECDSA-signed at write time, so "we patched and confirmed clean" is a verifiable artifact for an auditor or an insurer, not an assertion. Change-triggered campaigns re-run the moment a new Joomla asset appears on the perimeter — the exact window in which these two CVEs are being weaponized.
There is a network-side witness too. During the exposure window, the mass-scanning for com_sppagebuilder and the web shell's outbound beacon are traffic the endpoint never logs — the appliance host runs no agent inside the CMS. Zero Hunt's AI Traffic Analysis model, four inference heads at 2.7+ Gbit/s on the appliance GPU, flags the anomalous upload POSTs and the callback pattern while the activity is live, not in the next morning's log review. Patch the extension — then prove nothing walked in while it was open.