critical

CVE

CVE-2026-65145, CVE-2026-114612, CVE-2026-35002, CVE-2026-65151, CVE-2026-65119, CVE-2026-114053

CWE

CWE-95, CWE-502, CWE-269, CWE-306, CWE-89, CWE-73

Affected Surface

  • PyPI `agno` (`agno-agi/agno`) versions `< 2.3.24` (`CVE-2026-35002` / `GHSA-m4w4-3r8h-jw98` / `PYSEC-2026-256`, CVSS 9.8 Critical)
  • PyPI `litellm` (`BerriAI/litellm`) versions `>= 1.91.0` (and `1.87.0`..`1.90.x` with `EXPERIMENTAL_UI_LOGIN=true`) before `1.100.4`, `1.101.3`, `1.102.2`, `1.103.1` (`CVE-2026-114612` / `GHSA-7hp6-4w63-5g45`, CVSS 9.9), and `< 1.95.0` (`GHSA-g5ff-637f-6q2m`, CVSS 8.1)
  • PyPI `hydra-core` (`hydra-ecosystem/hydra`) versions `>= 1.3.6, < 1.3.8` and `>= 1.4.0.dev9, < 1.4.0rc3` (`GHSA-wf6j-7hvr-gr93` / `GHSA-757g-8w3h-hp29`, CVSS 7.8 High)
  • PyPI `vllm` (`vllm-project/vllm`) versions `>= 0.7.3, < 0.31.0` when `--trust-remote-code` is enabled on multimodal models (`CVE-2026-114053` / `GHSA-h3rc-6mm3-gc2m`, CVSS 8.1 High)
  • NVIDIA NeMo Agent Toolkit (`NVIDIA/NeMo-Agent-Toolkit`) versions `1.0` through `1.8.0` (`CVE-2026-65145`, CVSS 10.0 Critical) and `1.4` through `1.6` (`CVE-2026-65151`, CVSS 8.4 High)

TL;DR

On 27 October 2026, seven high- and critical-severity vulnerabilities were published across Python AI agent SDKs, LLM proxy gateways, and configuration/serving libraries:

  1. Agno < 2.3.24 (CVE-2026-35002 / GHSA-m4w4-3r8h-jw98, CVSS 9.8 Critical): In libs/agno/agno/models/base.py (run_function_calls()) and libs/agno/agno/tools/function.py (UserInputField.from_dict()), Agno converted the field_type string on a FunctionCall user-input field into a Python type by calling eval(field_type). Any caller, prompt-injected model output, or deserialized tool call that controlled field_type could execute arbitrary Python code in the Agno process.
  2. LiteLLM Proxy (CVE-2026-114612 / GHSA-7hp6-4w63-5g45, CVSS 9.9 Critical, and GHSA-g5ff-637f-6q2m, CVSS 8.1 High):
    • CVE-2026-114612: LiteLLM’s proxy used encrypt_value_helper() (keyed by LITELLM_SALT_KEY or LITELLM_MASTER_KEY without AES-GCM associated data) for two separate tasks: encrypting user-supplied secret values inside API key metadata and minting ExperimentalUIJWTToken bearer session tokens. An authenticated internal_user could generate an API key whose metadata contained a JSON payload matching a proxy_admin session token ({"user_id": ..., "user_role": "proxy_admin", ...}), receive the encrypted v2:gcm:... blob in the API response, and present that ciphertext as a bearer token to become proxy_admin (which can execute arbitrary commands via the MCP stdio endpoint). Note that the LiteLLM 1.107.0 postmortem on 21 October specifically referenced an embargoed enterprise vulnerability scheduled for disclosure on 27 October.
    • GHSA-g5ff-637f-6q2m (< 1.95.0): The /utils/transform_request request-body blocklist blocked vertex_credentials but omitted its alias vertex_ai_credentials, letting a low-privilege internal_user_viewer read local files (including /proc/self/environ containing LITELLM_MASTER_KEY) and send them to an attacker-controlled URL.
  3. Meta Hydra (hydra-core 1.3.6..1.3.7 and 1.4.0.dev9..1.4.0rc2, GHSA-wf6j-7hvr-gr93, CVSS 7.8 High): Hydra’s legacy UNCONTROLLED_EXECUTION_TARGETS blocklist blocked pickle., marshal., shelve., and pydoc., but omitted yaml.. When an application passed a third-party model or checkpoint config (for example from Hugging Face) to legacy hydra.utils.instantiate(), setting _target_: yaml.unsafe_load executed arbitrary Python code via !!python/object/apply tags.
  4. vLLM 0.7.3 to < 0.31.0 (CVE-2026-114053 / GHSA-h3rc-6mm3-gc2m, CVSS 8.1 High): When serving a multimodal model with --trust-remote-code, vLLM allowed per-request mm_processor_kwargs to override code_revision in AutoProcessor.from_pretrained(). Even when the operator pinned --revision to an audited commit, an untrusted API caller could point mm_processor_kwargs.code_revision at an unreviewed branch or PR revision in the same model repo and execute arbitrary Python code on import.
  5. NVIDIA NeMo Agent Toolkit < 1.9.0 (CVE-2026-65145, CVSS 10.0 Critical, and CVE-2026-65151, CVSS 8.4 High): In Security Bulletin 5912, NVIDIA disclosed a missing-authentication vulnerability (CVE-2026-65145, 1.0 to 1.8.0) enabling unauthenticated code execution and privilege escalation, plus a SQL injection flaw (CVE-2026-65151, 1.4 to 1.6), both fixed in v1.9.0.

Affected packages and projects

EcosystemPackage / ProjectCVE / AdvisorySeverityAffected versionsFixed versionVulnerable component
PyPI / GitHubNVIDIA NeMo Agent Toolkit (NVIDIA/NeMo-Agent-Toolkit)CVE-2026-65145, CVE-2026-65151CVSS 10.0 Critical / 8.4 High1.0..1.8.0 (65145); 1.4..1.6 (65151)1.9.0NeMo Agent Toolkit authentication & SQL query handling (NVIDIA Bulletin 5912)
PyPIlitellmCVE-2026-114612 (GHSA-7hp6-4w63-5g45)CVSS 9.9 Critical>= 1.91.0 (and 1.87.0..1.90.x with EXPERIMENTAL_UI_LOGIN=true)1.100.4, 1.101.3, 1.102.2, 1.103.1 (1.106.4 current safe)litellm/proxy/auth/auth_checks.py (ExperimentalUIJWTToken), encrypt_decrypt_utils.py
PyPIlitellmGHSA-g5ff-637f-6q2mCVSS 8.1 High< 1.95.01.95.0 (1.106.4 current safe)litellm/proxy/auth/auth_utils.py (/utils/transform_request vertex_ai_credentials)
PyPIagnoCVE-2026-35002 (GHSA-m4w4-3r8h-jw98, PYSEC-2026-256)CVSS 9.8 Critical< 2.3.242.3.24 (3.1.10 current)libs/agno/agno/models/base.py (run_function_calls), agno/tools/function.py (UserInputField.from_dict)
PyPIvllmCVE-2026-114053 (GHSA-h3rc-6mm3-gc2m)CVSS 8.1 High>= 0.7.3, < 0.31.00.31.0 (0.32.0 current)Multimodal request mm_processor_kwargs / --trust-request-mm-kwargs
PyPIhydra-coreGHSA-wf6j-7hvr-gr93 (GHSA-757g-8w3h-hp29)CVSS 7.8 High>= 1.3.6, < 1.3.8; >= 1.4.0.dev9, < 1.4.0rc31.3.8, 1.4.0rc3hydra/_internal/execution_policy.py (UNCONTROLLED_EXECUTION_TARGETS)

Technical analysis

1. CVE-2026-35002: eval(field_type) in Agno FunctionCall user-input schemas

When an Agno agent processes a tool call that requests structured user input (user_input_fields), both run_function_calls() in libs/agno/agno/models/base.py and UserInputField.from_dict() in libs/agno/agno/tools/function.py resolved the string type name ("str", "int", "bool", etc.) by passing it straight to Python’s built-in eval():

--- a/libs/agno/agno/models/base.py
+++ b/libs/agno/agno/models/base.py
@@ -2030,10 +2030,20 @@ def run_function_calls(
                 user_input_schema = []
                 for input_field in fc.arguments.get("user_input_fields", []):
                     field_type = input_field.get("field_type")
-                    try:
-                        python_type = eval(field_type) if isinstance(field_type, str) else field_type
-                    except (NameError, SyntaxError):
-                        python_type = str  # Default to str if type is invalid
+                    if isinstance(field_type, str):
+                        type_mapping = {
+                            "str": str,
+                            "int": int,
+                            "float": float,
+                            "bool": bool,
+                            "list": list,
+                            "dict": dict,
+                        }
+                        python_type = type_mapping.get(field_type, str)

Because fc.arguments comes from model tool-call output or serialized FunctionCall payloads, an attacker who influenced the model’s FunctionCall arguments (via prompt injection, an untrusted MCP/tool definition, or an API request) could set "field_type": "__import__('os').system('...')" and execute arbitrary Python code. Commit cbf675521d (v2.3.24) replaces both eval() calls with a static type_mapping dictionary lookup.

2. CVE-2026-114612 and GHSA-g5ff-637f-6q2m in LiteLLM Proxy

In CVE-2026-114612 (GHSA-7hp6-4w63-5g45, CVSS 9.9), ExperimentalUIJWTToken.get_experimental_ui_login_jwt_auth_token() in litellm/proxy/auth/auth_checks.py minted session tokens by serializing a LiteLLM_JWTAuth object to JSON and encrypting it with encrypt_value_helper():

# litellm/proxy/auth/auth_checks.py (vulnerable)
return encrypt_value_helper(valid_token.model_dump_json(exclude_none=True))

Inside litellm/proxy/common_utils/encrypt_decrypt_utils.py, _encrypt_aes_gcm() encrypted plaintext under AESGCM(_derive_key(signing_key)).encrypt(nonce, value.encode("utf-8"), None) with aad=None. Because the proxy used the exact same encrypt_value_helper() function to seal user-controlled secret fields stored in API key metadata (such as logging callback variables) and returned the sealed ciphertext to the caller, an authenticated internal_user could use the key-generation endpoint as an encryption oracle. By placing a JSON string with "user_role": "proxy_admin" into a field that LiteLLM encrypts at rest, the user received back a valid v2:gcm:... ciphertext that the bearer-token authentication path decrypted and trusted as a proxy_admin session token. Once promoted to proxy_admin, the attacker could register or invoke an MCP stdio server to run arbitrary OS commands.

Commit 1d5fdc87fe binds session tokens to a dedicated AES-GCM Additional Authenticated Data (aad) context and litellm_login_ prefix via encrypt_bearer_token() / decrypt_bearer_token(), so ciphertexts produced by encrypt_value_helper() (aad=None) fail GCM tag verification when presented as bearer tokens.

Separately, in GHSA-g5ff-637f-6q2m (commit 065faf6e69, fixed in 1.95.0), the /utils/transform_request endpoint blocked vertex_credentials in request bodies from low-privilege internal_user_viewer callers, but missed the alias vertex_ai_credentials. Passing a file path in vertex_ai_credentials alongside an attacker-controlled api_base caused the Vertex AI credential loader to read the local file and transmit its contents outbound.

3. GHSA-wf6j-7hvr-gr93 in Meta Hydra and CVE-2026-114053 in vLLM

  • PyYAML gadget gap in Hydra’s legacy blacklist (GHSA-wf6j-7hvr-gr93, commit 9a7a9a287d): In hydra-core 1.3.6 and 1.3.7, hydra/_internal/execution_policy.py maintained UNCONTROLLED_EXECUTION_TARGETS to block dangerous _target_ callables (eval, exec, pickle.*, marshal.*, shelve.*, trace.*, pydoc.*, bdb.*) when hydra.utils.instantiate() ran without an explicit execution whitelist. However, yaml. was omitted from the prefix denylist. An attacker who controlled a Hydra configuration file bundled inside a model checkpoint could specify _target_: yaml.unsafe_load (or yaml.load with _target_: yaml.UnsafeLoader) and pass a string containing !!python/object/apply:os.system ["..."]. Hydra 1.3.8 and 1.4.0rc3 add "yaml." to UNCONTROLLED_EXECUTION_TARGETS while excepting only yaml.safe_load, yaml.safe_load_all, yaml.safe_dump, and yaml.safe_dump_all.
  • Per-request mm_processor_kwargs.code_revision RCE in vLLM (CVE-2026-114053, commit 31f2e70cd3): When a vLLM operator serves a multimodal model that requires --trust-remote-code and pins --revision <commit-sha> so only audited model code runs, vLLM’s multimodal processor loader previously merged per-request mm_processor_kwargs from the OpenAI-compatible API request directly into AutoProcessor.from_pretrained(..., **mm_processor_kwargs). A client that sent "mm_processor_kwargs": {"code_revision": "refs/pull/123/head"} overrode the code_revision argument passed to Hugging Face transformers, causing the vLLM server to fetch and import dynamic auto_map Python code from an unreviewed revision. Starting in vLLM 0.31.0, non-empty per-request mm_processor_kwargs and media_io_kwargs are rejected by default unless --trust-request-mm-kwargs is explicitly passed on the CLI.

Detection and remediation

# 1. Check Python environments and dependency lockfiles for affected versions
pip show agno litellm hydra-core vllm nvidia-nat 2>/dev/null || true

rg -n -i '"?(agno|litellm|hydra-core|vllm|nvidia-nat|nemo-agent-toolkit)"?\s*([~=!<>]=|:)' \
  requirements*.txt pyproject.toml uv.lock poetry.lock Pipfile.lock 2>/dev/null

# 2. Search model/checkpoint YAML configs for suspicious Hydra _target_: yaml.* entries
rg -n '_target_\s*:\s*["'\'']?yaml\.' --glob '*.{yaml,yml}' . 2>/dev/null

# 3. Check LiteLLM deployment configs for EXPERIMENTAL_UI_LOGIN=true
rg -n 'EXPERIMENTAL_UI_LOGIN' . --glob '*.{yaml,yml,env,sh,py}' 2>/dev/null
  1. Upgrade affected packages:
    • Agno: Upgrade to agno >= 2.3.24 (3.1.10 is current on PyPI).
    • LiteLLM: Upgrade to a patched release (>= 1.103.1, or 1.106.4 on the current branch; never install 1.107.0, which was a compromised supply-chain release on 21 October). If you cannot upgrade immediately, set EXPERIMENTAL_UI_LOGIN=false to mitigate CVE-2026-114612.
    • Hydra: Upgrade to hydra-core >= 1.3.8 (or 1.4.0rc3 on the 1.4 pre-release track).
    • vLLM: Upgrade to vllm >= 0.32.0 (which includes both 0.31.0’s CVE-2026-114053 fix and the 0.32.0 fixes for CVE-2026-115912 and CVE-2026-115915), and keep --trust-request-mm-kwargs disabled when serving untrusted clients.
    • NVIDIA NeMo Agent Toolkit: Update to v1.9.0 or later from NVIDIA/NeMo-Agent-Toolkit.

Timeline

  • 2026-09-10: NVIDIA releases NeMo Agent Toolkit v1.9.0.
  • 2026-10-21: During the LiteLLM 1.107.0 supply-chain incident, LiteLLM notes that its private enterprise registry carried an embargoed security patch scheduled for public disclosure on 27 October.
  • 2026-10-27 (13:16 to 17:08 UTC): NVIDIA publishes Security Bulletin 5912 (CVE-2026-65145, CVE-2026-65151), and the GitHub Advisory Database and NVD publish GHSA-m4w4-3r8h-jw98 (CVE-2026-35002 in Agno), GHSA-7hp6-4w63-5g45 (CVE-2026-114612 in LiteLLM), GHSA-g5ff-637f-6q2m (LiteLLM), GHSA-h3rc-6mm3-gc2m (CVE-2026-114053 in vLLM), and GHSA-wf6j-7hvr-gr93 (Hydra).

From research to remediation

Check whether this pattern exists in your codebase

Turn this research into a remediation workflow. Scan dependencies and package manifests for similar supply-chain risk, then prioritize fixes with reachability context.

References