T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/apify_runner.py:44
- Finding
- Apify API Token Exposure Through URL Query Parameters and Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/apify_runner.py:44-49, 60, 75, 83, 144`; `SKILL.md:22-26, 67-71` **Vulnerability Type**: Credential exposure through request URLs and process arguments **Risk Level**: Medium ### Complete Code Snippets `scripts/apify_runner.py:44-49`: ```python resp = requests.post( url, json=run_input, headers={"Content-Type": "application/json"}, params={"token": token}, ) ``` `scripts/apify_runner.py:60`: ```python resp = requests.get(url, params={"token": token}) ``` `scripts/apify_runner.py:75`: ```python requests.post(url, params={"token": token}) ``` `scripts/apify_runner.py:83`: ```python resp = requests.get(url, params={"token": token}) ``` `scripts/apify_runner.py:144`: ```python parser.add_argument("--token", default=None, help="直接传 Token(优先级最高)") ``` `SKILL.md:22-26`: ```markdown Token can be provided via: 1. `--token` flag (highest priority) 2. `config.json` tokens map (by `--token-name`) 3. `APIFY_TOKEN` env var (fallback) ``` `SKILL.md:67-71`: ```bash python3 scripts/apify_runner.py {actor_id} \ --input '{...}' \ --token {token} \ --probe-only \ --list-key {key} ``` ### Technical Analysis The Apify token is a legitimate credential required for the Skill's declared functionality, and the destination is the fixed official HTTPS endpoint `https://api.apify.com/v2`. The behavior therefore does not indicate intentional credential exfiltration. However, the implementation sends the token as a URL query parameter using `params={"token": token}`. Although TLS protects the URL in transit from ordinary network observers, complete URLs can be captured by HTTP client diagnostics, reverse proxies, monitoring systems, exception telemetry, request tracing, or other infrastructure logs. Query parameters are generally more likely to be retained than authentication headers. The documented and implemented `--token` option creates another unnecessary exposure path. Command-line ...[truncated 2424 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Use authorization headers instead of query parameters** Centralize authenticated requests and send the token in an HTTP authorization header: ```python def auth_headers(token): return { "Authorization": f"Bearer {token}", "Content-Type": "application/json", } resp = requests.post( url, json=run_input, headers=auth_headers(token), timeout=30, ) ``` Apply equivalent header-based authentication to polling, abort, and dataset requests. Confirm the exact supported authentication scheme against current Apify API documentation. 2. **Remove or de-emphasize direct command-line token entry** Remove `--token` if compatibility permits. Prefer `APIFY_TOKEN` or a protected configuration file. If direct entry must remain available, warn that command-line arguments may be observable and provide an interactive `getpass.getpass()` option that does not echo or store the credential in shell history. 3. **Correct the documentation** Replace examples containing `--token {token}` with environment-based invocation, such as: ```bash APIFY_TOKEN="$(secure-secret-provider read apify-token)" \ python3 scripts/apify_runner.py apify/instagram-scraper \ --input '{...}' \ --probe-only \ --list-key directUrls ``` Avoid literal secret values in shell commands where possible because environment assignments may also be captured by shell or orchestration tooling. A protected secret manager or inherited environment is preferable. 4. **Protect configuration files** Require restrictive file permissions for token configuration files, avoid storing them inside the project repository, and document that they must be excluded from version control. Reject configuration files that are group- or world-readable where supported. 5. **Reduce token privileges** Use a dedicated Apify token with only the permissions and account sc ...[truncated 640 chars]
