T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/whatsapp_client.py:47
- Finding
- Basic Authentication Credentials Can Be Disclosed to a Caller-Controlled API Origin<![CDATA[ ## Vulnerability Details **File Location**: `scripts/whatsapp_client.py`, lines 47–58 **Vulnerability Type**: Credential disclosure through an unrestricted API base URL **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, params: Optional[dict] = None): url = f"{self._base_url}{path}" resp = requests.request(method, url, headers=self._headers, json=payload, params=params) ``` ### Technical Analysis The constructor accepts an unrestricted `base_url`, while `_request()` unconditionally sends the stored HTTP Basic Authorization header to the resulting origin. No validation ensures that the destination uses HTTPS or belongs to the expected EngageLab API host. The flagged Base64 operation is not, by itself, a covert output or exfiltration mechanism. Base64 encoding is required by the documented HTTP Basic authentication protocol, and the encoded value is not printed to stdout. However, Base64 provides no confidentiality: anyone receiving the header can decode it into `dev_key:dev_secret`. The behavior exceeds minimum privilege when arbitrary API origins are permitted to receive the credentials. The declared functionality only requires sending authentication data to the trusted EngageLab API endpoint. ### Attack Path 1. An attacker or compromised configuration influences the `base_url` argument passed to `EngageLabWhatsApp`. 2. The application initializes the client with valid EngageLab credentials and the attacker-controlled URL. 3. The application invokes any message or template API method. 4. `_request()` sends the `Authorization: Basic ...` header to the attacker-co ...[truncated 798 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Remove the `base_url` override if custom API origins are not required. - Otherwise, validate the URL before storing or using it: - Require the `https` scheme. - Allowlist the exact expected hostname, `wa.api.engagelab.cc`. - Reject embedded credentials, unexpected ports, and hostname suffix tricks. - Disable automatic redirects for authenticated requests, or validate every redirect target before forwarding the Authorization header. - Prefer `requests.auth.HTTPBasicAuth` or an equivalent authentication facility to reduce manual credential handling. - Add an explicit network timeout to prevent indefinite blocking. - Never include Authorization headers or encoded credentials in logs, exceptions, debug output, or Agent-visible responses. - If testing against another endpoint is necessary, require separate non-production credentials and an explicit development-only configuration. ]]>
