T09 · Insecure Skill Coding Practices
- Location
scripts/script.sh:90- Finding
Arbitrary Command Execution Through Unsafe Python Heredoc Interpolation
- Content
View full analysis
Vulnerability Details
File Location:
scripts/script.sh, lines 90–97. The same unsafe pattern is repeated at lines 139–144, 225–231, 263–266, 318–322, 365–367, 410–413, and 433–435.
Vulnerability Type: Python code injection leading to arbitrary operating-system command execution
Risk Level: HighVulnerable Code
bash python3 << PYEOF import math # ... opt_type = "${opt_type}" S = float(${spot}) K = float(${strike}) r = float(${rate}) sigma = float(${vol}) days = float(${days}) T = days / 365.0Equivalent direct interpolation occurs in the other calculator functions:
bash target = float(${market_price}) premium = float(${premium}) rng = int(${range}) entry = float(${entry}) current = float(${current}) qty = float(${qty})Technical Analysis
The script inserts user-controlled command-line arguments directly into executable Python source generated through an unquoted heredoc. Although option types are validated, numeric arguments are not parsed or validated by Bash before being embedded.
Expressions passed to Python's
float()orint()are evaluated as Python code before conversion. Consequently, an argument does not need to be a numeric literal; it can be an arbitrary Python expression that performs a side effect and then returns a number.For example, a crafted spot-price argument could take the following form:
text __import__('os').system('id') or 100This produces Python source equivalent to:
python S = float(__import__('os').system('id') or 100)Python executes
os.system('id')before evaluating theor 100fallback and converting the result. Any command available to the invoking user can therefore be executed.The vulnerability affects all calculation commands that interpolate numeric input into inline Python:
price,greeks,iv,payoff,compare,chain,pnl, andbreakeven.Attack Path
...[truncated 1779 chars]
- Remediation
View remediation
Remediation Suggestions
Do not construct Python source by interpolating command-line arguments. Pass all values as data through Python positional arguments and use a single-quoted heredoc delimiter:
bash bs_price() { local opt_type="$1" spot="$2" strike="$3" rate="$4" vol="$5" days="$6" python3 - "$opt_type" "$spot" "$strike" "$rate" "$vol" "$days" <<'PYEOF' import math import sys opt_type = sys.argv[1] try: S = float(sys.argv[2]) K = float(sys.argv[3]) r = float(sys.argv[4]) sigma = float(sys.argv[5]) days = float(sys.argv[6]) except ValueError: raise SystemExit("ERROR: all numeric arguments must be valid numbers") if opt_type not in {"call", "put"}: raise SystemExit("ERROR: option type must be call or put") if not all(math.isfinite(value) for value in (S, K, r, sigma, days)): raise SystemExit("ERROR: numeric arguments must be finite") if S <= 0 or K <= 0: raise SystemExit("ERROR: spot and strike must be positive") if sigma <= 0 or days <= 0: raise SystemExit("ERROR: volatility and days must be positive") T = days / 365.0 # Continue calculation using the parsed values. PYEOF }Apply the same design to every affected function:
- Use
python3 - "$arg1" "$arg2" ...to transport values as arguments. - Use
<<'PYEOF'so Bash performs no interpolation within Python source. - Parse values exclusively from
sys.argv. - Reject invalid, infinite, and NaN values with
math.isfinite(). - Enforce domain constraints such as positive spot, strike, volatility, expiration, and sensible payoff ranges.
- Validate both minimum and maximum argument counts to prevent ambiguous input.
- Add regression tests using Python expressions and shell metacharacters as inputs, verifying that they are rejected and never executed.
- Use
