Skip to content

Replace unsafe eval() usage in Calculator tool #469

@arJ-V

Description

@arJ-V

PR: #470

Problem:

The Calculator tool in gemma/gm/tools/_calculator.py uses eval() to evaluate mathematical expressions, which is a security risk. eval() can execute arbitrary Python code, making it vulnerable to code injection attacks.
Current code:

return eval(expression, _OPS) # pylint: disable=eval-used

Solution:
Replace eval() with a safe AST-based expression evaluator that:
Parses expressions using Python's ast module
Only allows safe AST node types (Expression, BinOp, UnaryOp, Constant, Name, Call)
Restricts function calls to operations defined in _OPS dictionary
Rejects unsafe operations (attribute access, imports, comprehensions, etc.)

Implementation:
Added _SafeEvaluator class that extends ast.NodeVisitor to safely traverse and evaluate AST nodes
Added _safe_eval() helper function for parsing and error handling
Updated Calculator.call() to use the safe evaluator instead of eval()
This maintains backward compatibility while removing the security vulnerability. All existing mathematical operations (+, -, , /, functions from _OPS) continue to work as before.

review PR for implementation details

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions