The front door has no lock and the receptionist hands out master keys to anyone who asks nicely
Page Builder CK is a widely deployed free page-builder extension for Joomla by Cédric Keiflin. The vulnerable endpoint is a front-end file upload handler that accepts POST uploads with no authentication check and no file-extension allowlist — the only gate is a Joomla anti-CSRF token that any anonymous visitor can scrape from the same site's public pages in one request. That means an attacker fetches any page, harvests the token, POSTs a .php payload, and gets a webshell running as the Joomla web user. Affected: Page Builder CK ≤ 3.5.10 on Joomla 4/5. Fixed lines: 3.6.0 (current), 3.4.10 (Joomla 4 back-patch), 3.1.1 (Joomla 3 back-patch), all shipped 27 June 2026.
The vendor CVSS of 9.8 (AV:N/AC:L/PR:N/UI:N/C:H/I:H/A:H) is honest. Some feeds are scoring this a 10.0. Given the CVE is KEV-listed, the exploit is a copy-paste curl one-liner, and the affected component sits on the public internet by definition, there is zero room to argue this down. noisgate concurs at CRITICAL and holds the score.
5 steps from start to impact.
Fingerprint Page Builder CK on target
httpx, nuclei -t joomla-detect, or a Shodan query for http.component:"Joomla") then probes the extension's known asset paths (/media/com_pagebuilderck/, /components/com_pagebuilderck/). A 200 on those assets confirms presence. Version disclosure is available in the extension's JS/CSS asset filenames.- Target Joomla site reachable on port 80/443
- Page Builder CK component installed and enabled
- Sites behind WAFs with hardened rulesets may drop the recon paths
- Some deployments rename or block
/administrator/and Joomla fingerprint paths
nuclei -t http/cves/2026/CVE-2026-56290.yaml templates were published within 72 hours of disclosure per ProjectDiscovery feed.Harvest CSRF token from public page
<input type="hidden" name="[hash]" value="1"> token. No cookie / session context required beyond the initial GET.- Any public URL on the target Joomla site returning a form-bearing page
- None — this is Joomla default behavior; the token is public by design
POST arbitrary file to Page Builder CK upload handler
shell.php with a p0wny/WSO webshell). Handler writes the file inside the site webroot under an attacker-predictable path (typically images/pagebuilderck/ or user-supplied directory). Standard PoC uses curl -F [email protected] -F token=<harvested>.- Web user has write permission to the upload directory (Joomla default)
- PHP execution not disabled in
images/(Joomla default: enabled)
- Sites with an
.htaccessor nginx rule blocking PHP execution under/images/(hardening guide-recommended but rarely applied on stock installs) - ModSecurity CRS may flag PHP-in-multipart uploads
Execute webshell → RCE as web user
www-data/apache/nobody), giving arbitrary command execution: read configuration.php for DB credentials, dump Joomla users table, drop persistence via cron, or pivot to internal network.- Direct HTTP access to the uploaded file path
- Egress filtering may slow C2 establishment
- SELinux/AppArmor confinement of the PHP-FPM pool blunts host reach on hardened distros
php-fpm → shell rules trigger immediately.Post-exploitation: content injection, credential theft, pivot
#__users. Ransomware actors chain this to internal SMB scans if the box is dual-homed.- RCE achieved in step 4
- Shared hosting jails limit lateral movement
- Read-only filesystems (immutable containers) prevent persistence
templates/*.php and #__users table row-additions catches typical follow-on activity.images/ and media/com_pagebuilderck/ — Add an nginx location ~ ^/(images|media/com_pagebuilderck)/.*\.php$ { deny all; } or Apache <FilesMatch> deny rule. Neutralizes the webshell drop even if the file lands. Ship this in the same change window as the patch as belt-and-suspenders..php files under images/, review web-access logs for POSTs to Page Builder CK upload endpoints, audit #__users for unknown Super Users, and rotate credentials in configuration.php.- Adding a captcha to the site login page — the vulnerable endpoint is not the login page; the attacker never touches it.
- Rotating Joomla admin passwords alone — bug is pre-auth, credential rotation does nothing for the initial upload.
- Enabling Joomla two-factor auth — same reason; 2FA gates admin login, not front-end file uploads.
- Trusting the CSRF token — it is scraped from a public page; it is not an authentication factor.
- Disabling the Page Builder CK front-end module only — the vulnerable component route is registered by the component itself, not the module; uninstall the component or patch.
The supporting signals.
| In-the-wild status | KEV-listed by CISA following observed mass-exploitation. CCB Belgium issued a national Patch-Patch-Patch advisory on 30 Jun 2026. |
|---|---|
| Public PoC | Full technical write-up + working exploit published by Phil Taylor / mySites.guru on disclosure day. Mallory, IONIX and SentinelOne vulnerability DBs mirror the PoC. |
| EPSS | 0.00738 (~0.7%). Low percentile is misleading here — EPSS lags KEV-listed items in the first weeks; treat KEV as the ground truth. |
| KEV status | Listed — mitigation SLA collapses to "patch immediately" regardless of the noisgate table. |
| CVSS vector | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — internet-reachable, no auth, no user interaction. Vendor score 9.8; some feeds score 10.0. |
| Affected versions | Page Builder CK ≤ 3.5.10 on Joomla 4/5; also affects the Joomla 3 legacy line. |
| Fixed versions | 3.6.0 (Joomla 5, current), 3.4.10 (Joomla 4 back-patch), 3.1.1 (Joomla 3 back-patch). All released 27 Jun 2026. |
| Exposure data | Shodan http.component:"Joomla" returns ~350k hosts globally. Page Builder CK is one of the most-installed free page builders per JED; realistic exposed-and-vulnerable population is in the tens of thousands. |
| Disclosure date | 2026-06-29 (public advisory). Patch shipped 2026-06-27, i.e., two-day coordinated window. |
| Reporter | Phil Taylor, mySites.guru — coordinated disclosure with vendor Cédric Keiflin (joomlack.fr). |
Sources.
Why this verdict
- Zero-precondition unauth RCE: attacker needs only HTTP reachability — no credentials, no session, no user click. The CSRF token is not a gate; it is a public string.
- KEV-listed: CISA has evidence of in-the-wild exploitation. That alone overrides any friction argument.
- Role multiplier — public-facing CMS: Page Builder CK by definition lives on internet-exposed web tiers. Successful chain yields webshell → DB creds in
configuration.php→ Joomla user-table dump → potential pivot into any internal network the web box can reach. Where the box is dual-homed (marketing site inside a corporate VLAN, common in mid-market), blast radius extends to internal fileshares and directory services. The affected component is canonically an internet-exposed role → CRITICAL floor applies. - Trivially weaponized: exploit is one curl command; already integrated into Nuclei templates and commodity CMS-scanner toolchains within 72 hours.
Why not higher?
CRITICAL is the top severity bucket. Some feeds score 10.0 instead of 9.8; the practical response is identical. There is no operational reason to invent a higher tier.
Why not lower?
No friction factor survives scrutiny. It is unauthenticated, network-reachable, KEV-listed, and trivially exploitable. The only way to downgrade would be to argue the extension has negligible install base, which is contradicted by JED popularity and Shodan Joomla-fleet size.
Crowdsourced verification payload.
Run from an auditor workstation with network access to the target Joomla site. Invoke as ./check-cve-2026-56290.sh https://target.example.com. No credentials required — this only fingerprints the extension and its version from public assets.
#!/usr/bin/env bash
# noisgate check for CVE-2026-56290 — Page Builder CK unauth file upload
# Usage: ./check-cve-2026-56290.sh https://target.example.com
set -u
TARGET="${1:-}"
if [[ -z "$TARGET" ]]; then
echo "Usage: $0 <https://target>" >&2
exit 2
fi
TARGET="${TARGET%/}"
UA="noisgate-cve-check/1.0"
FIXED_CURRENT="3.6.0"
FIXED_J4="3.4.10"
FIXED_J3="3.1.1"
# 1. Detect Page Builder CK asset paths
HTTP_CODE=$(curl -sk -o /dev/null -w "%{http_code}" -A "$UA" \
"$TARGET/media/com_pagebuilderck/css/pagebuilderck.css")
if [[ "$HTTP_CODE" != "200" ]]; then
# Try alternate asset dir
HTTP_CODE=$(curl -sk -o /dev/null -w "%{http_code}" -A "$UA" \
"$TARGET/components/com_pagebuilderck/pagebuilderck.xml")
fi
if [[ "$HTTP_CODE" != "200" ]]; then
echo "UNKNOWN — Page Builder CK not detected on $TARGET (component may be absent, renamed, or WAF-blocked)"
exit 0
fi
# 2. Attempt to read manifest for version
MANIFEST=$(curl -sk -A "$UA" "$TARGET/administrator/components/com_pagebuilderck/pagebuilderck.xml" 2>/dev/null)
VERSION=$(echo "$MANIFEST" | grep -oE '<version>[^<]+' | head -1 | sed 's/<version>//')
if [[ -z "$VERSION" ]]; then
# fall back to guessing from CSS asset hash if present
echo "UNKNOWN — component detected but version not disclosed publicly; manually verify against 3.6.0 / 3.4.10 / 3.1.1"
exit 0
fi
# 3. Version comparison
ver_lte() { [[ "$(printf '%s\n%s' "$1" "$2" | sort -V | head -1)" == "$1" ]]; }
if ver_lte "$VERSION" "3.1.0"; then
echo "VULNERABLE — Page Builder CK $VERSION (< $FIXED_J3 for Joomla 3)"
exit 1
elif [[ "$VERSION" == 3.1.* || "$VERSION" == 3.2.* || "$VERSION" == 3.3.* ]]; then
# Joomla 3 line — fixed at 3.1.1
if ver_lte "$VERSION" "3.1.0"; then
echo "VULNERABLE — Page Builder CK $VERSION"; exit 1
fi
echo "PATCHED — Page Builder CK $VERSION"; exit 0
elif [[ "$VERSION" == 3.4.* ]]; then
if ver_lte "$VERSION" "3.4.9"; then
echo "VULNERABLE — Page Builder CK $VERSION (needs $FIXED_J4)"; exit 1
fi
echo "PATCHED — Page Builder CK $VERSION"; exit 0
elif ver_lte "$VERSION" "3.5.10"; then
echo "VULNERABLE — Page Builder CK $VERSION (needs $FIXED_CURRENT)"
exit 1
else
echo "PATCHED — Page Builder CK $VERSION"
exit 0
fi