T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:1797
- Finding
- Trust Verification Can Be Bypassed Before Escrow Creation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:1797-1836` **Vulnerability Type**: Missing authorization enforcement before a financial operation **Risk Level**: Medium ### Vulnerable Code ```python @tool def hire_with_escrow( agent_id: str, amount: float, task_description: str, ) -> str: """Create an escrow-protected contract with a verified agent. IMPORTANT: Always call verify_before_hire first. Args: agent_id: The GreenHelix agent ID to hire. amount: Payment amount in USD. task_description: What the agent should do. """ import requests resp = requests.post( "https://sandbox.greenhelix.net/v1", headers={ "Content-Type": "application/json", "Authorization": f"Bearer {os.environ['GREENHELIX_API_KEY']}", }, json={ "tool": "create_escrow", "input": { "payer_agent_id": os.environ["AGENT_ID"], "payee_agent_id": agent_id, "amount": str(amount), "description": task_description, }, }, ) resp.raise_for_status() result = resp.json() return f"Escrow created: {result.get('escrow_id')}. ${amount} locked." ``` ### Technical Analysis The function performs an authenticated, state-changing financial operation using `GREENHELIX_API_KEY`. Although its docstring instructs callers to invoke `verify_before_hire` first, the function does not technically enforce that prerequisite. The verification and escrow operations are exposed as separate tools. Consequently, an LLM, framework, or direct caller can select `hire_with_escrow` without first invoking the verification tool. The function does not: - Call `verify_before_hire` or `AgentVerifier.full_audit`. - Require a signed or short-lived verification approval. - Bind an approval to the payee, amount, task, or authenticated payer. - Validate that the amount is positive and w ...[truncated 2395 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Enforce verification inside the financial function.** Do not rely on the model or caller to invoke a separate tool. ```python def hire_with_escrow(agent_id, amount, task_description): amount = Decimal(str(amount)) if amount <= 0 or amount > MAX_ESCROW_AMOUNT: raise ValueError("Escrow amount is outside the authorized range") report = verifier.full_audit(agent_id) if not is_approved(report): raise PermissionError("Payee failed mandatory trust verification") # Continue only after mandatory checks succeed. ``` 2. **Bind approval to the transaction.** Create a short-lived, server-validated approval containing the payer, payee, amount, task hash, verification result, expiration time, and nonce. Reject an approval if any transaction property changes. 3. **Require explicit confirmation.** For financial actions, present the exact payee, amount, and task summary to the user and require confirmation immediately before submission. Higher amounts should require stronger or out-of-band approval. 4. **Apply least privilege.** Use a dedicated API credential restricted to escrow creation, with per-transaction and cumulative spending limits. Do not provide unrelated read/write permissions. 5. **Validate all inputs.** Enforce an allowlisted agent-ID format, positive decimal amounts, maximum limits, currency rules, and task-description length and sensitivity constraints. 6. **Prevent duplicate transactions.** Supply a unique idempotency key and securely record the resulting transaction identifier. 7. **Harden network behavior.** Add a short timeout, bounded retries only when paired with idempotency, and strict response-schema validation. 8. **Avoid unnecessary secret requirements.** Remove `AGENT_SIGNING_KEY` from the Skill metadata because the audited examples do not use it. Requiring an unused private signing key violates least-privilege principles and unnecessarily exposes a high-value credenti ...[truncated 32 chars]
