T09 · Insecure Skill Coding Practices
- Location
SKILL.md:729- Finding
Unauthenticated Webhooks Can Trigger Agent Pause or Termination
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:729-815
Vulnerability Type: Missing authentication and integrity verification for control webhooks
Risk Level: HighVulnerable Code
python from flask import Flask, request, jsonify import logging app = Flask(__name__) logger = logging.getLogger("finops_alerts") @app.route("/alerts/warning", methods=["POST"]) def handle_warning(): """75% budget consumed -- log and notify Slack.""" payload = request.json agent_id = payload.get("agent_id") spent_pct = payload.get("spent_pct") remaining = payload.get("remaining_budget") logger.warning( f"BUDGET WARNING: {agent_id} at {spent_pct}% " f"(${remaining} remaining)" ) notify_slack( channel="#agent-finops", message=f"Agent {agent_id} has consumed {spent_pct}% of its daily budget. " f"${remaining} remaining.", ) return jsonify({"status": "acknowledged"}) @app.route("/alerts/critical", methods=["POST"]) def handle_critical(): """90% budget consumed -- pause the agent.""" payload = request.json agent_id = payload.get("agent_id") logger.critical( f"BUDGET CRITICAL: {agent_id} at {payload.get('spent_pct')}%. " f"Pausing agent." ) pause_agent(agent_id) notify_slack( channel="#agent-finops", message=f"CRITICAL: Agent {agent_id} paused at 90% budget.", ) return jsonify({"status": "agent_paused"}) @app.route("/alerts/exhausted", methods=["POST"]) def handle_exhausted(): """100% budget consumed -- kill the agent process.""" payload = request.json agent_id = payload.get("agent_id") logger.error( f"BUDGET EXHAUSTED: {agent_id}. Terminating." ) kill_agent(agent_id) notify_slack( channel="#agent-finops", message=f"EXHAUSTED: Agent {agent_id} terminated. Budget fully consumed.", ) return jsonify({"status": "agent_terminated"}) def pause_agent( ...[truncated 2763 chars]- Remediation
View remediation
Remediation Suggestions
- Verify a provider-generated HMAC or Ed25519 signature over the unmodified request body before parsing or acting on it.
- Compare signatures using a constant-time operation and reject requests with absent, malformed, or invalid signatures.
- Require a signed timestamp and enforce a narrow acceptance window.
- Store and reject previously processed event IDs or nonces to prevent replay.
- Bind each webhook registration to its expected agent and event type; do not permit an arbitrary body field to select the control target.
- Validate the JSON schema and allowlist known agent identifiers and threshold values.
- Place the endpoint behind TLS, authentication, network access controls, and rate limiting.
- Separate notification endpoints from destructive control actions. Queue authenticated events for policy evaluation rather than directly terminating processes in the HTTP handler.
- Record signature-validation results and event IDs in tamper-resistant audit logs.
- Add tests covering forged signatures, stale timestamps, duplicate events, unknown agents, malformed payloads, and cross-agent substitution.
