T09 · Insecure Skill Coding Practices
- Location
scripts/contract_review.py:10- Finding
Plaintext Transmission of Contract Data and API Credentials
- Content
View full analysis
Vulnerability Details
File Location:
scripts/contract_review.py, lines 10–11, 17–21, and 87–91
Vulnerability Type: Plaintext transmission of sensitive information
Risk Level: HighVulnerable Code
python API_BASE = os.environ.get(f"COZE_CONTRACT_API_URL_{SKILL_ID}", os.environ.get("CONTRACT_API_URL", "http://47.109.39.255:8765/api/v4") USER_KEY = os.environ.get("CONTRACT_API_USER_KEY", "")python def api_call(endpoint, data=None, method="POST"): url = f"{API_BASE.rstrip('/')}/{endpoint}" h = {"Content-Type": "application/json"} if USER_KEY: h["X-User-Key"] = USER_KEY try: if method == "GET": resp = requests.get(url, headers=h, params=data or {}, timeout=30) else: resp = requests.post(url, headers=h, json=data or {}, timeout=60)python def cmd_review(args): if not USER_KEY: print("❌ Please set the CONTRACT_API_USER_KEY environment variable first", file=sys.stderr) print(" Registration command: script register --username your-name", file=sys.stderr) sys.exit(1) print(f"🚀 Reviewing contract risks...", file=sys.stderr) data = {} data['contract_text'] = args.text if args.type: data['contract_type'] = args.type result = api_call("contract-review", data)Technical Analysis
The default API base URL uses unencrypted HTTP at a bare public IP address. The request places the user's API credential in the
X-User-Keyheader and sends the complete contract text in the JSON body.HTTP provides neither transport confidentiality nor reliable endpoint integrity. An attacker positioned on the network path—such as an operator of a hostile wireless network, compromised router, malicious proxy, or upstream network actor—can inspect the API key and contract contents. The same attacker can modify requests or substitute API responses.
Contracts may co ...[truncated 1861 chars]
- Remediation
View remediation
Remediation Suggestions
- Replace the default endpoint with an HTTPS URL using a valid certificate and a trusted hostname.
- Reject non-HTTPS API URLs rather than silently allowing plaintext transport:
python from urllib.parse import urlparse parsed = urlparse(API_BASE) if parsed.scheme != "https": raise RuntimeError("The contract API endpoint must use HTTPS") - Do not provide a plaintext HTTP fallback. Fail closed when no secure endpoint is configured.
- Ensure certificate and hostname verification remain enabled. Do not introduce
verify=Falseor equivalent bypasses. - Align the implementation and documentation so users can accurately identify the service receiving their contracts.
- Clearly disclose the remote processor, data-retention policy, and handling of contract data before submission.
- Advise users to redact personal identifiers, financial details, trade secrets, and other unnecessary sensitive fields.
- Rotate API keys that may previously have been sent through the plaintext endpoint, and provide revocation and usage-monitoring controls.
- Consider short-lived, narrowly scoped authorization tokens instead of a reusable static user key.
- Add automated tests that fail when the configured production endpoint uses any scheme other than HTTPS.
