T09 · Insecure Skill Coding Practices
- Location
scripts/service.py:19- Finding
Payment Authorization Can Be Forged Through Editable Local Order Data
- Content
View full analysis
Vulnerability Details
File Location:
scripts/service.py:19-26, 45-57
Vulnerability Type: Improper credential validation and fail-open payment status
Risk Level: HighVulnerable Code
python def is_credential_valid(order_data: dict) -> bool: credential = order_data.get("payCredential") if not credential: return False credential_ts = order_data.get("credentialTimestamp") if credential_ts and time.time() - credential_ts > CREDENTIAL_TTL: return False return Truepython if not is_credential_valid(order_data): print("PAY_STATUS: ERROR") print("ERROR_INFO: 未找到有效的支付凭证。请先通过 clawtip 完成支付。") sys.exit(1) pay_status = order_data.get("payStatus", "SUCCESS") print(f"PAY_STATUS: {pay_status}") if pay_status != "SUCCESS": print(f"ERROR_INFO: 支付状态为 {pay_status},无法续进") sys.exit(1) print("AUTHORIZATION_RESULT=verified")Technical Analysis
Payment authorization relies entirely on fields loaded from a locally writable JSON order file. The code considers any truthy
payCredentialvalue valid; it does not verify a digital signature, trusted issuer, credential structure, payment recipient, amount, order number, or indicator.The credential timestamp is optional. If
credentialTimestampis absent, expiration is not enforced. In addition,payStatusdefaults toSUCCESSwhen absent, creating a fail-open authorization path.Consequently, the local file is treated simultaneously as untrusted storage and as the authoritative payment-verification source. A cryptographically verifiable statement from the payment provider is never required.
Attack Path
- Run
scripts/create_order.pyto create an order and obtain its order number. - Locate the order JSON under
~/.openclaw/skills/orders/{indicator}/{order_no}.json. - Add a truthy attacker-controlled value such as
"payCredential": "x". - Omit `credentialTim ...[truncated 692 chars]
- Run
- Remediation
View remediation
Remediation Suggestions
- Require a payment credential signed by a trusted Clawtip key and verify the signature locally using a pinned, trusted public key.
- Bind the verified credential to the exact order number, amount, recipient, indicator, merchant identity, and expiration time.
- Require
credentialTimestampandpayStatus; reject the credential if either field is missing or malformed. - Remove the
SUCCESSdefault and fail closed for absent or unknown payment states. - Validate types before arithmetic or comparison operations.
- Protect order files with restrictive permissions, but do not treat filesystem permissions as a replacement for cryptographic verification.
- Record and reject already-consumed credentials if payment credentials are intended for one-time use.
