Skip to content

security: replace eval() with safe AST math evaluator in calculate reward#1279

Open
RaymondSeven wants to merge 1 commit intogoogle:mainfrom
RaymondSeven:fix/remove-eval-rce-reward-calculate
Open

security: replace eval() with safe AST math evaluator in calculate reward#1279
RaymondSeven wants to merge 1 commit intogoogle:mainfrom
RaymondSeven:fix/remove-eval-rce-reward-calculate

Conversation

@RaymondSeven
Copy link

@RaymondSeven RaymondSeven commented Mar 23, 2026

Resolves b/495205094

Summary

Replace the unsafe eval() call in calculate_reward() with a safe AST-based
mathematical expression evaluator. The eval() on line 192 of
tunix/rl/agentic/rewards/reward.py allowed arbitrary code execution via
crafted dataset inputs (e.g. task["question"] containing
__import__('os').system(...)).

Changes

tunix/rl/agentic/rewards/reward.py

  • Added _safe_eval_math() function that parses expressions into an AST and
    only evaluates ast.Constant (int/float), ast.BinOp, and ast.UnaryOp
    nodes with a whitelist of arithmetic operators
  • Replaced eval(expression) with _safe_eval_math(expression) in
    calculate_reward()
  • Removed the WARNING comment about eval() unsafety (no longer applicable)

tests/rl/agentic/rewards/reward_test.py

  • Added test_calculate_reward_rejects_code_injection with 5 parameterized
    payloads (__import__, eval(), open(), dunder class traversal)
  • All existing test_calculate_reward cases continue to pass

…ward

Replace the unsafe eval() call in calculate_reward() with a safe
AST-based mathematical expression evaluator that only permits numeric
literals and basic arithmetic operators (+, -, *, /, //, %, **).

The eval() call allowed arbitrary code execution via crafted dataset
inputs (e.g. task['question'] containing __import__('os').system(...)).
The new _safe_eval_math() function parses expressions into an AST and
walks only ast.Constant, ast.BinOp, and ast.UnaryOp nodes, raising
ValueError for anything else.

Also adds parameterized test cases verifying that code injection
payloads are safely rejected.

Bug: b/495205094
@google-cla
Copy link

google-cla bot commented Mar 23, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants