T09 · Insecure Skill Coding Practices
- Location
scripts/calc.py:31- Finding
Arbitrary Code Execution Through Unrestricted Expression Evaluation
- Content
View full analysis
Vulnerability Details
File Location:
scripts/calc.py, line 31
Vulnerability Type: Python code injection through unrestrictedeval()
Risk Level: CriticalVulnerable Code:
python try: result = eval(expr) return result except Exception as e: raise ValueError(f"Invalid expression: {e}")Technical Analysis
The calculator accepts a user-controlled expression from the positional command-line argument and passes it to
evaluate(). At line 31, the transformed expression is evaluated using Python's unrestrictedeval()function.No safe globals or locals are supplied, and no parser or allowlist restricts input to numeric literals, arithmetic operators, and approved mathematical functions. Consequently, Python built-ins such as
__import__remain accessible. The earlier string substitutions do not provide a security boundary and can be bypassed by constructing valid Python expressions that do not depend on the advertised calculator syntax.Attack Path
-
An attacker supplies a crafted calculator expression through the required CLI argument.
-
main()reads the value fromargs.expression. -
main()passes the attacker-controlled value toevaluate(). -
evaluate()performs textual substitutions but does not validate the resulting expression. -
eval(expr)executes the expression as Python code. -
For example, an attacker can invoke:
bash calc-tool "__import__('os').system('id')" -
Python imports the
osmodule and executes the supplied operating-system command.
Impact Assessment
Successful exploitation provides arbitrary Python and operating-system command execution with the privileges of the calculator process. An attacker may read or modify files accessible to that user, disclose credentials or other sensitive data, destroy data, execute additional programs, and initiate network activity where permitted.
The vulnerabili ...[truncated 154 chars]
-
- Remediation
View remediation
Remediation Suggestions
Replace
eval()with a strict expression evaluator based on Python'sastmodule or a mature calculator parser.The evaluator should:
- Allow only numeric literals and explicitly supported unary and binary arithmetic operators.
- Map approved functions such as
sin,cos,sqrt, andlogdirectly to trusted callables. - Allow only explicitly approved constants such as
piande. - Reject imports, arbitrary names, attribute access, subscripting, comprehensions, lambdas, and calls to non-allowlisted functions.
- Enforce limits on expression length, nesting depth, exponent size, and computational complexity to reduce denial-of-service risk.
- Validate the precision argument and impose a reasonable upper bound.
- Add regression tests that verify rejection of payloads involving
__import__, attribute traversal, built-in access, file operations, and process execution.
Do not attempt to secure the current design using regular-expression filtering alone, because Python syntax offers numerous ways to bypass denylist-based controls.
