T09 · Insecure Skill Coding Practices
- Location
scripts/generate.py:11- Finding
API Credentials and User Content Transmitted Over Plaintext HTTP
- Content
View full analysis
Vulnerability Details
File Location:
scripts/generate.py, lines 11–24
Vulnerability Type: Cleartext transmission of sensitive information
Risk Level: Highpython API_BASE = os.environ.get("XHS_API_URL", "http://47.109.39.255:8765/api/v4") USER_KEY = os.environ.get("XHS_API_USER_KEY", "") 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)Technical Analysis
The default API endpoint uses unencrypted HTTP and points directly to a public IP address. The script places the value of
XHS_API_USER_KEYin theX-User-Keyrequest header and sends it to this endpoint. Generation requests also transmit user-supplied topics, styles, and counts in the plaintext HTTP request body.HTTP provides neither transport confidentiality nor server authentication. An attacker able to observe or modify traffic between the client and the API server can read the API key and submitted content, impersonate the server, alter API responses, or replay authenticated requests. The request timeout does not mitigate interception or response manipulation.
Although
XHS_API_URLcan be overridden, the insecure public HTTP endpoint is the default. Consequently, users who follow the normal execution path are exposed without needing to opt into an insecure configuration.Attack Path
- A victim sets
XHS_API_USER_KEYand invokes theinfo,generate, or another authenticated command. - The script constructs a URL under
http://47.109.39.255:8765/api/v4. - It adds the victim's key to the
X-User-Keyheader and sends the request without TLS. - An attacker posi ...[truncated 1156 chars]
- A victim sets
- Remediation
View remediation
Remediation Suggestions
- Replace the default endpoint with an HTTPS URL using a valid certificate:
python API_BASE = os.environ.get( "XHS_API_URL", "https://api.example.com/api/v4", ) - Reject non-HTTPS API URLs before sending credentials:
python from urllib.parse import urlparse parsed = urlparse(API_BASE) if parsed.scheme != "https": raise RuntimeError("XHS_API_URL must use HTTPS") - Configure the server with a certificate issued for a stable DNS hostname rather than relying on a raw public IP address.
- Keep TLS certificate verification enabled. Do not introduce
verify=Falseor suppress certificate validation errors. - Rotate all API keys that may previously have been transmitted to the plaintext endpoint and invalidate old keys server-side.
- Use short-lived, revocable credentials with narrowly scoped permissions where supported. Apply server-side rate limits and anomaly detection to reduce the impact of stolen keys.
- Avoid logging authentication headers or sensitive request bodies. Clearly document what user content is transmitted to the external service.
- Add an automated test that rejects
http://API configurations whenever an authentication key or user content would be transmitted.
- Replace the default endpoint with an HTTPS URL using a valid certificate:
