T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/otp_client.py:41
- Finding
- Basic Authentication credentials can be redirected to an attacker-controlled endpoint<![CDATA[ ## Vulnerability Details **File Location**: `scripts/otp_client.py`, lines 41–52 **Vulnerability Type**: Unrestricted credential destination **Risk Level**: High ### Vulnerable Code ```python def __init__(self, dev_key: str, dev_secret: str, base_url: str = BASE_URL): auth = base64.b64encode(f"{dev_key}:{dev_secret}".encode()).decode() self._headers = { "Content-Type": "application/json", "Authorization": f"Basic {auth}", } self._base_url = base_url.rstrip("/") def _request(self, method: str, path: str, payload: Optional[dict] = None) -> dict: url = f"{self._base_url}{path}" resp = requests.request(method, url, headers=self._headers, json=payload) ``` ### Technical Analysis The client accepts an arbitrary `base_url` while preparing a reusable `Authorization` header containing the Base64-encoded `dev_key:dev_secret` credential pair. Every subsequent request sends that header to the configured URL. Base64 is the encoding required by HTTP Basic Authentication; it is not encryption. Anyone who receives the header can trivially recover the original credentials. Because the client does not enforce HTTPS, validate the hostname, restrict ports, or allowlist the EngageLab API origin, an untrusted or mistakenly configured `base_url` can redirect credentials to an attacker-controlled endpoint. The default endpoint, `https://otp.api.engagelab.cc`, is consistent with the Skill's declared functionality. The vulnerability arises from permitting unrestricted endpoint replacement while automatically attaching privileged credentials. ### Attack Path 1. A victim application initializes `EngageLabOTP` with valid EngageLab credentials. 2. An attacker influences the `base_url` constructor argument through configuration injection, an environment setting, a compromised wrapper, or unsafe user input. 3. The attacker supplies a URL such as an attacker-controlled HTTPS server or a plaintext HTTP endpoint. 4. The victim calls any c ...[truncated 1062 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove the public `base_url` override if custom endpoints are not a required feature. 2. If endpoint customization is necessary, parse the URL before storing or using it. 3. Require the `https` scheme and reject plaintext HTTP. 4. Allowlist the exact expected hostname, such as `otp.api.engagelab.cc`, unless an explicitly documented set of trusted regional hosts is required. 5. Reject embedded URL credentials, fragments, unexpected ports, and malformed hostnames. 6. Validate the final destination immediately before attaching the Authorization header, including after redirects. 7. Disable cross-origin redirects or strip credentials whenever a redirect changes the origin. 8. Prefer a `requests.Session` with a narrowly scoped authentication policy instead of a reusable credential-bearing header attached to arbitrary destinations. 9. Add tests confirming that HTTP URLs, lookalike domains, subdomain tricks, user-information syntax, and unexpected ports are rejected. ]]>
