T09 · Insecure Skill Coding Practices
Warning
- Location
- lib/map_helper.py:259
- Finding
- Google Maps API Key Disclosed in Returned Photo URLs<![CDATA[ ## Vulnerability Details **File Location**: `lib/map_helper.py:254-260` and `lib/map_helper.py:278-283` **Vulnerability Type**: Sensitive credential exposure in application output **Risk Level**: Medium ### Vulnerable Code ```python results = res.get("results", [])[:5] for place in results: if place.get("photos"): photo_ref = place["photos"][0]["photo_reference"] place["photo_url"] = f"https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference={photo_ref}&key={self.api_key}" return results ``` ```python res = requests.get(url, params=params).json().get("result", {}) if res.get("photos"): photo_ref = res["photos"][0]["photo_reference"] res["photo_url"] = f"https://maps.googleapis.com/maps/api/place/photo?maxwidth=800&photoreference={photo_ref}&key={self.api_key}" return res ``` The resulting objects are subsequently printed to standard output: ```python print(json.dumps(result, ensure_ascii=False, indent=2)) ``` ### Technical Analysis The `search` and `details` operations construct photo URLs containing `self.api_key` as a query parameter and return those URLs as part of their normal output. Because the complete result is serialized to standard output, the credential can be propagated into agent responses, command logs, shell captures, telemetry, chat histories, or downstream integrations. Transmitting the API key directly to Google's authenticated API endpoints is necessary for the declared mapping functionality. Returning that key to the caller in a generated URL is not necessary and exceeds the minimum disclosure required for the task. Although HTTPS protects the URL while it is sent to Google, it does not prevent disclosure through application output, logging, browser history, referrer metadata, screenshots, or other systems that process the returned JSON. ### Attack Path 1. A user configures the Skill with a valid `GOOGLE_API_KEY` or `GOOGLE_MAPS_API_KEY`. 2. The attacker causes the user ...[truncated 1208 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not include API keys in returned URLs or serialized application output. 2. Return the photo reference instead of an authenticated URL, for example: ```python place["photo_reference"] = photo_ref ``` 3. If callers require the photo itself, retrieve it server-side and return the image data or a locally controlled short-lived reference without exposing the Google credential. 4. Add output sanitization that removes sensitive query parameters such as `key`, `token`, and `signature` before serialization or logging. 5. Ensure exception handlers and HTTP debugging facilities do not log authentication headers, request URLs containing keys, or full response objects carrying generated credential-bearing URLs. 6. Restrict the Google API key to only the required Google Maps APIs. Where supported, apply application, source-IP, HTTP-referrer, or service-account restrictions. 7. Configure conservative quotas and billing alerts. 8. Rotate the existing key if outputs from `search` or `details` may already have entered logs, telemetry, or chat histories. 9. Add automated tests asserting that command output never contains the configured API key. ]]>
