DEV Community

CVE Reports
CVE Reports

Posted on Originally published at cvereports.com

CVE-2026-35002: CVE-2026-35002: Eval Injection and Arbitrary Code Execution in Agno Agent Platform

CVE-2026-35002: Eval Injection and Arbitrary Code Execution in Agno Agent Platform

Vulnerability ID: CVE-2026-35002
CVSS Score: 9.8
Published: 2026-10-27

CVE-2026-35002 is an arbitrary code execution vulnerability in the Agno agent platform (formerly Phidata) affecting all versions prior to 2.3.24. The flaw resides in the model execution logic (libs/agno/agno/models/base.py) and tool serialization logic (libs/agno/agno/tools/function.py), where the application directly passes the field_type string parameter into Python's built-in eval() function to resolve string type names into Python data types. An attacker who can influence FunctionCall arguments via prompt injection or supply untrusted dictionary structures for deserialization can execute arbitrary Python expressions within the context of the host process.

TL;DR

Agno versions prior to 2.3.24 use Python's eval() function to resolve string type names in the field_type parameter during function calling and tool deserialization. Replacing type strings with arbitrary Python expressions allows unauthenticated remote code execution.


⚠️ Exploit Status: POC

Technical Details

  • CWE ID: CWE-95 (Eval Injection)
  • CVSS v3.1 Score: 9.8 (Critical)
  • CVSS v4.0 Score: 9.3 (Critical)
  • Attack Vector: Network (AV:N)
  • Impact: Arbitrary Code Execution (RCE)
  • EPSS Score: 1.15% (66.68th Percentile)
  • Exploit Status: Proof of Concept (PoC)
  • CISA KEV Status: Not Listed

Affected Systems

  • Agno Agent Platform (PyPI package: agno)
  • Agno: < 2.3.24 (Fixed in: 2.3.24)

Code Analysis

Commit: cbf6755

fix: replace eval() with type mapping SDK-417

diff --git a/libs/agno/agno/models/base.py b/libs/agno/agno/models/base.py
index abcdef1..cbf6755 100644
--- 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)
+                    elif isinstance(field_type, type):
+                        python_type = field_type
+                    else:
+                        python_type = str
                     user_input_schema.append(
                         UserInputField(
                             name=input_field.get("field_name"),
@@ -2185,10 +2195,20 @@ async def arun_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)
+                    elif isinstance(field_type, type):
+                        python_type = field_type
+                    else:
+                        python_type = str
                     user_input_schema.append(
                         UserInputField(
                             name=input_field.get("field_name"),
diff --git a/libs/agno/agno/tools/function.py b/libs/agno/agno/tools/function.py
index 1234567..89abcdef 100644
--- a/libs/agno/agno/tools/function.py
+++ b/libs/agno/agno/tools/function.py
@@ -54,9 +54,17 @@ def to_dict(self) -> Dict[str, Any]:

     @classmethod
     def from_dict(cls, data: Dict[str, Any]) -> "UserInputField":
+        type_mapping = {"str": str, "int": int, "float": float, "bool": bool, "list": list, "dict": dict}
+        field_type_raw = data["field_type"]
+        if isinstance(field_type_raw, str):
+            field_type = type_mapping.get(field_type_raw, str)
+        elif isinstance(field_type_raw, type):
+            field_type = field_type_raw
+        else:
+            field_type = str
         return cls(
             name=data["name"],
-            field_type=eval(data["field_type"]),  # Convert string type name to actual type
+            field_type=field_type,
             description=data["description"],
             value=data["value"],
         )
Enter fullscreen mode Exit fullscreen mode

Mitigation Strategies

  • Upgrade the Agno package to version 2.3.24 or later to eliminate the eval() injection sink.
  • Implement strict schema validation on all external dictionary data prior to calling deserialization helpers such as UserInputField.from_dict().
  • Restrict network egress and apply least-privilege execution contexts (such as isolated containers or sandboxes) for LLM agent worker processes.
  • Use static application security testing (SAST) rules to detect and block dynamic evaluation functions like eval() and exec() in Python codebases.

Remediation Steps:

  1. Audit all Python environments and dependency lockfiles using 'pip list | grep -i agno' to locate installations running versions prior to 2.3.24.
  2. Update the dependency specification in requirements.txt, pyproject.toml, or Pipfile to require 'agno>=2.3.24'.
  3. Execute 'pip install --upgrade "agno>=2.3.24"' and rebuild affected application containers.
  4. Rotate any API keys, database credentials, or cloud IAM tokens accessible to the Agno process if the application was exposed to untrusted external inputs prior to patching.

References


Read the full report for CVE-2026-35002 on our website for more details including interactive diagrams and full exploit analysis.

Top comments (0)