T09 · Insecure Skill Coding Practices
- Location
scripts/google_maps_email_extractor_actor.py:238- Finding
Apify API Token Exposed in the Request URL
- Content
View full analysis
dict[str, Any]: params: dict[str, str | int | float] = { "token": token, "timeout": timeout_sec, "clean": "true", } if budget_usd is not None: if budget_usd <= 0: raise SkillError("--budget-usd must be > 0.") params["maxTotalChargeUsd"] = budget_usd url = ( f"https://api.apify.com/v2/acts/{urllib.parse.quote(actor_id, safe='')}/run-sync-get-dataset-items" f"?{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") try: with urllib.request.urlopen(req, timeout=min(timeout_sec + 30, 3600)) as response: ``` ### Technical Analysis The Apify API token is added to the request URL as a `token` query parameter. TLS protects the URL while it is transmitted directly to Apify, and the destination is the documented official Apify endpoint. This is therefore not evidence of malicious exfiltration. However, URLs are commonly recorded by reverse proxies, HTTP access logs, debugging tools, monitoring agents, exception telemetry, and network security products. A query-string credential can consequently be disclosed to systems or personnel that do not otherwise need access to it. URL credentials may also be retained longer than authorization headers. The network request itself is necessary for the Skill's declared functionality, but placing the credential in the URL does not follow least-exposure practices. ### Attack Path 1. A user runs the Skill with a valid `APIFY_TOKEN`. 2. The run ...[truncated 756 chars]- Remediation
View remediation
