Skip to content

Conversation

@K4TV
Copy link

@K4TV K4TV commented Aug 21, 2025

Description
Replace eval() with ast.literal_eval() to prevent code injection. This PR addresses the code injection vulnerability (CWE-94) identified in the function_message function where ‘eval()’ was being used to parse function arguments. The use of ‘eval()’ creates a vulnerability that could allow arbitrary code execution if an attacker could control the input message.

Changes Made:

  • Replaced all instances of eval() with ast.literal_eval() in interface.py
  • Added import ast where needed
  • Maintained existing functionality while improving security

How to test

  • create a test file with the following content:
import ast
 
def archival_memory_insert(content):
    print("Code inserted.")

def function_message(msg):
    if msg.startswith("Running "):
        function_args = msg[len("Running "):].strip()
        print(f"Detected function call: {function_args}")
        msg_dict = eval(function_args)  # this is where eval() is used

def function_message_literal(msg):
    if msg.startswith("Running "):
        function_args = msg[len("Running "):].strip()
        print(f"Detected function call - literal: {function_args}")
        msg_dict = ast.literal_eval(function_args)  # this is where ast.literal_eval() is used

if __name__ == "__main__":
    # test inputs
    test_input = "Running archival_memory_insert({'key': 'value'})"
    exploit_input = "Running archival_memory_insert(__import__('os').system('echo vulnerable'))"
    exploit_input2 = "Running archival_memory_insert(__import__('os').system('echo *'))"

    print("--------------- Testing eval() ---------------")
    print("eval() - DANGEROUS (executes code):")
    function_message(test_input)
    print("eval() - DANGEROUS (executes code):")
    function_message(exploit_input)
    print("eval() - DANGEROUS (executes code): \n")
    function_message(exploit_input2)

    print("\n----------Testing malicious input----------")
    print("literal_eval() - SAFE (blocks code):")
    try:
        function_message_literal(exploit_input)
    except ValueError as e:
        print(f"ValueError: {e}")
    
    try:
        function_message_literal(exploit_input2)
    except ValueError as e:
        print(f"ValueError: {e}")

run the test

python3 [test_file_name]

Have you tested this PR?
Yes these were the following results:

# test cases
--------------- Testing eval() ---------------
eval() - DANGEROUS (executes code):
Detected function call: archival_memory_insert({'key': 'value'})
Code inserted.
eval() - DANGEROUS (executes code):
Detected function call: archival_memory_insert(__import__('os').system('echo vulnerable'))
vulnerable
Code inserted.
eval() - DANGEROUS (executes code): 

Detected function call: archival_memory_insert(__import__('os').system('echo *'))
__init__.py __pycache__ clear_postgres_db.py code_inject.py config.py configs conftest.py constants.py data helpers integration_test_agent_tool_graph.py integration_test_async_tool_sandbox.py integration_test_batch_api_cron_jobs.py integration_test_batch_sdk.py integration_test_builtin_tools.py integration_test_chat_completions.py integration_test_composio.py integration_test_multi_agent.py integration_test_pinecone_tool.py integration_test_send_message.py integration_test_sleeptime_agent.py integration_test_summarizer.py integration_test_tool_execution_sandbox.py integration_test_voice_agent.py manual_test_many_messages.py manual_test_multi_agent_broadcast_large.py mcp pytest.ini sdk test_agent_files test_agent_serialization.py test_agent_serialization_v2.py test_base_functions.py test_cli.py test_client.py test_file_processor.py test_google_embeddings.py test_letta_agent_batch.py test_letta_request_schema.py test_llm_clients.py test_managers.py test_memory.py test_multi_agent.py test_optimistic_json_parser.py test_plugins.py test_provider_trace.py test_providers.py test_redis_client.py test_sdk_client.py test_server.py test_sources.py test_static_buffer_summarize.py test_stream_buffer_readers.py test_timezone_formatting.py test_tool_rule_solver.py test_tool_sandbox test_tool_schema_parsing.py test_tool_schema_parsing_files test_utils.py utils.py
Code inserted.

----------Testing malicious input----------
literal_eval() - SAFE (blocks code):
Detected function call - literal: archival_memory_insert(__import__('os').system('echo vulnerable'))
ValueError: malformed node or string on line 1: <ast.Call object at 0x7e7f6c71b450>
Detected function call - literal: archival_memory_insert(__import__('os').system('echo *'))
ValueError: malformed node or string on line 1: <ast.Call object at 0x7e7f6c71b4d0>

Related issues or PRs
#2613

Is your PR over 500 lines of code?
No

Additional context
ast.literal_eval() is much safer than eval() as it only evaluates literals and does not execute arbitrary code. This prevents malicious input from being executed as python code while still allowing the intended functionality of parsing dictionary arguments.

The files shown above are under the folder tests and for testing purposes our test file is named code_inject.py.

mattzh72 and others added 30 commits July 24, 2025 10:53
Co-authored-by: Kevin Lin <[email protected]>
Co-authored-by: Matthew Zhou <[email protected]>
Co-authored-by: Kian Jones <[email protected]>
Co-authored-by: Andy Li <[email protected]>
Co-authored-by: jnjpng <[email protected]>
Co-authored-by: Jin Peng <[email protected]>
Co-authored-by: Eric Ly <[email protected]>
Co-authored-by: Eric Ly <[email protected]>
Co-authored-by: Shubham Naik <[email protected]>
Co-authored-by: Shubham Naik <[email protected]>
carenthomas and others added 23 commits August 18, 2025 16:26
…okens for google reasoning models

Co-authored-by: Jin Peng <[email protected]>
@sarahwooders sarahwooders added the safe to test Lets CI tests which require secrets to be ran label Aug 22, 2025
@kianjones9 kianjones9 force-pushed the main branch 2 times, most recently from b6907a4 to ae775db Compare September 15, 2025 22:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to test Lets CI tests which require secrets to be ran

Projects

None yet

Development

Successfully merging this pull request may close these issues.