T09 · Insecure Skill Coding Practices
- Location
scripts/autoloop.py:159- Finding
Configured Cost Cap Does Not Reliably Enforce the Spending Limit
- Content
View full analysis
Vulnerability Details
File Location:
scripts/autoloop.py:159-164, 211-216, 269-291
Vulnerability Type: Inadequate resource and cost-limit enforcement
Risk Level: MediumVulnerable Code
python proc = subprocess.run(cmd, capture_output=True, text=True) duration = time.monotonic() - iter_start if proc.returncode != 0: state.last_failure_trace = proc.stderr.strip() or proc.stdout.strip() state.status = "error" result = { "target": target, "attempts": 0, "max_retries": 0, "final_decision": "error", "final_candidate_id": None, "final_artifact_path": None, "error": state.last_failure_trace, } return state, result result = _parse_orchestrator_output(proc.stdout, target) cost = _estimate_cost(duration)python # Update cost cost_val = cost if not dry_run else 0.0 state.total_cost_usd += cost_valpython def _estimate_cost(duration_seconds: float, result: dict[str, Any] | None = None) -> float: """Estimate cost from token usage if available, else duration heuristic.""" if result: summary_path = result.get("final_artifact_path") if summary_path: try: data = read_json(Path(summary_path)) input_tokens = data.get("total_input_tokens", 0) output_tokens = data.get("total_output_tokens", 0) if input_tokens > 0 or output_tokens > 0: cost = (input_tokens * 3.0 + output_tokens * 15.0) / 1_000_000 return round(cost, 4) except (OSError, KeyError, TypeError): pass return round(duration_seconds / 60.0 * 0.10, 4)Technical Analysis
The application checks the cumulative cost before beginning an iteration, but it does not reserve the maximum possible cost of that iteration or enforce a limit while the ...[truncated 1880 chars]
- Remediation
View remediation
Remediation Suggestions
- Collect authoritative token usage or provider billing data from every orchestrator run instead of relying primarily on elapsed time.
- Pass the parsed result to the estimator:
python result = _parse_orchestrator_output(proc.stdout, target) cost = _estimate_cost(duration, result) - Validate that the referenced summary artifact belongs to the current run before using its token counts.
- Before launching an iteration, reserve a conservative worst-case amount and refuse to start when the remaining budget cannot cover it.
- Where supported, propagate explicit token, request, and monetary limits to the downstream orchestrator or provider API.
- Add timeout and cancellation controls so a running iteration can be stopped when a resource threshold is reached.
- Clearly document whether
--max-costis a hard cap or an estimate. Rename it if strict enforcement cannot be provided. - Add tests proving that token-based accounting is used, that an iteration cannot start without sufficient remaining budget, and that a single run cannot silently exceed its allocated limit.
