Back to skill

Security audit

calculator-py

Security checks for vulnerabilities and agentic risk

Overview

This calculator is purpose-aligned, but it needs review because crafted math expressions can execute local commands despite the documentation claiming they cannot.

Review before installing. Use this only in a tightly isolated environment and do not let untrusted documents, web pages, or prompts supply expressions to it. The unsafe eval implementation should be replaced with a real restricted math parser before normal agent use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/calc.py:116
Finding

Arbitrary Code Execution Through Unsafe Mathematical Expression Evaluation

Content
View full analysis
float: """Evaluate a math expression using numpy.""" import numpy as np safe_ns = { "sin": np.sin, "cos": np.cos, "tan": np.tan, "asin": np.arcsin, "acos": np.arccos, "atan": np.arctan, "sinh": np.sinh, "cosh": np.cosh, "tanh": np.tanh, "sqrt": np.sqrt, "cbrt": np.cbrt, "log": np.log, "log2": np.log2, "log10": np.log10, "exp": np.exp, "abs": np.abs, "floor": np.floor, "ceil": np.ceil, "round": np.round, "pi": np.pi, "e": np.e, "inf": np.inf, "nan": np.nan, "np": np, } try: result = eval(expr, {"__builtins__": {}}, safe_ns) return float(result) ``` Additional user-controlled expression evaluation occurs in the mpmath, optimization, integration, and ODE paths at `scripts/calc.py:150-182`, `scripts/calc.py:482-496`, `scripts/calc.py:542-556`, and `scripts/calc.py:570-590`. ### Technical Analysis Removing `__builtins__` from the globals dictionary does not turn Python `eval()` into a secure expression parser. Python expressions still support attribute access, dictionary subscripting, calls, and traversal through objects supplied in the local namespace. The NumPy evaluator directly exposes the NumPy module as `np`. Python modules normally retain a reference to their builtins dictionary through `__builtins__`. A malicious expression can therefore traverse from `np` to the import function, import a system module, and invoke operating-system functionality. Conceptually, the escape follows this chain: ```text np -> np.__builtins__ -> ["__import__"] -> import an operating-system module -> invo ...[truncated 1938 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:14
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (13)

eval() call detected

High
Category
Dangerous Code Execution
Confidence
88% confidence
Finding

Using eval() to parse bounds is risky even though the local namespace is small, because Python eval is not a robust sandbox and may still be abused through language features or implementation quirks. This input channel is narrower than the expression evaluators, so practical exploitability may be lower, but it still introduces unnecessary code-execution exposure for untrusted input.

Content

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

python
# Retry with math constants for expressions like [0,pi]
        safe_ns = {"pi": math.pi, "e": math.e, "inf": math.inf}
        try:
            data = eval(s, {"__builtins__": {}}, safe_ns)
        except Exception:
            error_exit(
                f"Invalid bounds: {s}", "Use format [lo,hi], e.g. [-10,10] or [0,pi]"

eval() call detected

High
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

This code evaluates attacker-controlled expressions with Python eval() in a namespace that still exposes powerful Python objects such as the imported numpy module and callable objects. Even with builtins removed, Python introspection and object traversal can often be abused to escape the sandbox, leading to arbitrary code execution or at minimum denial of service via expensive computations. In an agent skill that is intended to process user/agent-provided math expressions, this is especially dangerous because untrusted input is the normal operating mode.

Content

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

python
"np": np,
    }
    try:
        result = eval(expr, {"__builtins__": {}}, safe_ns)
        return float(result)
    except Exception as e:
        error_exit(

eval() call detected

High
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

This arbitrary-precision path also uses eval() on untrusted input, exposing mpmath objects and functions to the expression. Restricting builtins is not a sufficient sandbox for Python eval, and the available objects may enable sandbox bypasses or allow pathological computations that consume extreme CPU and memory. Because this skill advertises expression evaluation as a primary feature, the attack surface is directly reachable.

Content

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

python
"mp": mpmath.mp,
    }
    try:
        result = eval(expr, {"__builtins__": {}}, safe_ns)
        return mpmath.nstr(result, precision)
    except Exception as e:
        error_exit(

eval() call detected

High
Category
Dangerous Code Execution
Confidence
94% confidence
Finding

The optimizer evaluates a user-supplied function string using eval() for every solver callback. This creates code-execution risk from untrusted expressions and also makes denial-of-service easier because the expression may be invoked many times by optimization routines. In an agent environment, a malicious prompt or upstream tool input could weaponize this entry point.

Content

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

python
"exp": math.exp,
            "abs": abs,
        }
        return eval(expr_str, {"__builtins__": {}}, ns)

    op = args.operation
    try:

eval() call detected

High
Category
Dangerous Code Execution
Confidence
94% confidence
Finding

The integration subcommand evaluates user-controlled expressions with eval() inside the numerical integrator callback. As with the other eval paths, this can permit sandbox escape or at least computational abuse, and repeated callback execution amplifies the impact. The calculator context increases danger because evaluating arbitrary user expressions is a first-class advertised capability.

Content

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

python
"exp": math.exp,
            "abs": abs,
        }
        return eval(expr_str, {"__builtins__": {}}, ns)

    op = args.operation
    try:

eval() call detected

High
Category
Dangerous Code Execution
Confidence
94% confidence
Finding

The ODE solver evaluates a user-supplied differential expression with eval() during repeated solver callbacks. This combines the same code-execution concerns as other eval uses with potentially amplified denial-of-service impact due to many evaluations during integration. Since the skill is designed to accept arbitrary equations, an attacker can directly reach this dangerous path.

Content

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

python
"exp": math.exp,
                    "abs": abs,
                }
                return [eval(ode_expr, {"__builtins__": {}}, ns)]

            x_span = (bounds[0], bounds[1])
            x_eval = [bounds[0] + (bounds[1] - bounds[0]) * i / 20 for i in range(21)]

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

该文档从标题到正文全部使用中文,且没有提供其他语言选项、用户选择机制或对语言限制的明确说明。根据规则,强制特定语言而未取得用户选择/同意,属于自然语言层面的语言/地区政策问题。

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill invokes local shell commands and Python scripts but does not declare any tool scope such as permissions or allowed-tools. In an agent environment, this can cause overbroad execution authority, making it easier for the skill to be used in unintended ways or combined with untrusted inputs to run local code.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest description and the entire user-facing documentation are written exclusively in Chinese, with no indication that the skill can operate in other languages or that this locale restriction is intentional. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/test_calc.py (reported line 596)May include surrounding context.

python
"""Run a single test case. Returns (passed, message)."""
    cmd = [sys.executable, str(CALC_PATH)] + args
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
    except subprocess.TimeoutExpired:
        return False, f"TIMEOUT after 30s"
    except Exception as e:

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
75% confidence
Finding

Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Content

Scanner excerpt · scripts/test_calc.py (reported line 629)May include surrounding context.

python
def main():
    args_parser = __import__("argparse").ArgumentParser(
        description="Calculator skill test suite"
    )
    args_parser.add_argument(

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

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

python
}
            scipy_name = dist_map.get(dist_name, dist_name)
            try:
                dist = getattr(sp_stats, scipy_name)
            except AttributeError:
                error_exit(
                    f"Unknown distribution: {dist_name}",

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

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

python
}
            scipy_name = dist_map.get(dist_name, dist_name)
            try:
                dist = getattr(sp_stats, scipy_name)
            except AttributeError:
                error_exit(
                    f"Unknown distribution: {dist_name}",

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

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