T09 · Insecure Skill Coding Practices
- Location
scripts/track.sh:86- Finding
Negative numeric inputs can corrupt persistent cost statistics and suppress threshold alerts
- Content
View full analysis
Vulnerability Details
File Location:
scripts/track.sh, lines 86-163
Vulnerability Type: Insufficient input validation and accounting-data integrity failure
Risk Level: MediumVulnerable Code:
bash record_call() { local input_tokens=0 local output_tokens=0 local cache_read=0 local cache_write=0 local model="unknown" local duration=0 while [ $# -gt 0 ]; do case "$1" in --input-tokens) input_tokens=$2 shift 2 ;; --output-tokens) output_tokens=$2 shift 2 ;; --cache-read-tokens) cache_read=$2 shift 2 ;; --cache-write-tokens) cache_write=$2 shift 2 ;; --model) model=$2 shift 2 ;; --duration) duration=$2 shift 2 ;; *) shift ;; esac done init_stats local cost=$(calculate_cost $input_tokens $output_tokens "$model") python3 - "$STATS_FILE" "$input_tokens" "$output_tokens" "$cache_read" "$cache_write" "$model" "$duration" "$cost" << 'PYEOF' import json import sys from datetime import datetime stats_file = sys.argv[1] input_tokens = int(sys.argv[2]) output_tokens = int(sys.argv[3]) cache_read = int(sys.argv[4]) cache_write = int(sys.argv[5]) model = sys.argv[6] duration = int(sys.argv[7]) cost = float(sys.argv[8]) try: with open(stats_file, 'r') as f: stats = json.load(f) stats['totalCalls'] += 1 stats['totalInputTokens'] += input_tokens stats['totalOutputTokens'] += output_tokens stats['totalCache ...[truncated 2802 chars]- Remediation
View remediation
Remediation Suggestions
- Require all token counts, cache counts, and durations to be decimal integers greater than or equal to zero.
- Verify that every option requiring a value has a following argument before accessing
$2. - Reject unknown options instead of silently ignoring them.
- Repeat validation in Python so the persistence boundary does not rely solely on shell validation.
- Reject negative or non-finite calculated costs before updating the statistics file.
- Apply reasonable upper bounds to prevent accidental or malicious records from creating implausibly large totals.
- Return a nonzero exit status when validation or persistence fails.
Example shell-side validation:
bash validate_nonnegative_integer() { local name="$1" local value="$2" if [[ ! "$value" =~ ^[0-9]+$ ]]; then echo "Invalid $name: expected a non-negative integer" >&2 exit 1 fi } validate_nonnegative_integer "input token count" "$input_tokens" validate_nonnegative_integer "output token count" "$output_tokens" validate_nonnegative_integer "cache read token count" "$cache_read" validate_nonnegative_integer "cache write token count" "$cache_write" validate_nonnegative_integer "duration" "$duration"Python should independently enforce the same invariant before modifying persistent state:
python values = { "input_tokens": input_tokens, "output_tokens": output_tokens, "cache_read": cache_read, "cache_write": cache_write, "duration": duration, } for name, value in values.items(): if value < 0: raise ValueError(f"{name} must be non-negative") if not math.isfinite(cost) or cost < 0: raise ValueError("cost must be finite and non-negative")
