Back to skill

Security audit

Expected Value Calculator

Security checks for vulnerabilities and agentic risk

Overview

This EV calculator is small and mostly purpose-aligned, but it needs review because its instructions place user-provided values into a shell command in a potentially unsafe way.

Review this before installing if the agent may process odds or probabilities copied from untrusted sources. Prefer a version that validates numeric inputs and invokes Python with structured arguments, or that performs the calculation directly without a shell command.

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

Warning
Location
SKILL.md:38
Finding

Potential Shell Command Injection Through Unsafe Placeholder Substitution

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 38–69
Vulnerability Type: Shell command injection through insufficiently constrained user input
Risk Level: Medium

The documented operation instructs an agent to invoke an inline Python program and replace ODDS and TRUE_PROB_PERCENT with values originating from the user:

bash
python3 -c "
import sys

odds_input = sys.argv[1]
true_prob = float(sys.argv[2]) / 100 if float(sys.argv[2]) > 1 else float(sys.argv[2])

# Convert to decimal odds
if odds_input.startswith('+'):
    decimal_odds = 1 + int(odds_input) / 100
elif odds_input.startswith('-'):
    decimal_odds = 1 + 100 / abs(int(odds_input))
elif odds_input.startswith('$') or odds_input.startswith('0.'):
    price = float(odds_input.replace('$', ''))
    decimal_odds = 1 / price
else:
    decimal_odds = float(odds_input)

implied_prob = 1 / decimal_odds
ev_per_dollar = true_prob * decimal_odds - 1
edge = true_prob - implied_prob

print(f'Offered odds: {odds_input} (decimal {decimal_odds:.3f})')
print(f'Implied probability: {implied_prob:.1%}')
print(f'Your true probability: {true_prob:.1%}')
print(f'Edge: {edge:+.1%}')
print(f'EV per \$1: {ev_per_dollar:+.4f}')
print(f'EV per \$100: {ev_per_dollar * 100:+.2f}')
print(f'Verdict: {\"✅ +EV — BET\" if ev_per_dollar > 0 else \"❌ -EV — PASS\"} ')
" "ODDS" "TRUE_PROB_PERCENT"

Technical Analysis

The Python code expects the odds and probability in sys.argv, but the surrounding skill documentation expresses execution as a shell command containing quoted placeholders. It does not require strict numeric validation before interpolation, a shell-free process API, or shell-safe argument encoding.

If an implementing agent performs direct textual replacement of ODDS or TRUE_PROB_PERCENT, malicious input containing a closing double quote followed by shell syntax can terminate the intended argument. The shell pro ...[truncated 1686 chars]

Remediation
View remediation

Remediation Suggestions

  1. Move the calculator into a standalone Python script rather than embedding it in a shell command.
  2. Invoke Python through a structured process API with an argument array and with shell execution disabled. For example, pass ["python3", "calculator.py", odds, probability] directly to the execution tool.
  3. Validate input before execution using strict allowlists:
    • Permit American odds only in forms such as +150 or -200.
    • Permit decimal odds only as a finite positive decimal number.
    • Permit Kalshi prices only as numeric values in the valid contract-price range.
    • Permit probability only as a finite numeric value in an explicitly documented range.
    • Reject quotes, whitespace-separated extra tokens, shell metacharacters, and trailing content.
  4. Perform parsing and range validation inside Python and return a controlled error for zero prices, non-finite values, malformed numbers, and out-of-range probabilities.
  5. If shell execution is unavoidable, use a platform-appropriate escaping routine for every argument and never interpolate raw user input into executable command text.
  6. Add regression tests using inputs containing quotes, command separators, substitutions, newlines, and malformed numeric values to verify that none are interpreted by a shell.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (1)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest description says to use the skill when asked about expected value, EV, whether a bet is worth it, +EV opportunities, or breakeven probability, but it does not define clear boundaries or exclusions. Phrases like 'whether a bet is worth it' and '+EV opportunities' are broad natural-language formulations that could overlap with many ordinary betting discussions and cause unintended invocation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.