Back to skill

Security audit

Calc Tool

Security checks for vulnerabilities and agentic risk

Overview

This calculator skill is simple, but its implementation runs user-supplied calculator input as unrestricted Python code.

Do not install or use this version in automated workflows or with expressions from other people. It should be revised to use a strict math expression parser, reject imports and attribute access, and either implement or remove the claimed unit conversion feature.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
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 unrestricted eval()
Risk Level: Critical

Vulnerable 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 unrestricted eval() 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

  1. An attacker supplies a crafted calculator expression through the required CLI argument.

  2. main() reads the value from args.expression.

  3. main() passes the attacker-controlled value to evaluate().

  4. evaluate() performs textual substitutions but does not validate the resulting expression.

  5. eval(expr) executes the expression as Python code.

  6. For example, an attacker can invoke:

    bash
    calc-tool "__import__('os').system('id')"
    
  7. Python imports the os module 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's ast module 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, and log directly to trusted callables.
  • Allow only explicitly approved constants such as pi and e.
  • 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.

Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The code does align with much of the declared purpose: it is a command-line calculator that evaluates arithmetic expressions and supports trig and other math functions such as sqrt, log, ln, floor, ceil, abs, and pow. However, the description explicitly claims unit conversion capability, and there is no unit conversion logic in the supplied code. That is a material description-behavior mismatch. There are no evident undeclared external resource accesses or unrelated triggers in this chunk.

Content

No source excerpt is available for this finding.

eval() call detected

High
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

The calculator passes user-controlled input directly to Python's eval() with default scope, which allows arbitrary Python expression execution rather than only arithmetic. An attacker can invoke builtins, import modules, read files, or execute system commands, making this a direct code execution issue.

Content

Scanner excerpt · scripts/calc.py (reported line 33)May include surrounding context.

python
expr = expr.replace('^', '**')
    
    try:
        result = eval(expr)
        return result
    except Exception as e:
        raise ValueError(f"Invalid expression: {e}")

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The implementation claims to be a calculator, but in practice it evaluates arbitrary Python syntax after a few string substitutions. That means expressions can escape the intended math-only domain and perform actions unrelated to calculation, including code execution and data access.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

Arbitrary code execution is not necessary for a calculator skill, so exposing it greatly expands attack surface without functional justification. In this skill context, the dangerous capability is especially unjustified because users would reasonably expect only arithmetic, trig, and conversions, not execution of Python code.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill executes user-supplied expressions as Python code without warning, which creates a severe trust mismatch: users believe they are entering math, but the program actually runs code. Lack of disclosure does not mitigate the core issue and can increase practical risk because unsafe inputs may be supplied in automation or shared workflows.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/calc.py:33