Die Python-Funktion eval(expression) parst einen String als Python-Ausdruck und wertet ihn aus. Das macht sie extrem mächtig — und extrem gefährlich. Mit eval() lassen sich Strings in beliebigen Python-Code verwandeln, was sie zur klassischen Schwachstelle für Code-Injection macht. Für sichere Auswertung von Literalen ist ast.literal_eval() fast immer die richtige Alternative.

Einleitung

eval() parst einen String als Expression (also einen Ausdruck, keine Statement-Liste) und wertet ihn im aktuellen Scope aus. Damit lassen sich:

  • Mathematische Formeln aus String-Eingaben rechnen.
  • Konfiguration in Python-Syntax laden.
  • Dynamisch Attribute oder Funktionen aufrufen.

Das Sicherheitsproblem: Solange die Eingabe komplett unter eigener Kontrolle ist, ist eval() ok. Sobald sie aus User-Input, Netz, Datei oder DB kommt, ist sie lebensgefährlich:

eval("__import__('os').system('rm -rf /')")

Wer nur Literale auswerten will — also Listen, Dicts, Tupel, Strings, Zahlen, Booleans — nutzt ast.literal_eval(), das nur diese erlaubt.

Syntax

Python Syntax
eval(expression, globals=None, locals=None)
Parameter
expression

Ein String (oder ein per compile() vorbereitetes Code-Objekt) mit einem Python-Ausdruck.

globals

(Optional) Dict mit globalen Variablen. Default: aktuelle Globals.

locals

(Optional) Dict mit lokalen Variablen. Default: aktuelle Locals.

Rückgabewert

Das Ergebnis des ausgewerteten Ausdrucks. Bei Syntax-Fehlern: SyntaxError, bei Laufzeit-Fehlern: die jeweilige Exception.

Beispiele

Einfacher Ausdruck

eval() hat Zugriff auf den aktuellen Scope — Variablen werden korrekt aufgelöst:

Python Beispiel
x = 10
print(eval("x * 2 + 5"))
Output
25

Mit eingeschränkten Globals

Mit explizitem globals lässt sich der Zugriff einschränken — ein leeres Dict deaktiviert alle Builtins außer __builtins__:

Python Beispiel
# Eigene globale Symbole bereitstellen, alles andere blockieren
safe_globals = {"__builtins__": {}, "pi": 3.14159}
result = eval("pi * 2", safe_globals)
print(result)
Output
6.28318

Sicher: ast.literal_eval

Für Literale ist ast.literal_eval() der idiomatische, sichere Ersatz — er parst nur Datenstrukturen, keine Funktionsaufrufe:

Python Beispiel
from ast import literal_eval

print(literal_eval("[1, 2, 3]"))
print(literal_eval("{'a': 1, 'b': 2}"))
print(literal_eval("(3.14, 'pi', True)"))

# Schlägt fehl bei Ausdrücken oder Funktionsaufrufen:
try:
    literal_eval("__import__('os').system('ls')")
except (ValueError, SyntaxError) as e:
    print("Blockiert:", type(e).__name__)
Output
[1, 2, 3]
{'a': 1, 'b': 2}
(3.14, 'pi', True)
Blockiert: ValueError

Praktische Beispiele

Mini-Taschenrechner (mit Vorsicht)

Wer eine Formel-Eingabe baut, sollte mindestens den Ausdruck per compile() validieren — eval() direkt mit User-Input ist nie eine gute Idee:

Python Beispiel
import math

ALLOWED_NAMES = {k: getattr(math, k) for k in dir(math) if not k.startswith("_")}
ALLOWED_NAMES["abs"] = abs
ALLOWED_NAMES["round"] = round

def calc(expr: str):
    code = compile(expr, "<input>", "eval")
    for name in code.co_names:
        if name not in ALLOWED_NAMES:
            raise NameError(f"'{name}' nicht erlaubt")
    return eval(code, {"__builtins__": {}}, ALLOWED_NAMES)

print(calc("sqrt(2) * pi"))
Output
4.442882938158366

Konfig aus Python-Datei laden — besser nicht eval()

Statt eine Python-Datei zu evaluieren, lieber JSON oder TOML nutzen — sicher, portabel, sprachunabhängig:

Python Beispiel
# SCHLECHT:
config = eval(open("config.py").read())

# GUT:
import json
with open("config.json") as f:
    config = json.load(f)

# ODER, falls Python-Literal-Syntax gewünscht:
from ast import literal_eval
with open("config.py") as f:
    config = literal_eval(f.read())

Praktische Hinweise

  • NIEMALS eval() auf User-Input — Code-Injection ist Standard-Beute.
  • ast.literal_eval() ist der sichere Default für Datenstruktur-Parsing.
  • globals und locals einschränken hilft kaum — Angreifer haben elaborierte Wege, an __builtins__ heranzukommen.
  • Performance: eval() hat Parsing-Overhead — für mehrfache Aufrufe das Code-Objekt mit compile() cachen.
  • Verwandte Funktionen: exec() (Statements ausführen), compile() (vorab kompilieren), ast.literal_eval() (sicher).
/ Weiter

Zurück zu Builtin Functions

Zur Übersicht