Skip to content

Fix arbitrary code execution via eval() in calculator - #1

Open
devin-ai-integration[bot] wants to merge 1 commit into
masterfrom
devin/1784470121-fix-eval-rce
Open

Fix arbitrary code execution via eval() in calculator#1
devin-ai-integration[bot] wants to merge 1 commit into
masterfrom
devin/1784470121-fix-eval-rce

Conversation

@devin-ai-integration

Copy link
Copy Markdown

Summary

The calculator evaluated user-controlled expressions with Python's built-in eval() in four places (square, sqrt, perc, evaluate). Because the display expression is built from typed/pasted characters (and keyboard bindings feed straight into it), this is an arbitrary-code-execution sink — e.g. entering __import__("os").system(...) would run shell commands.

This PR replaces eval() with a new safe_eval() that parses the expression with ast.parse(..., mode="eval") and walks the tree, permitting only numeric literals and arithmetic operators (+ - * / // % ** and unary +/-). Anything else (names, calls, attribute access, subscripts) raises ValueError.

def safe_eval(expr):
    node = ast.parse(expr, mode="eval")   # SyntaxError -> ValueError
    # recurse: Constant(int/float only), BinOp/UnaryOp in allowlist
    # everything else -> ValueError("unsupported expression")

Call sites changed from eval(...) to safe_eval(...); evaluate() still wraps the call in try/except so invalid input shows Error as before.

Verified: 2+3*4→14, 9**0.5→3.0, 50*20/100→10.0 still compute; __import__("os").system("id"), open("x"), bare names, and multi-statement input are all rejected.

Scan notes

Other requested categories are not applicable to this repo — it's a standalone tkinter desktop app with no web server, database, network I/O, dependencies beyond the stdlib, or secrets. No SQL injection, CORS, debug endpoints, auth, or hardcoded credentials exist. The eval() RCE was the only critical finding.

Link to Devin session: https://app.devin.ai/sessions/26d1dbca8aab45edb08a50dc5852bbd4
Requested by: @martlyma

@martlyma martlyma self-assigned this Jul 19, 2026
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration

Copy link
Copy Markdown
Author

Test results — eval() → safe_eval() RCE fix

Tested by launching the tkinter calculator locally and driving it via on-screen buttons (arithmetic still works after the swap), plus a shell test proving safe_eval() rejects code-execution payloads.

  • It should compute 2 × 3 + 4 = 10 — passed (10)
  • It should compute √9 = 3.0 — passed (3.0)
  • It should compute 5² = 25 — passed (25)
  • It should compute 200 + 10% = 20 — passed (20.0)
  • It should block code execution in safe_evalpassed (payloads raise ValueError, nothing runs)
UI evidence: arithmetic computed through safe_eval
2 × 3 + 4 = 10 5² = 25
2x3+4 5squared
RCE fix evidence (shell)
sanity 2+3*4 = 14
BLOCKED: __import__("os").system("id")  -> ValueError unsupported expression
BLOCKED: open("/etc/passwd").read()      -> ValueError unsupported expression

Old eval() would have executed these.

Caveat: unrelated pre-existing bug — calc.py:22 loads calc3.png which isn't in the repo (repo has calculator.png), so launch crashes until fixed. I used a temporary copy to test; worth fixing separately.

No CI is configured on this repo. Session: https://app.devin.ai/sessions/26d1dbca8aab45edb08a50dc5852bbd4

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.

1 participant