How to Exploit and Secure Python's eval: Bypass Tricks and Whitelist Defenses

This article explains how Python's eval can execute arbitrary code, demonstrates multiple bypass techniques—including __import__, __builtins__ manipulation, and object subclass exploitation—and shows how to safely restrict eval using whitelist globals or ast.literal_eval to prevent code injection and denial‑of‑service attacks.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
How to Exploit and Secure Python's eval: Bypass Tricks and Whitelist Defenses

Python's eval evaluates a string as an expression. Simple examples show that eval("2+3") returns 5 and that eval("[x for x in range(9)]") produces a list of numbers 0‑8.

If the built‑in os module is available, eval("os.system('whoami')") can execute shell commands. Although eval cannot directly perform import, the exec function can, and eval can import modules via __import__, e.g., eval("__import__('os').system('whoami')").

In real applications, developers often use eval or exec to dynamically load user‑selected modules (such as different crawlers in a web service). If user input is not properly sanitized, this creates severe security vulnerabilities.

To mitigate risks, the recommended practice is to limit the functions available to eval by providing explicit globals and locals dictionaries. For example, allowing only the abs function:

eval('abs(-20)', {'abs': abs}, {'abs': abs})  # returns 20

Attempting to call os.system with the same whitelist raises a NameError because os is not defined.

However, attackers can bypass these restrictions. By setting __builtins__ to None they may think they have blocked access, but __builtin__ is an alias to the same object, and the original built‑ins can still be reached. Using object subclass discovery, one can locate dangerous classes such as zipimporter and load external modules:

[x for x in ().__class__.__bases__[0].__subclasses__() if x.__name__ == "zipimporter"][0]('/path/to/configobj.egg').load_module('configobj').os.system('whoami')

Similar techniques work with modules like urllib, urllib2, or setuptools, which also expose os.

Denial‑of‑service attacks are also possible. By crafting a payload that creates a code object with an empty stack and executes a malicious string (e.g., "KABOOM"), the Python interpreter can crash:

eval('(lambda fc=(lambda n:[c for c in __builtins__.__dict__.values() if c.__name__==n][0]):fc("function")(fc("code")(0,0,0,0,"KABOOM",(),(),(),"","",0,""),{})()', {'__builtins__':None})

The interpreter aborts, resulting in a service outage.

In summary, merely clearing built‑in modules is insufficient. The most reliable defense is to construct a strict whitelist of allowed names or, even better, replace eval with ast.literal_eval for safe evaluation of literals.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PythonSecurityWhitelistCode Injectionevalpayload
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.