T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/scrape_profiles.py:96
- Finding
- Apify API Token Exposed in URL Query String## Vulnerability Details **File Location**: `scripts/scrape_profiles.py`, line 96 **Vulnerability Type**: Credential exposure through a URL query parameter **Risk Level**: Medium ### Vulnerable Code ```python url = f'https://api.apify.com/v2/acts/apify~instagram-profile-scraper/run-sync-get-dataset-items?token={APIFY_KEY}' ``` ### Technical Analysis The script embeds `APIFY_API_KEY` directly in the request URL. HTTPS encrypts the request while it is in transit, but it does not prevent the complete URL from being retained by application diagnostics, server access logs, reverse proxies, API gateways, monitoring products, or exception-reporting systems. This method exposes the credential to more systems and operators than necessary. The API token should instead be transmitted through an authorization header so it is less likely to be captured by URL-oriented logging. The fallback request itself is consistent with the Skill’s declared creator-screening functionality and does not constitute an unauthorized privilege escalation. The vulnerability is specifically the insecure credential transport mechanism. ### Attack Path 1. A user configures `APIFY_API_KEY` and invokes username-based profile scraping. 2. The script interpolates the plaintext API token into the Apify request URL. 3. A server, proxy, gateway, debugging facility, or monitoring system records the complete URL. 4. An attacker or unauthorized operator with access to those records extracts the token. 5. The attacker reuses the token against Apify within the permissions and account limits assigned to it. ### Impact Assessment A leaked token could allow unauthorized use of the victim’s Apify account capabilities, including execution of actors and consumption of paid resources, subject to the token’s configured permissions. This may cause financial loss, quota exhaustion, unauthorized data access, or disruption of legitimate scraping tasks. The issue does not expose local system privileges by itsel ...[truncated 90 chars]
- Remediation
- ## Remediation Suggestions - Use Apify’s supported authorization header rather than a query parameter: ```python url = 'https://api.apify.com/v2/acts/apify~instagram-profile-scraper/run-sync-get-dataset-items' req = urllib.request.Request(url, data=data, method='POST') req.add_header('Authorization', f'Bearer {APIFY_KEY}') req.add_header('Content-Type', 'application/json') ``` - Ensure logs and exception handlers never record authorization headers or credential-bearing URLs. - Apply least privilege to the Apify token and restrict its permissions where supported. - Rotate any token previously used by this implementation if request URLs may have been logged. - Use separate tokens for development and production and monitor for unexpected actor executions or resource consumption. - Add an automated test that rejects outbound URLs containing sensitive parameter names such as `token`, `api_key`, or `secret`.
