T09 · Insecure Skill Coding Practices
- Location
- skills/smyx_common/scripts/util.py:317
- Finding
- Authentication Credentials Can Be Forwarded to Arbitrary Absolute URLs<![CDATA[ ## Vulnerability Details **File Location**: `skills/smyx_common/scripts/util.py:317-318, 352-354, 386-387` **Vulnerability Type**: Credential exfiltration through unrestricted request destinations **Risk Level**: High ### Vulnerable Code ```python if not url.startswith("https://") and not url.startswith("http://"): url = cls.BASE_URL + url headers.setdefault("X-Access-Token", ApiEnum.TOKEN) headers.setdefault("X-Api-Key", ApiEnum.API_SECRET_KEY) headers.setdefault("Authorization", ApiEnum.OPEN_TOKEN) response = requests.request( method, url, *args, json=data, params=params, headers=headers, timeout=int(timeout), **argss ) ``` ### Technical Analysis The shared HTTP helper accepts both relative and absolute URLs. Relative paths are appended to the configured service base URL, but absolute HTTP or HTTPS URLs are accepted without validating their hostname, port, or trust level. After destination processing, the helper automatically attaches the current access token, API key, and open authorization token. Consequently, any internal or future caller that passes an attacker-controlled absolute URL can cause authentication credentials to be transmitted to an unrelated server. The credential attachment occurs regardless of whether the destination belongs to the expected `lifeemergence.com` service. HTTPS alone would not resolve the issue because an attacker can operate a valid HTTPS endpoint. ### Attack Path 1. An attacker identifies a call path where a request URL is user-controlled or can be influenced through configuration, plugin code, or a future endpoint integration. 2. The attacker supplies an absolute URL such as `https://attacker.example/collect`. 3. `http_request()` recognizes the string as an absolute URL and does not prepend the trusted API base. 4. The function adds `X-Access-Token`, `X-Api-Key`, and `Authorization`. 5. The request is sent to the attacker-controlled endpoint. 6. The attacker captures ...[truncated 614 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Reject absolute URLs in the authenticated request helper and only accept relative API paths. 2. If absolute URLs are operationally required, parse them with `urllib.parse.urlparse()` and enforce: - HTTPS only; - An exact hostname allowlist; - An approved port list; - No embedded user information; - No redirects to untrusted hosts. 3. Attach authentication headers only after destination validation. 4. Disable automatic redirects or revalidate the destination on every redirect. 5. Use separate unauthenticated and authenticated HTTP clients. 6. Add tests proving that credentials are not sent to unapproved hosts. 7. Rotate existing credentials if logs or untrusted URL calls may already have exposed them. ]]>
