Summary
A sandbox escape in heym's expression engine allows authenticated users to bypass intended expression restrictions and execute arbitrary Python code. Crafted workflow expressions can abuse dunder attribute access and resolver behavior to invoke operating-system commands as the backend process.
Affected context
The vulnerability occurs in heym deployments before version 0.0.91 when authenticated users can create or modify workflows that use the expression engine. Risk is concentrated in the DotList map/filter implementation and fallback resolver, where expression evaluation may expose Python internals or dangerous runtime objects.
Exploit preconditions
- Attack surface: Workflow expression evaluation in the heym backend
- Required access: An authenticated account with permission to create or modify workflows or expressions
- Trigger point: Evaluation of crafted item expressions or fallback-resolver expressions
- Why exploitation is possible: Dunder attribute access and resolver behavior can expose objects such as
os.system, allowing attacker-controlled expressions to reach Python command-execution functionality
Why this happens
The underlying flaw is insufficient isolation between a restricted expression language and the Python runtime.
Expression paths involving DotList map/filter operations and the fallback resolver permit access to special attributes or objects that should remain inaccessible. This maps to CWE-94: Improper Control of Generation of Code, because attacker-controlled expression content can cause the application to generate or invoke executable Python behavior rather than remain limited to safe data operations.
Potential impact
- Execution of arbitrary commands with the backend process's privileges
- Compromise of application data and workflow integrity
- Exposure or modification of secrets accessible to the backend
- Lateral movement into connected services or infrastructure
- Service disruption, data tampering, or supply-chain manipulation
General mitigation guidance
Mitigation generally focuses on enforcing a genuinely isolated expression language and reducing the trust granted to workflow authors.
Common defensive patterns include:
- Replacing general Python-compatible evaluation with an allowlisted expression grammar
- Blocking dunder names, attribute traversal, imports, callable objects, and runtime escape paths
- Applying the same validation rules consistently to map/filter item expressions and fallback resolution
- Executing workflow evaluation in a separately confined, least-privileged process when isolation is required
- Limiting authenticated users' ability to create or modify executable workflow content
- Restricting backend credentials, filesystem access, and network permissions according to least privilege
- Treating workflow definitions as untrusted input and validating them before execution
How teams detect issues like this
Organizations can look for:
- Static-analysis findings involving dynamic evaluation, reflective attribute access,
getattr, dunder names, and command-execution APIs - Code-review signals showing expression resolvers returning arbitrary Python objects or callables
- Tests that attempt to access special attributes, imports, builtins, subprocess interfaces, or operating-system APIs
- Runtime audit events for unusual workflow changes, expression failures, child-process creation, and unexpected command execution
- Policy enforcement that restricts workflow authorship and requires review for changes to executable expressions
Automated code-review and security-analysis tools can help identify dangerous evaluation paths, but should be supplemented with sandbox-boundary testing.

