v8.1.19 - Security fix: eval() sandbox escape in QASMParser
Security
Fixed a code-execution vulnerability affecting every previously published version.
QASMParser's gate-parameter evaluator (_eval_param, used for expressions like rx(...), p(...)) called eval() with {'__builtins__': {}} as its only protection. That blocks direct builtin names (open, len, __import__, ...) but does not block attribute/dunder traversal of the live Python object graph (().__class__.__bases__[0].__subclasses__()...), which needs no builtin name at all — from there, any class loaded in the process is reachable, including ones whose __globals__ reference os/subprocess.
Verified directly: a crafted gate-parameter expression, passed through the public QASMParser.parse() entry point — the primary entry point of the whole library (dashboard, Qiskit/PennyLane interop bridge, direct usage) — executed successfully. Anyone parsing untrusted QASM text was affected.
Fixed by replacing eval() with an AST node-type whitelist evaluator (_eval_ast_node) — only literals, +-*/%** arithmetic, and calls/lookups restricted to the documented math environment (pi, sin, sqrt, ...) are ever evaluated; an attribute access is structurally impossible to reach, not blocklisted. _resolve_int_expr (QASM3 for-loop bounds) used the same pattern but was already protected by a separate pre-filter — verified safe before this fix — now migrated to the same evaluator for consistency, so no raw eval()/exec() remains anywhere in the codebase.
No behavior change for legitimate expressions — every previously-supported parameter syntax evaluates identically.
If you parse QASM text from any source you don't fully trust, upgrade immediately.