T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/fetch_trends.py:23
- Finding
- Hardcoded YouTube API Key Exposed and Transmitted in Request URLs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fetch_trends.py`, lines 23-64 **Vulnerability Type**: Hardcoded secret and insecure credential handling **Risk Level**: Medium ### Vulnerable Code ```python # YouTube API Key (set via environment or default) YOUTUBE_API_KEY = os.environ.get("YOUTUBE_API_KEY", "AIzaSyC-4zq2k2ohAwtQM7lF8jPct_QhzpENG88") ``` The credential is subsequently included in an HTTP query parameter: ```python def search_youtube(days: int = 3, max_results: int = 10) -> list[dict]: """Search YouTube for OpenClaw videos using Data API v3.""" results = [] if not YOUTUBE_API_KEY: print("Warning: No YouTube API key set", file=sys.stderr) return results published_after = (datetime.now() - timedelta(days=days)).isoformat() + "Z" for query in SEARCH_TERMS[:2]: # Limit queries try: url = "https://www.googleapis.com/youtube/v3/search" params = { "part": "snippet", "q": query, "type": "video", "order": "date", "publishedAfter": published_after, "maxResults": max_results, "key": YOUTUBE_API_KEY, } full_url = f"{url}?{urllib.parse.urlencode(params)}" req = urllib.request.Request(full_url) with urllib.request.urlopen(req, timeout=10) as response: data = json.loads(response.read().decode()) ``` ### Technical Analysis The source code contains a reusable Google/YouTube API key as the default value used when `YOUTUBE_API_KEY` is not defined in the environment. Anyone who can read or download the Skill package can extract this credential without executing the script. The key is appended to the request URL as the `key` query parameter and sent to `www.googleapis.com`. HTTPS protects the request while it is in transit, but query strings can be retained by appli ...[truncated 2368 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Immediately revoke or rotate the exposed API key in the associated Google Cloud project. 2. Remove the hardcoded fallback and require runtime configuration: ```python YOUTUBE_API_KEY = os.environ.get("YOUTUBE_API_KEY") ``` 3. If the variable is absent, skip YouTube searches or terminate with a clear configuration error rather than silently using a shared credential. 4. Store the replacement key in an approved secret manager or protected runtime environment variable. Do not commit it to the repository, documentation, examples, or generated artifacts. 5. Restrict the replacement key to the YouTube Data API only. 6. Apply the strongest feasible application restrictions, quota limits, budget alerts, and usage monitoring in Google Cloud. 7. Use a separate project and credential for this Skill so compromise does not affect unrelated services. 8. Review source-control history, package releases, build artifacts, and logs for copies of the exposed key. 9. Avoid recording complete request URLs containing credentials. Redact the `key` parameter from application, proxy, and diagnostic logs. 10. Add automated secret scanning to development and release workflows to prevent future credential commits. 11. Update `SKILL.md` to remove the statement that a key is embedded and clearly document secure user-provided credential configuration. ]]>
