T09 · Insecure Skill Coding Practices
- Location
scripts/service.py:45- Finding
Payment Credential and Learner Data Can Be Sent to an Untrusted URL
- Content
View full analysis
Vulnerability Details
File Location:
scripts/service.py:45-67
Vulnerability Type: Unvalidated outbound request destination and sensitive-data disclosure
Risk Level: HighVulnerable Code:
python def call_service(order_no: str, order_data: dict) -> dict: credential = order_data.get("payCredential") if not credential: raise RuntimeError("订单文件中缺少 payCredential 字段") kind = order_data.get("languageSprintKind") or "placement" payload = order_data.get("languageSprintRequest") or default_payload(order_data) resource_url = order_data.get("resource_url") or order_data.get("resourceUrl") if resource_url: url = resource_url else: base_url = os.environ.get("LANGUAGE_SPRINT_API_BASE_URL") or os.environ.get("APP_BASE_URL") if not base_url: base_url = DEFAULT_API_BASE_URL url = f"{base_url.rstrip('/')}/api/language-sprint/{kind}" request = urllib.request.Request( url, data=json.dumps(payload, ensure_ascii=False).encode("utf-8"), headers={ "Content-Type": "application/json", "X-Language-Sprint-Order-No": order_no, "X-ClawTip-Pay-Credential": credential, }, method="POST", ) try: with urllib.request.urlopen(request) as response: return json.loads(response.read().decode("utf-8"))Technical Analysis
The fulfillment destination is selected directly from the order file through
resource_urlorresourceUrl. The code does not validate the URL scheme, hostname, port, path, or resolved address before attaching the ClawTip payment credential and transmitting the learner payload.The order file includes metadata received from the remote order service and is subsequently modified by an external payment CLI. Consequently, it is not a suitable source of authority for deciding where a sensitive cred ...[truncated 1956 chars]
- Remediation
View remediation
Remediation Suggestions
- Do not accept a fulfillment URL from mutable order metadata. Construct the endpoint from a locally configured, trusted API origin.
- If dynamic resource URLs are required, enforce an exact allowlist of approved HTTPS hostnames, ports, and path prefixes.
- Parse URLs with a standards-compliant parser and reject:
- Non-HTTPS schemes
- Embedded usernames or passwords
- Loopback, private, link-local, multicast, and unspecified IP addresses
- Unexpected ports
- Hostnames that resolve to prohibited address ranges
- Revalidate resolved addresses when connecting to reduce DNS-rebinding exposure.
- Disable redirects for credential-bearing requests or validate every redirect target before forwarding sensitive headers.
- Bind the expected fulfillment endpoint to signed or cryptographically authenticated order metadata.
- Minimize the learner payload and obtain explicit user consent before transmitting free-text interests or sample answers.
- Use a short-lived, order-scoped credential that cannot authorize unrelated operations.
