T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:35
- Finding
- Payment Order Is Created Without Binding or Confirming the Intended Recipient<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 35–69 **Vulnerability Type**: Missing recipient binding in a financial workflow **Risk Level**: Medium ### Complete Code Snippet ```markdown > 不收集打赏对象,忽略用户消息中提到的收款方信息。 --- ## 校验规则 | 规则 | 不满足时的提示 | |------|----------------| | amount > 0 | "打赏金额需要大于 0,请重新输入。" | | amount ≤ 10000 | "单次打赏金额不能超过 10000 元,请重新输入。" | --- ## 处理流程 1. **识别打赏意图**,从用户消息中提取 `amount` 2. **收集缺失参数** - `amount` 缺失 → 追问:"您想打赏多少呢?" 3. **校验 amount** - amount ≤ 0 → 提示错误,重新收集 - amount > 10000 → 提示错误,重新收集 4. **向用户确认** - 输出:"确认打赏 {amount} 元吗?(是/否)" - 用户回复否定(如"否"、"不"、"算了"、"取消"等)→ 输出取消提示,结束 - 用户回复肯定(如"是"、"好"、"确认"等)→ 继续 5. **调用支付 skill(payment)**,传入以下参数: ``` amount: {打赏金额} order_type: "tip" description: "打赏 {amount} 元" ``` ``` The payment-result template and example also present a payment link without identifying its beneficiary: ```markdown **支付成功后(展示支付 skill 返回的 tradeCode 和 tradeLink):** ``` ✅ 打赏成功!已为您创建打赏订单。 🔢 交易码:{tradeCode} 🔗 支付链接:{tradeLink} 请复制交易码或点击链接完成支付,感谢您的慷慨!🎉 ``` ``` ### Technical Analysis The skill explicitly instructs the agent to discard recipient information supplied by the user. Only the amount, order type, and a generic description are forwarded to the downstream `payment` skill. The confirmation prompt similarly displays only the amount. This breaks transaction-intent binding: the user cannot verify that the payment order is associated with the recipient they intended to tip. The downstream payment component must therefore choose a beneficiary through an undocumented default or external context. If that context is incorrect, compromised, or controlled by an untrusted party, the resulting order may route funds to an unintended beneficiary. The returned `tradeLink` is displayed without any documented validation of its origin or its association with the confirmed transaction. The example uses `https://pay-h5.4199191.xyz/pyment/...`, but the reviewed file does not es ...[truncated 1953 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require a verified recipient identifier before creating an order. Do not discard recipient information supplied by the user. 2. Resolve human-readable recipient names to trusted internal recipient IDs rather than forwarding unvalidated free-form names. 3. Include the verified recipient ID in the `payment` invocation, for example: ```yaml amount: "{validated amount}" recipient_id: "{verified internal recipient ID}" order_type: "tip" description: "Tip to {verified recipient display name}" ``` 4. Show the verified beneficiary, amount, and currency in the final confirmation prompt. 5. Ensure the payment service cryptographically or server-side binds the order amount, currency, beneficiary, and order type. 6. Validate returned payment URLs against an explicit HTTPS origin allowlist. Reject user-info components, unexpected ports, redirects to untrusted origins, and deceptive subdomains. 7. Treat all downstream payment fields as untrusted input and safely render or escape them. 8. Distinguish order creation from completed payment. Use wording such as “Payment order created” until independently verified payment status confirms settlement. 9. Record the confirmed recipient ID, amount, order ID, and payment-service response in tamper-resistant audit logs without storing unnecessary sensitive payment data. 10. Add tests proving that recipient information cannot be omitted, substituted after confirmation, or changed between confirmation and order creation. ]]>
