T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/apollo_like_leads_actor.py:128
- Finding
- Apify API Token Exposed in URL Query String## Vulnerability Details **File Location**: `scripts/apollo_like_leads_actor.py`, lines 128–143 **Vulnerability Type**: Credential exposure through URL query parameters **Risk Level**: Medium ```python def run_actor(token: str, actor_id: str, payload: Dict[str, Any], timeout_sec: int) -> Dict[str, Any]: base_url = f"https://api.apify.com/v2/acts/{actor_id}/run-sync-get-dataset-items" params = { "token": token, "timeout": timeout_sec, "clean": "true", } url = f"{base_url}?{urllib.parse.urlencode(params)}" body = json.dumps(payload).encode("utf-8") req = urllib.request.Request( url=url, data=body, headers={"Content-Type": "application/json"}, method="POST", ) ``` ### Technical Analysis The script places the Apify API token directly in the request URL. TLS protects the URL while it travels between the client and the HTTPS endpoint, but it does not prevent the complete URL from being captured by local diagnostics, HTTP instrumentation, reverse proxies, observability platforms, exception reports, or server-side access logs. Credentials should be transmitted through an authorization header because infrastructure commonly treats headers—particularly `Authorization`—as sensitive and applies redaction controls. Query parameters are more likely to be logged without redaction. The outbound request is necessary for the Skill’s declared lead-collection functionality, but putting the credential in the URL is not necessary and exceeds secure minimum-disclosure requirements. ### Attack Path 1. A user configures a valid `APIFY_TOKEN` and invokes the Skill. 2. `run_actor` inserts the token into the URL as the `token` query parameter. 3. A proxy, monitoring agent, request debugger, API access log, or error-reporting system records the complete request URL. 4. A person or compromised service with access to those records extracts the to ...[truncated 687 chars]
- Remediation
- ## Remediation Suggestions - Remove the `token` field from the URL query parameters. - Send the credential in an authorization header, subject to confirmation of the Apify API’s supported authentication format: ```python params = { "timeout": timeout_sec, "clean": "true", } url = f"{base_url}?{urllib.parse.urlencode(params)}" req = urllib.request.Request( url=url, data=json.dumps(payload).encode("utf-8"), headers={ "Content-Type": "application/json", "Authorization": f"Bearer {token}", }, method="POST", ) ``` - Configure HTTP clients, proxies, and telemetry systems to redact authorization headers and known secret values. - Avoid including request URLs or request objects in exceptions where credentials could be present. - Use a narrowly scoped Apify token with only the permissions required to run the designated actor and retrieve its output. - Rotate the token if the existing implementation has been used in an environment where full URLs may have been retained.
