# CVE-2026-48908 — Variant / Bypass Analysis

## Summary

This variant stage tested whether SP Page Builder 6.6.2 can be bypassed or whether the same underlying unauthenticated file-upload bug can be triggered from a different entry point. **No bypass or distinct RCE variant was found.** The vendor fix adds an authorization/CSRF guard to the front-end `SppagebuilderControllerAsset` class, and that guard blocks every tested unauthenticated path that reaches the same ZIP extraction sink. A sibling unauthenticated method (`asset.loadCustomIcons`) does exist on the vulnerable build, but it reads from the database rather than writing files, so it is not a variant of the file-upload/RCE vulnerability.

## Fix Coverage / Assumptions

### What the fix covers
- The only unauthenticated path to the ZIP upload/extraction sink is the front-end task `index.php?option=com_sppagebuilder&task=asset.uploadCustomIcon`.
- The 6.6.2 patch adds a constructor to `site/controllers/asset.php` that checks:
  1. `core.admin` or `core.manage` authorization for the component.
  2. A logged-in user (`$user->id`).
  3. A valid Joomla CSRF token via `Session::checkToken()`.
- The patch also removes the three non-upload CRUD methods (`loadCustomIcons`, `deleteCustomIcon`, `changeCustomIconStatus`) from the site controller and narrows `unpack()` from `public static` to `private static`, preventing direct task invocation.

### What the fix does NOT cover
- The upload logic itself is unchanged: the ZIP is still extracted and copied into the web root under `/media/com_sppagebuilder/assets/iconfont/`. The extension filter is still a case-sensitive block-list. An attacker with a valid administrator session and a CSRF token could still execute the same RCE chain.
- The fix does not add a content allow-list, restrict the iconfont directory to static assets, or disable `.htaccess` / PHP execution in that directory. Those remain defense-in-depth gaps that the site administrator must address on the web server.
- No code paths outside `site/controllers/asset.php` were modified, because every other file-upload or file-write controller already had authorization checks (`media.php`, `ai_content.php`, the admin `editor.php`, `site/views/ajax/view.json.php`, etc.).

## Variant / Alternate Trigger

Five candidate entry points were tested against the vulnerable (6.6.1) and fixed (6.6.2) builds:

| Candidate | Vulnerable 6.6.1 | Fixed 6.6.2 | Assessment |
|-----------|------------------|-------------|------------|
| `asset.uploadCustomIcon` (control) | **RCE confirmed** | `403` "require admin" | The fix covers the original sink. |
| `uploadCustomIcon` without controller prefix | `404` | `404` | Joomla routes to the default controller, not the asset controller. Not a bypass. |
| `asset.unpack` (direct) | `500` (missing argument) | `403` | The method was never reachable with attacker-controlled input; the fix blocks it anyway. |
| `editor.icons` via `/administrator/` | Blocked by auth | Blocked by auth | The admin `IconsTrait` is protected by the admin editor's own constructor. |
| `asset.loadCustomIcons` | `200` (unauthenticated list) | `403` | Same controller, but the method only reads from the database; it does not upload or extract files, so it is not a variant of the file-upload/RCE bug. |

### Code paths involved
- `site/controllers/asset.php` — `SppagebuilderControllerAsset::__construct()` (new guard) and `uploadCustomIcon()` (the sink).
- `admin/editor/traits/IconsTrait.php` — `uploadIcons()` (same logic, but only used by the admin editor, which is protected by `admin/controllers/editor.php`).
- `admin/controllers/editor.php` — `SppagebuilderControllerEditor::__construct()` (admin-side guard).

## Impact

- **Package / component:** SP Page Builder (`com_sppagebuilder`) by JoomShaper.
- **Affected versions (as tested):** 6.6.1 vulnerable, 6.6.2 fixed.
- **Risk level:** No new risk introduced by this variant search. The original unauthenticated RCE is fully mitigated by the 6.6.2 guard for the tested paths.

## Impact Parity

- **Disclosed/claimed maximum impact:** Unauthenticated arbitrary file upload leading to remote code execution.
- **Reproduced impact from this variant run:** None — no distinct bypass or alternate RCE trigger was confirmed.
- **Parity:** `none` for the variant stage. The original RCE was reproduced as a control on 6.6.1.
- **Not demonstrated:** Further post-exploitation or privilege escalation beyond the reproduced `www-data` shell.

## Root Cause

The root cause of the original CVE is missing authentication/authorization on the `SppagebuilderControllerAsset` class, which allowed any remote caller to reach `uploadCustomIcon()` and extract an attacker-controlled ZIP under the web root. The 6.6.2 fix removes that missing-auth condition by adding a constructor guard. Because the guard runs for every task of that class, no alternative task name or direct method invocation can bypass it from an unauthenticated session. The admin-side `IconsTrait` shares the same extraction logic but is already protected by the admin editor's constructor, so it cannot be used as an unauthenticated variant either.

## Reproduction Steps

1. **Script:** `bundle/vuln_variant/reproduction_steps.sh` (self-contained, idempotent; exits 1 when no bypass is found).
2. **What it does:**
   - Creates two Docker Compose stacks (`joomla:5.2-php8.2-apache` + `mysql:8.0`) for 6.6.1 and 6.6.2.
   - Installs the corresponding SP Page Builder ZIP through the real Joomla web installer.
   - Runs a Python variant tester that uploads the same `.htaccess + .PHP` payload to each candidate endpoint and tries to execute the dropped shell.
   - Runs the original public PoC as a control for each build.
3. **Expected evidence:**
   - **Vulnerable 6.6.1:** control endpoint prints `RCE` and the PoC prints `CODE EXECUTION CONFIRMED`.
   - **Fixed 6.6.2:** every candidate endpoint returns an auth-related block (403/"require admin") and the PoC prints `TARGET NOT VULNERABLE`.

## Evidence

Log files produced by the variant script (both runs produced the same result):

- `bundle/logs/variant_vuln_test.log` — variant matrix on the vulnerable build.
- `bundle/logs/variant_fixed_test.log` — variant matrix on the fixed build.
- `bundle/logs/variant_vuln_poc_control.log` — original PoC confirming RCE on 6.6.1.
- `bundle/logs/variant_fixed_poc_control.log` — original PoC confirming 6.6.2 rejects the upload.
- `bundle/logs/variant_vuln_compose.log` and `bundle/logs/variant_fixed_compose.log` — Docker stack creation.
- `bundle/vuln_variant/runtime_manifest.json` — structured runtime evidence.

Key excerpts from the latest run:

**Vulnerable 6.6.1 — control endpoint RCE:**
```json
{
  "control_asset.uploadCustomIcon": {
    "result": "RCE",
    "detail": "SPPB-VAR-42\n",
    "iconfont_dir": "media/com_sppagebuilder/assets/iconfont/icovoqhdk"
  }
}
```

**Fixed 6.6.2 — all candidates blocked:**
```json
{
  "control_asset.uploadCustomIcon": { "result": "BLOCKED", "detail": "auth/csrf message", "status": 403 },
  "variant_task_no_prefix": { "result": "BLOCKED", "detail": "non-JSON response", "status": 404 },
  "variant_direct_unpack": { "result": "BLOCKED", "detail": "auth/csrf message", "status": 403 },
  "variant_admin_editor.icons": { "result": "BLOCKED", "detail": "auth/csrf message", "status": 200 },
  "variant_asset.loadCustomIcons": { "result": "BLOCKED", "detail": "auth/csrf message", "status": 403 }
}
```

**Original PoC control on 6.6.2:**
```
[*] try .php            -> 403 'require admin' = patched
[-] TARGET NOT VULNERABLE — SP Page Builder is patched (6.6.2+)
```

**Environment:** Joomla 5.2 + PHP 8.2 (Apache) + MySQL 8.0, SP Page Builder 6.6.1 and 6.6.2 in Docker, tested from an ephemeral `python:3-slim` container on the same network.

## Recommendations / Next Steps

- **No additional code change is required** for the unauthenticated vector. The 6.6.2 fix is complete for the claimed scope.
- **Defense in depth:**
  - Add a strict extension allow-list to the icon-font upload (only `.ttf`, `.woff`, `.woff2`, `.css`, `.json`) instead of relying on the case-sensitive block-list.
  - Disable PHP execution and `AllowOverride` under `/media/com_sppagebuilder/assets/iconfont/` at the web-server level.
- **Monitor for partial updates:** A forum post suggested some 6.6.2 installations might still have an unpatched `site/controllers/asset.php` if the extension update was incomplete. Verify the patched file hash after upgrading.
- **Assume-breach review:** As recommended in the original repro, check for unexpected `.php`/`.PHP` files, `.htaccess`, and newly created directories under the iconfont path, and look for rogue Super User accounts.

## Additional Notes

- **Idempotency:** The variant script was run twice consecutively. Both runs exited 1 with the same results: the vulnerable build reproduced the original RCE, the fixed build blocked all tested paths, and no bypass/variant was found.
- **Limitations:** The variant search focused on entry points and task names within the SP Page Builder component. It did not attempt to bypass a valid Joomla admin session or CSRF token; such a scenario would be an authenticated compromise, not a bypass of the unauthenticated vulnerability.
- **Threat model:** No `SECURITY.md` or explicit threat model was found in the package. The Joomla! Project CNA and vendor advisory scope the issue as unauthenticated remote code execution, and the 6.6.2 fix is scoped to that exact trust boundary.

