
PoC für CVE-2026-7669: SGLang stilles trust_remote_code-Override -> RCE
SGLang überschreibt stillschweigend trust_remote_code=False mit True und ruft
AutoTokenizer.from_pretrained erneut auf, sobald transformers v5 ein
TokenizersBackend-Objekt zurückgibt. Ein Modell mit einer benutzerdefinierten tokenizer_class und
einer auto_map, die auf tokenizer.py verweist, erreicht beliebige Codeausführung
innerhalb des SGLang-Prozesses, selbst wenn der Betreiber False übergeben hat. In keiner
Log-Ebene wird eine Zeile ausgegeben.
main (Commit fae90abf6)python/sglang/srt/utils/hf_transformers_utils.py:898-909AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H = 8.8 Hochif not trust_remote_code and type(tokenizer).__name__ == "TokenizersBackend":
tokenizer = AutoTokenizer.from_pretrained(
tokenizer_name,
*args,
trust_remote_code=True,
tokenizer_revision=tokenizer_revision,
clean_up_tokenization_spaces=False,
**kwargs,
)
Eingeführt in PR #17784
(Commit d1e95af28, 2026-03-18). Der ursprüngliche logger.info(...)-Hinweis
wurde durch Commit 27ac831a8 (2026-03-23) unter dem Titel „docs: improve CI
and testing documentation" entfernt, wodurch die Überschreibung in jeder
veröffentlichten verwundbaren Version völlig still bleibt.
git clone https://github.com/<your-org>/CVE-2026-7669.git
cd CVE-2026-7669
./run.sh
Erstellt ein Docker-Image (python:3.12.7-slim-bookworm + transformers==5.3.0
Andere Modi:
./run.sh --server Reproduktion über TokenizerManager.__init__
./run.sh --versions transformers 5.0..5.5 Matrix
./run.sh --revshell IP optionale Reverse Shell auf IP:4444
./run.sh --rebuild erzwingt --no-cache Neubau
./run.sh --copy-ledger ./ledger.json
Exit 0 bedeutet bestätigt. Abschließende Zusammenfassung:
Phase 1 transformers + False return=TokenizersBackend exec=False
Phase 1b PATCHED sglang + False return=TokenizersBackend exec=False
Phase 2 REAL sglang + False return=MaliciousTokenizer exec=True
Phase 2b PATCHED sglang + True return=MaliciousTokenizer exec=True
Phase 3 REAL sglang + False (langsam) return=MaliciousTokenizer exec=True
Behauptungen: 29 PASS / 0 FAIL / 0 N/A / 29 GESAMT
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H = 8.8 Hoch
*** SCHWACHSTELLE BESTÄTIGT -- ALLE BEHAUPTUNGEN GESTÜTZT ***
Exit-Codes:
| Code | Bedeutung |
|---|---|
| 0 | Bestätigt |
| 1 | Nicht ausgelöst |
| 2 | Falsch positiv (transformers selbst führte tokenizer.py aus, Fehler liegt upstream) |
| 3 | Preflight mit festgelegter Version fehlgeschlagen |
Die Preflight-Phase liest pinned_versions.json und prüft jeden Wert
gegen die Laufzeitumgebung. Abweichungen führen vor jedem Test zu Exit 3.
| Komponente | Festlegung |
|---|---|
| Python | 3.12.7-slim-bookworm |
| transformers | 5.3.0 |
| SGLang-Commit | fae90abf6e15aaffb6fd924a439253674771487d |
hf_transformers_utils.py SHA256 | 9e798eabf2451630bd5939aa9aa65ec397a769157f26fb905057c17ee938497e |
| Verwundbarer Block (Zeilen 898-909) SHA256 | 109fe46208631b80a58755799b44339e19b6902ffe76d68f18b31a59e26b2ece |
| Metrik | Wert | Gestützt durch |
|---|---|---|
| AV | N | Auslösedateien (config.json, tokenizer_config.json, tokenizer.json, tokenizer.py) sind das Standard-HF-Hub-auto_map-Layout. Jede Registry, die sie bereitstellt, erreicht den Fehler. |
| AC | L | PHASE-2 feuert deterministisch bei einem einzigen Lauf. Jede Auslösebedingung ist vom Angreifer erstellter Inhalt. PRE-1..7 bestätigen kein Umgebungs-Fingerprinting. |
| PR | N | Kostenloser HF-Hub-Upload ist ausreichend. Nichts in der Auslösekette erfordert bestehende Berechtigungen auf dem Opfer. |
| UI | R | Der Auslöser feuert nur, wenn ein Betreiber (oder eine vom Betreiber konfigurierte Pipeline) launch_server --model-path attacker/model aufruft. |
| S | U | Alle SEV-*-Behauptungen laufen innerhalb der SGLang-Prozessautorität. Kein Sandbox- oder Container-Escape. |
| C | H | SEV-secrets erfasst HF_TOKEN, OPENAI_API_KEY, ANTHROPIC_API_KEY, GPG_KEY aus der Prozessumgebung. SEV-network öffnet einen ausgehenden TCP-Exfiltrationskanal. |
| I | H | SEV-write-sglang, SEV-write-launchsrv, SEV-write-model, SEV-pip sind vier unabhängige Integritäts-Primitive an verschiedenen sensiblen Stellen. |
| A | H | Aus RCE abgeleitet. SEV-pip beweist beliebige Subprozessausführung, was dasselbe Primitive ist, das für Self-DoS benötigt wird. Der PoC demonstriert keinen direkten Self-Kill. |
8.8 ist die konservative Untergrenze. 9.6 (mit S:C) und 10.0 (sowohl S:C als auch
UI:N) sind vertretbar, hängen aber vom Prüfer ab.
UI:N ist für diese CVE nicht gerechtfertigt. Der HTTP-Server von SGLang hat
einen echten Standard-Umgehung ohne Authentifizierung, wenn api_key=None und admin_api_key=None
(verifiziert durch AUTH-1 gegen das decide_request_auth-Primitive zur
Laufzeit), aber kein HTTP-Endpunkt erreicht get_tokenizer nach dem Start
(verifiziert durch CHAIN-1). Alle vier get_tokenizer-Aufrufstellen
(TokenizerManager.__init__, Scheduler.__init__, TPWorker.__init__,
DetokenizerManager.__init__) feuern einmal beim Serverstart aus dem
vom Betreiber bereitgestellten --model-path. Die Authentifizierungsumgehung ist daher ein separates
Problem und kein Kettenpartner für CVE-2026-7669.
Der PoC schreibt ein JSON-Ledger unter /tmp/poc_claim_ledger.json mit 29
einzeln testbaren Behauptungen. Verwenden Sie ./run.sh --copy-ledger ./ledger.json,
um es zu extrahieren.