T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/ccs_online_client.py:57
- Finding
- Authentication credentials and receipt data can be transmitted to arbitrary or plaintext endpoints<![CDATA[ ## Vulnerability Details **File Location**: `scripts/ccs_online_client.py`, lines 57-59 and 91-105 **Vulnerability Type**: T09: Insecure Skill Coding Practices **Risk Level**: High ### Vulnerable Code ```python def resolve_endpoint(cli_value: str | None = None) -> str: ep = cli_value or os.environ.get("CCS_API_ENDPOINT") or DEFAULT_ENDPOINT return ep.rstrip("/") ``` ```python def call(path: str, body: dict, endpoint: str | None = None, timeout: float = 30.0) -> dict: """POST JSON to the CCS API; return the parsed JSON response. Raises PaymentRequiredError on HTTP 402 (bill printed to stderr), CCSAPIError on other non-2xx. The request body is never logged. """ ep = resolve_endpoint(endpoint) data = json.dumps(body, ensure_ascii=False).encode("utf-8") if len(data) > MAX_BODY_BYTES: raise CCSAPIError(413, {"error": f"请求体超过 {MAX_BODY_BYTES} 字节上限"}) headers = {"Content-Type": "application/json; charset=utf-8", "User-Agent": "CCS-CLI/1.0 (channel=clawhub)"} api_key = os.environ.get("CCS_API_TOKEN") if api_key: headers["X-API-Key"] = api_key # A2M: payment proof from the Alipay checkout flow (official contract # header name is Payment-Proof). CCS_PAY_TOKEN kept as a legacy alias. proof = os.environ.get("CCS_PAYMENT_PROOF") or os.environ.get("CCS_PAY_TOKEN") if proof: headers["Payment-Proof"] = proof req = urllib.request.Request(ep + path, data=data, headers=headers, method="POST") ``` The online mode is invoked from `scripts/batch_audit.py`, lines 145-149: ```python if args.online: import ccs_online_client as client # noqa: E402 try: rep = client.call("/v1/audit/batch", body, endpoint=args.endpoint, timeout=90) ``` ### Technical Analysis The online client accepts an endpoint from the `--endpoint` option or the `CCS_API_ENDPOINT` environment variable without vali ...[truncated 2060 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse endpoints using `urllib.parse.urlsplit` and reject malformed URLs. 2. Require the `https` scheme for all online requests. If plaintext transport is required for local testing, place it behind a clearly named opt-in option such as `--allow-insecure-http`. 3. Reject URL user information, fragments, unexpected ports, loopback hosts, private networks, link-local ranges, and cloud metadata addresses unless a separately authorized development mode explicitly permits them. 4. Bind credentials to trusted origins. Do not automatically send production API tokens or payment proofs to arbitrary custom endpoints. 5. Require credentials to be supplied for a specific endpoint or maintain an explicit allowlist of origins authorized to receive each credential. 6. Disable redirects or validate every redirect target and strip sensitive headers when the origin changes. 7. Display the final destination and request explicit confirmation before sending receipt contents to a non-default endpoint. 8. Update `SKILL.md` to explain custom-endpoint trust requirements and accurately state that HTTPS is enforced only after the code implements that enforcement. 9. Add automated tests verifying rejection of HTTP, malformed URLs, loopback/private/metadata destinations, and cross-origin credential forwarding. ]]>
