CVE-2026-41523: vLLM: Security Check Bypass via assert Statement in Activation Function Loading Allows Arbitrary Code Execution
Summary
An assert-based security check in vLLM's activation function loading allows any unauthenticated attacker to achieve arbitrary code execution on the server by publishing a malicious HuggingFace model, when vLLM runs in Python optimized mode (python -O or PYTHONOPTIMIZE=1).
Details
vLLM uses an assert statement at vllm/modelexecutor/layers/pooler/activations.py:48 as its sole security control to restrict which activation functions can be loaded from a HuggingFace model's config.json:
python vllm/modelexecutor/layers/pooler/activations.py:35-53 functionname: str | None = None if ( hasattr(config, "sentencetransformers") and "activationfn" in config.sentencetransformers ): functionname = config.sentencetransformers["activationfn"] elif ( hasattr(config, "sbertcedefaultactivationfunction") and config.sbertcedefaultactivationfunction is not None ): functionname = config.sbertcedefaultactivationfunction
if functionname is not None: assert functionname.startswith("torch.nn.modules."), ( "Loading of activation functions is restricted to " "torch.nn.modules for security reasons" ) fn = resolveobjbyqualname(functionname)()
Python's assert statements are stripped at compile time when running in optimized mode (python -O or PYTHONOPTIMIZE=1). When the assert is absent, the attacker-controlled functionname from the model's config.json is passed directly to resolveobjbyqualname() — an unrestricted import gadget:
python def resolveobjbyqualname(qualname: str) -> Any: modulename, objname = qualname.rsplit(".", 1) module = importlib.importmodule(modulename) return getattr(module, objname)
This is the same vulnerability class as CVE-2017-1000433 (pysaml2 assert-based auth bypass), flagged by Bandit B101 and Ruff S101, and the reason Django proactively replaced all assert-based security checks (ticket #32508).
Attacker-controlled input sources: - config.sentencetransformers["activationfn"] (line 40) - config.sbertcedefaultactivationfunction (line 45)
Affected call sites — getactfn() is called via resolveclassifieractfn() from: - vllm/modelexecutor/layers/pooler/seqwise/poolers.py:122 — SequencePooler - vllm/modelexecutor/layers/pooler/tokwise/poolers.py:130 — TokenPooler
Broader systemic risk: resolveobjbyqualname is called from ~20 locations across the codebase with no validation of its own. Any future caller feeding user-controlled input to it without validation creates the same vulnerability class.
Suggested fix: Replace the assert with an explicit conditional raise:
python if not functionname.startswith("torch.nn.modules."): raise ValueError( "Loading of activation functions is restricted to " "torch.nn.modules for security reasons" )
Impact
Arbitrary code execution. A malicious model author publishes a HuggingFace model with a crafted config.json. When a victim loads this model with vLLM running under python -O or PYTHONOPTIMIZE=1, arbitrary code executes during model initialization with the privileges of the vLLM process.
The attack requires: 1. Victim loads a malicious model from HuggingFace (user interaction) 2. vLLM runs under python -O or PYTHONOPTIMIZE=1 (documented in production use) 3. Model uses a cross-encoder architecture (e.g. BERT or RoBERTa with sequence classification)
Coordinated disclosure note: This vulnerability was also reported via huntr.com on April 2, 2026 (https://huntr.com/bounties/dcb05b04-e625-41e7-adbc-bbae0cc2d64c). A GitHub Security Advisory was also filed because it is vLLM's stated preferred disclosure channel per SECURITY.md.
Fix
A fix for this was introduced in this commit: https://github.com/vllm-project/vllm/commit/b3c7ffcab82c2439726f8cb213800f6f38c023d3
Other sources
vLLM is an inference and serving engine for large language models (LLMs). Prior to 0.22.0, an assert-based security check in vLLM's activation function loading allows any unauthenticated attacker to achieve arbitrary code execution on the server by publishing a malicious HuggingFace model, when vLLM runs in Python optimized mode (python -O or PYTHONOPTIMIZE=1). This vulnerability is fixed in 0.22.0.
— MITRE
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/vllmto a version that resolves this vulnerability.Fixed in 0.22.0 - Upgrade
Upgrade
vllmto a version that resolves this vulnerability.Fixed in 0.22.0 - Configuration
Run vLLM without Python optimized mode so that the activation-function security check is not stripped (the issue occurs when `python -O` / `PYTHONOPTIMIZE=1` removes `assert` checks).
vLLM (Python runtime) PYTHONOPTIMIZE / python -O (assert stripping) = disable optimization (do not run with python -O or PYTHONOPTIMIZE=1) - Compensating control
If you must accept untrusted HuggingFace models, ensure only trusted repositories/models are used to prevent attacker-controlled `config.json` (including `sentence_transformers.activation_fn` / `sbert_ce_default_activation_function`) from reaching vLLM’s activation function resolver.
Event History
Frequently Asked Questions
What is the severity of CVE-2026-41523?
The severity of CVE-2026-41523 is classified as high with a score of 7.5.
How do I fix CVE-2026-41523?
To fix CVE-2026-41523, ensure that vLLM is not run in Python optimized mode by avoiding the `python -O` flag or setting `PYTHONOPTIMIZE` to 1.
What type of vulnerability is CVE-2026-41523?
CVE-2026-41523 is a code injection vulnerability that allows unauthenticated attackers to execute arbitrary code.
Who is affected by CVE-2026-41523?
Users of vLLM that run it in Python optimized mode and use malicious HuggingFace models are at risk from CVE-2026-41523.
What impact can CVE-2026-41523 have on my system?
CVE-2026-41523 can allow an attacker to execute arbitrary code on your server, which can lead to complete system compromise.