T09 · Insecure Skill Coding Practices
- Location
SKILL.md:970- Finding
Unvalidated Caller-Controlled Escrow Release Amount
- Content
View full analysis
dict: """Release a specific milestone payment from escrow.""" result = execute("release_escrow", { "escrow_id": task.escrow_id, "amount_usd": str(amount_usd), "release_type": "partial", "reason": f"Milestone completed: {milestone_name}", "metadata": { "task_id": task.task_id, "milestone": milestone_name, }, }) # Record the payment as a transaction execute("record_transaction", { "agent_id": ORCHESTRATOR_ID, "type": "milestone_payment", "counterparty_id": task.assigned_worker_id, "amount_usd": str(amount_usd), "metadata": { "task_id": task.task_id, "milestone": milestone_name, "escrow_id": task.escrow_id, }, }) return result ``` ### Technical Analysis The example passes the caller-provided `amount_usd` directly to the authenticated `release_escrow` operation. It does not verify that: - The amount is positive and finite. - The named milestone exists in the escrow agreement. - The milestone has been completed and approved. - The milestone has not already been paid. - The requested amount equals the milestone's authorized amount. - The amount is less than or equal to the remaining escrow balance. - The caller is authorized to approve this milestone. - The request has an idempotency key preventing duplicate releases. The `milestone_name` is also caller-controlled and is used only as descriptive metadata. It is not resolved against an immutable milestone record. The subsequent transaction record does not prevent the release; it merely logs ...[truncated 1488 chars]- Remediation
View remediation
