T09 · Insecure Skill Coding Practices
- Location
scripts/service.py:48- Finding
Payment Authorization Bypass Through Forged Local Order Data
- Content
View full analysis
Vulnerability Details
File Location:
scripts/service.py, lines 48-65 and 81-93
Vulnerability Type: Client-controlled payment credential validation
Risk Level: HighVulnerable Code
python def _load_order(indicator, order_no): _validate_order_no(order_no) path = os.path.join(_get_orders_dir(indicator), f"{order_no}.json") if not os.path.isfile(path): raise RuntimeError(f"Order file not found: {path}") with open(path, "r", encoding="utf-8") as f: return json.load(f) 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: No valid payment credential found. Complete payment via clawtip first.") sys.exit(1) pay_status = order_data.get("payStatus", "SUCCESS") print(f"PAY_STATUS: {pay_status}") if pay_status != "SUCCESS": print(f"ERROR_INFO: Payment status is '{pay_status}', cannot proceed") sys.exit(1)Technical Analysis
The payment authorization decision is based entirely on fields loaded from an unauthenticated JSON file in the current user's home directory. The validation routine only checks whether
payCredentialis non-empty. It does not cryptographically validate the credential or bind it to the order number, payment amount, recipient, skill indicator, or merchant.Timestamp enforcement is also fail-open. If
credentialTimestampis absent, the credential is accepted indefinitely. In addition,payStatusdefaults toSUCCESSwhen the field is absent. Consequently, an attacker who can modify their own order file can fabricate all data required to pass au ...[truncated 1110 chars]- Remediation
View remediation
Remediation Suggestions
- Cryptographically verify every payment credential using a trusted clawtip public key, authenticated API, or equivalent authoritative verification mechanism.
- Bind the verified credential to the expected
order_no, amount, recipient address, merchant, skill indicator, and transaction identifier. - Require
credentialTimestampto be present, numeric, within the allowed lifetime, and not unreasonably far in the future. - Require an explicit authenticated
payStatusvalue ofSUCCESS; never default a missing status to success. - Reject malformed, missing, unknown, or duplicate credential fields using a strict schema.
- Protect persisted order data with an authenticated signature or message authentication code. File permissions alone must not be treated as proof of payment.
- Track consumed transaction identifiers to prevent credential replay across orders.
- Fail closed whenever verification infrastructure is unavailable or any verification step fails.
