GHSA-9W56-46F6-3QHX

GHSA-9W56-46F6-3QHX is a medium-severity security vulnerability in asteval (pip), affecting versions < 1.0.9. It is fixed in 1.0.9.

Does this CVE actually affect you?

Kodem shows which CVEs are reachable and running in your applications, so you fix what's exploitable, not just what's listed.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Runtime intelligence, not another scanner.

Summary

asteval Sandbox Escape: arbitrary native memory read/write via numpy ctypes in default asteval Interpreter

With its default configuration (numpy enabled, import disabled), asteval's Interpreter lets an attacker-controlled expression obtain a raw arbitrary process-memory read and write primitive, without using import, any __dunder__ attribute, or eval/exec/getattr. Arbitrary in-process read/write is equivalent to arbitrary code execution and is a complete escape of the sandbox whose entire purpose is "untrusted string in, no arbitrary execution out." Any application that feeds untrusted input to asteval with numpy installed (the default) is affected.

Details

asteval's attribute filter (asteval/astutils.py: safe_getattr) blocks every __dunder__ name and blocks objects whose attribute value is identity-equal to one of the modules in UNSAFE_MODULES = {io, os, sys, ctypes}. The ctypes module entry was added recently (commit 9d9d430) and correctly blocks ndarray.ctypes._ctypes.

However, the module check is identity-only against the ctypes module. It does not cover ctypes type objects and their metaclass methods, which are reachable through numpy's ndarray.ctypes wrapper using only ordinary (non-dunder) attribute names:

zeros(1, dtype=int32).ctypes.shape._type_      ->  <class 'ctypes.c_long'>

ndarray.ctypes exposes .shape (a ctypes array) whose element type ._type_ is ctypes.c_long. None of ctypes, .shape, ._type_ is a dunder, none is in UNSAFE_ATTRS, and the returned value is a type, not the ctypes module, so safe_getattr permits all of them.

On that ctypes type, the metaclass method from_address is reachable (non-dunder, not in UNSAFE_ATTRS; it is not even listed by dir(), which is likely why it was missed):

  • Arbitrary read: c_long.from_address(addr).value reads 8 bytes at any address. id() (a permitted builtin) supplies arbitrary object addresses.
  • Arbitrary write: cell = c_long.from_address(addr); cell.value = X writes 8 bytes to any address. The write half rides asteval's unfiltered setattr in Interpreter.node_assign (the ast.Attribute branch performs setattr(self.run(node.value), node.attr, val) with no attribute-name check).

Root cause is two gaps:

  1. safe_getattr blocks the ctypes module but not ctypes types / metaclass methods (from_address, from_buffer, from_buffer_copy, in_dll, from_param) reachable via ndarray.ctypes ... ._type_.
  2. node_assign performs attribute writes (setattr) and deletes (delattr) with no attribute-name filtering.

This belongs to the known "numpy is a large attack surface" class (the docs already note open() read and ndarray.tofile() write), but this specific arbitrary memory read/write chain is undocumented and bypasses the most recent ctypes-module hardening. All previously reported escapes (CVE-2025-24359 / GHSA-3wwr-3g9f-9gc7, GHSA-vp47-9734-prjw, reduce/reduce_ex, classic __subclasses__ traversal) are patched on the current code; this one is live.

PoC

Self contained POC here: https://gist.github.com/thegr1ffyn/16b67c5f9b5339a7e2bdc91423ff09e3
Environment: pip install asteval numpy (verified on asteval 1.0.8, numpy 2.4.6, CPython 3.12.3; the chain is numpy-1.x/2.x robust). Default Interpreter (use_numpy=True, import disabled).

Minimal one-expression arbitrary read (reads 8 bytes at an attacker-chosen address):

zeros(1,dtype=int32).ctypes.shape._type_.from_address(id(zeros(1))).value

Minimal arbitrary write (writes 0x4142434445464748 to a chosen address; here our own array buffer, observed back through numpy):

a = zeros(2, dtype=int32)
cell = a.ctypes.shape._type_.from_address(a.ctypes.data)
cell.value = 0x4142434445464748        # -> a[0]=0x45464748, a[1]=0x41424344

A full self-contained script is attached (poc_asteval_ctypes.py); running it prints the recovered PyObject header of a private object (arbitrary read) and confirms a raw write landing at a chosen pointer (arbitrary write), all from a default, import-disabled interpreter.

Impact

Sandbox escape / protection-mechanism failure leading to arbitrary in-process native memory read and write (RCE-equivalent). Impact:

  • Disclosure of any data in the host process's address space (secrets, keys, other users' data).
  • Corruption of arbitrary memory -> control-flow hijack / arbitrary code execution and/or process crash (DoS).

Affected: any application that evaluates untrusted/attacker-influenced expressions with asteval while numpy is installed (the default). No authentication and no special configuration is required; import does not need to be enabled. Mitigation until patched: construct the interpreter with use_numpy=False.

GHSA-9W56-46F6-3QHX has a CVSS score of 5.5 (Medium). The vector is requires local access, no privileges required, and user interaction required. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (1.0.9); upgrading removes the vulnerable code path.

Affected versions

asteval (< 1.0.9)

Security releases

asteval → 1.0.9 (pip)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

Already deployed Kodem?

See it in your environmentNew to Kodem? Get a demo →

Remediation advice

Upgrade asteval to 1.0.9 or later to resolve this vulnerability.

Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.

Frequently Asked Questions

  1. What is GHSA-9W56-46F6-3QHX? GHSA-9W56-46F6-3QHX is a medium-severity security vulnerability in asteval (pip), affecting versions < 1.0.9. It is fixed in 1.0.9.
  2. How severe is GHSA-9W56-46F6-3QHX? GHSA-9W56-46F6-3QHX has a CVSS score of 5.5 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
  3. Which versions of asteval are affected by GHSA-9W56-46F6-3QHX? asteval (pip) versions < 1.0.9 is affected.
  4. Is there a fix for GHSA-9W56-46F6-3QHX? Yes. GHSA-9W56-46F6-3QHX is fixed in 1.0.9. Upgrade to this version or later.
  5. Is GHSA-9W56-46F6-3QHX exploitable, and should I be worried? Whether GHSA-9W56-46F6-3QHX is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  6. What actually determines whether GHSA-9W56-46F6-3QHX is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  7. How do I fix GHSA-9W56-46F6-3QHX? Upgrade asteval to 1.0.9 or later.

Stop the waste.
Protect your environment with Kodem.