VYPR
High severityNVD Advisory· Published May 16, 2024· Updated Aug 1, 2024

Command Injection in run-llama/llama_index

CVE-2024-4181

Description

A command injection vulnerability exists in the RunGptLLM class of the llama_index library, version 0.9.47, used by the RunGpt framework from JinaAI to connect to Language Learning Models (LLMs). The vulnerability arises from the improper use of the eval function, allowing a malicious or compromised LLM hosting provider to execute arbitrary commands on the client's machine. This issue was fixed in version 0.10.13. The exploitation of this vulnerability could lead to a hosting provider gaining full control over client machines.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Improper use of eval in llama_index's RunGptLLM class allows command injection, enabling malicious LLM providers to execute arbitrary commands on client machines.

Root

Cause

CVE-2024-4181 is a command injection vulnerability found in the RunGptLLM class of the llama_index library (version 0.9.47), used by the RunGpt framework from JinaAI to connect to Language Learning Models (LLMs). The vulnerability stems from the improper use of Python's eval function. Specifically, in the stream_complete and stream_chat methods, the code was calling eval(item.data) on data received from the LLM provider [3]. This is a critical security flaw as it allows arbitrary code execution on the client machine when processing LLM responses.

Exploitation

To exploit this vulnerability, an attacker would need to control or compromise an LLM hosting provider that the client connects to via the vulnerable library. No authentication is required against the client beyond the ability to send malicious responses. The attack surface is the network communication between the client and the LLM provider. When the client processes a crafted response, the eval function executes the attacker's payload in the client's context [1][3].

Impact

Successful exploitation grants the malicious LLM provider full control over the client machine. This includes the ability to execute arbitrary commands, access sensitive data, install malware, or pivot to other systems. The vulnerability is rated as critical due to the high potential for complete compromise of affected systems [1].

Mitigation

The vulnerability has been patched in llama_index version 0.10.13 [1]. The fix replaced the eval call with a safe dict() conversion, as shown in the commit that removed the vulnerable code [3]. Users are strongly advised to update their library immediately. No workaround is available for older versions. This CVE is not listed in CISA's Known Exploited Vulnerabilities catalog as of the publication date.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
llama-indexPyPI
< 0.10.130.10.13
llama-index-llms-rungptPyPI
< 0.1.30.1.3

Affected products

3

Patches

1
d73715eaf064

remove random vuls

https://github.com/run-llama/llama_indexLogan MarkewichFeb 24, 2024via ghsa
3 files changed · +5 12
  • llama-index-core/llama_index/core/query_engine/cogniswitch_query_engine.py+0 1 modified
    @@ -41,7 +41,6 @@ def query_knowledge(self, query: str) -> Response:
             response = requests.post(
                 self.knowledge_request_endpoint,
                 headers=self.headers,
    -            verify=False,
                 data=data,
             )
             if response.status_code == 200:
    
  • llama-index-integrations/llms/llama-index-llms-rungpt/llama_index/llms/rungpt/base.py+2 3 modified
    @@ -1,4 +1,3 @@
    -import json
     from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union
     
     from llama_index.core.base.llms.types import (
    @@ -153,7 +152,7 @@ def stream_complete(
             def gen() -> CompletionResponseGen:
                 text = ""
                 for item in response_iter:
    -                item_dict = json.loads(json.dumps(eval(item.data)))
    +                item_dict = dict(item.data)
                     delta = item_dict["choices"][0]["text"]
                     additional_kwargs = item_dict["usage"]
                     text = text + self._space_handler(delta)
    @@ -214,7 +213,7 @@ def stream_chat(
             def gen() -> ChatResponseGen:
                 content = ""
                 for item in chat_iter:
    -                item_dict = json.loads(json.dumps(eval(item.data)))
    +                item_dict = dict(item.data)
                     chat_message, delta = self._message_unpacker(item_dict)
                     content = content + self._space_handler(delta)
                     chat_message.content = content
    
  • llama-index-integrations/tools/llama-index-tools-cogniswitch/llama_index/tools/cogniswitch/base.py+3 8 modified
    @@ -91,9 +91,7 @@ def store_data(
                     "documentName": document_name,
                     "documentDescription": document_description,
                 }
    -            response = requests.post(
    -                api_url, headers=headers, verify=False, data=data, files=files
    -            )
    +            response = requests.post(api_url, headers=headers, data=data, files=files)
     
             elif file:
                 api_url = self.source_file_endpoint
    @@ -108,9 +106,7 @@ def store_data(
                     "documentName": document_name,
                     "documentDescription": document_description,
                 }
    -            response = requests.post(
    -                api_url, headers=headers, verify=False, data=data, files=files
    -            )
    +            response = requests.post(api_url, headers=headers, data=data, files=files)
             if response.status_code == 200:
                 return response.json()
             else:
    @@ -134,7 +130,7 @@ def query_knowledge(self, query: str) -> dict:
             headers = self.headers
     
             data = {"query": query}
    -        response = requests.post(api_url, headers=headers, verify=False, data=data)
    +        response = requests.post(api_url, headers=headers, data=data)
             if response.status_code == 200:
                 return response.json()
             else:
    @@ -157,7 +153,6 @@ def knowledge_status(self, document_name: str) -> dict:
                 self.knowledge_status_endpoint,
                 headers=self.headers,
                 params=params,
    -            verify=False,
             )
             if response.status_code == 200:
                 source_info = response.json()
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.