T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/global_coverage.js:4
- Finding
- Hard-Coded ScraperAPI Credential Transmitted over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: - `scripts/global_coverage.js:4` - `scripts/global_coverage.js:91-96` - `scripts/user_journey.js:3` - `scripts/user_journey.js:24-34` **Vulnerability Type**: Hard-coded secret and plaintext credential transmission **Risk Level**: High ### Vulnerable Code From `scripts/global_coverage.js`: ```javascript const SCRAPER_API_KEY = 'fd18228b13dd001b794a8c74e9a35667'; ``` ```javascript const params = { api_key: SCRAPER_API_KEY, url: fullUrl, country_code: country.code, render: renderJS, session_number: Math.floor(Math.random() * 100000) }; const response = await axios.get('http://api.scraperapi.com', { params, timeout: 90000 }); ``` From `scripts/user_journey.js`: ```javascript const SCRAPER_API_KEY = 'fd18228b13dd001b794a8c74e9a35667'; ``` ```javascript const response = await axios.get('http://api.scraperapi.com', { params: { api_key: SCRAPER_API_KEY, url: fullUrl, country_code: task.code, render: true, wait_for_selector: 'body', session_number: Math.floor(Math.random() * 10000) }, timeout: 60000 }); ``` ### Technical Analysis A live-looking ScraperAPI credential is embedded directly in two distributed source files. Anyone able to read the package can recover and reuse the credential without executing the scripts. The scripts additionally send the credential as the `api_key` query parameter to an `http://` endpoint. Because the transport is not protected by TLS, a network observer or active machine-in-the-middle attacker may inspect or modify the request. Query parameters may also be retained in intermediary proxy logs, monitoring systems, or service access logs. This implementation contradicts the documented configuration model in `skill.md`, which instructs users to supply `SCRAPER_API_KEY` through an environment variable. ### Attack Path 1. An attacker downloads, receives, or otherwise reads the skill package. 2 ...[truncated 977 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Revoke and rotate the exposed ScraperAPI key immediately. Removing it from a future version does not invalidate copies already distributed. 2. Remove the credential from every source file and load it from the environment: ```javascript const SCRAPER_API_KEY = process.env.SCRAPER_API_KEY; if (!SCRAPER_API_KEY) { throw new Error('SCRAPER_API_KEY is required'); } ``` 3. Replace the plaintext endpoint with the HTTPS endpoint: ```javascript const response = await axios.get('https://api.scraperapi.com', { params, timeout: 90000 }); ``` 4. Ensure credentials are never printed in logs, exception messages, generated reports, or request diagnostics. 5. Add automated secret scanning to development and release workflows. 6. If supported by ScraperAPI, restrict the replacement key by allowed source, scope, usage limits, and alert thresholds. 7. Review repository history and published package archives for previous copies of the credential. ]]>
