CVE-2026-102734 Overview
CVE-2026-102734 is a sandbox escape vulnerability in asteval, a Python expression evaluator designed for restricted execution. Versions prior to 1.0.9 expose a reachable ctypes type when numpy is enabled, allowing attacker-controlled expressions to bypass the interpreter's safety controls. The safe_getattr function blocks the ctypes module directly but fails to filter reachable ctypes type objects. Attribute assignments compound the issue by using unfiltered setattr instead of safe_setattr. The flaw is tracked under [CWE-693: Protection Mechanism Failure].
Critical Impact
An attacker-controlled expression can derive an address with id, read process memory through from_address, and write through attribute assignment, enabling sandbox escape, code execution, secret disclosure, or process crash.
Affected Products
- asteval Python package versions prior to 1.0.9
- Deployments running asteval with numpy support enabled
- Applications relying on asteval as a restricted expression sandbox
Discovery Timeline
- 2026-10-13 - CVE CVE-2026-102734 published to NVD
- 2026-10-13 - Last updated in NVD database
Technical Details for CVE-2026-102734
Vulnerability Analysis
asteval is marketed as a safe alternative to Python's built-in eval, restricting access to dangerous builtins and modules. The default Interpreter with numpy enabled unintentionally exposes a ctypes type object through numpy's internal references. While safe_getattr denies direct access to the ctypes module name, it does not inspect objects that transitively resolve to ctypes types already present in the evaluator namespace.
Attackers who reach a ctypes type can call from_address to construct a Python object pointing at an arbitrary memory location. Combined with the unfiltered setattr used for attribute writes, this provides a primitive to both read and corrupt arbitrary process memory from inside a supposedly sandboxed expression.
Root Cause
The root cause is incomplete enforcement of the protection mechanism. safe_getattr blocks module-level names but not reachable type objects, and attribute assignment paths bypass safe_setattr by invoking the raw setattr builtin. The sandbox denylist is thus incomplete across both read and write code paths in asteval/astutils.py.
Attack Vector
Exploitation requires local access and user interaction, typically delivery of a crafted expression to an application that evaluates untrusted input through asteval. The attacker uses id(obj) to obtain the address of a controlled Python object, then invokes ctypes_type.from_address(addr) to materialize a view into that memory. Attribute assignment on the resulting object writes attacker-chosen bytes to arbitrary locations, enabling sandbox escape, in-process code execution, exfiltration of secrets, or process termination.
# Patch excerpt from asteval/astutils.py (sanitized)
# Source: https://github.com/lmfit/asteval/commit/a3e56e7f8ed567a4817684d94213b290359077b4
# This is a necessary API but it's undocumented and moved around
# between Python releases
-try:
- from _string import formatter_field_name_split
-except ImportError:
- def formatter_field_name_split(x):
- return x._formatter_field_name_split()
-
+from _string import formatter_field_name_split
MAX_EXPONENT = 10000
The full fix in version 1.0.9 extends safe_getattr to filter reachable ctypes type objects and routes attribute assignments through safe_setattr. See the GitHub Security Advisory GHSA-9w56-46f6-3qhx for additional detail.
Stop Remote Code Execution Before It Runs
Singularity™ Endpoint detects and blocks exploit attempts at machine speed, including zero-days and novel attack techniques.
Stop Exploit AttemptsDetection Methods for CVE-2026-102734
Indicators of Compromise
- Expressions submitted to asteval containing references to from_address, ctypes, or chained attribute access against numpy internals.
- Unexpected process crashes or segmentation faults in Python services that embed asteval.
- Anomalous memory read patterns or secret material appearing in logs produced by asteval-backed services.
Detection Strategies
- Audit application logs for user-supplied expressions passed to asteval.Interpreter.eval and flag use of from_address, id, or attribute writes against unexpected object types.
- Perform software composition analysis to identify asteval versions earlier than 1.0.9 across Python environments.
- Add static analysis rules that detect asteval usage with use_numpy=True on untrusted input.
Monitoring Recommendations
- Monitor Python application telemetry for unexplained crashes, abnormal memory growth, or unexpected native library loads.
- Alert on child process creation or outbound network connections originating from processes that normally only evaluate math expressions.
- Track dependency manifests (requirements.txt, pyproject.toml, Pipfile.lock) in CI for pinned versions of asteval < 1.0.9.
How to Mitigate CVE-2026-102734
Immediate Actions Required
- Upgrade asteval to version 1.0.9 or later in all affected environments.
- Inventory services that accept user-supplied expressions and evaluate them with asteval, then prioritize patching those exposed to untrusted input.
- Rotate secrets accessible to any process that evaluated untrusted expressions through a vulnerable asteval version.
Patch Information
The fix is published in asteval 1.0.9 and merged via Pull Request #153. The remediation extends safe_getattr to deny reachable ctypes type objects and routes attribute assignment through safe_setattr. Review the upstream commit for the complete change set.
Workarounds
- Disable numpy support in the asteval interpreter when numpy features are not required by the application.
- Treat all input to asteval as untrusted and apply strict input validation and allowlists before evaluation.
- Isolate services that evaluate untrusted expressions in least-privilege sandboxes or containers with no access to sensitive secrets.
# Upgrade asteval to the patched release
pip install --upgrade 'asteval>=1.0.9'
# Verify installed version
python -c "import asteval; print(asteval.__version__)"
# If numpy support is not required, instantiate without it
# python -c "from asteval import Interpreter; aeval = Interpreter(use_numpy=False)"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

