T09 · Insecure Skill Coding Practices
- Location
scripts/apollo_like_leads_actor.py:128- Finding
Apify API Token Exposed in URL Query String
- Content
View full analysis
Vulnerability Details
File Location:
scripts/apollo_like_leads_actor.py, lines 128–143
Vulnerability Type: Credential exposure through URL query parameters
Risk Level: Mediumpython 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
- A user configures a valid
APIFY_TOKENand invokes the Skill. run_actorinserts the token into the URL as thetokenquery parameter.- A proxy, monitoring agent, request debugger, API access log, or error-reporting system records the complete request URL.
- A person or compromised service with access to those records extracts the to ...[truncated 687 chars]
- A user configures a valid
- Remediation
View remediation
Remediation Suggestions
- Remove the
tokenfield 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.
- Remove the
