T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/zoom_api.py:275
- Finding
- Unvalidated identifiers are interpolated into authenticated Zoom API paths## Vulnerability Details **File Location**: `scripts/zoom_api.py:275-334` **Vulnerability Type**: Improper validation and encoding of URL path segments **Risk Level**: Medium ### Vulnerable Code ```python def get_meeting(self, meeting_id: str) -> dict: """ Retrieve meeting details. Args: meeting_id: Zoom meeting ID. Returns: Meeting details. """ response = self._request("GET", f"/meetings/{meeting_id}") return { "meeting_id": str(response.get("id", meeting_id)), "join_url": response.get("join_url", ""), "password": response.get("password", ""), "topic": response.get("topic", ""), "start_time": response.get("start_time", ""), "duration": response.get("duration", 0), "timezone": response.get("timezone", ""), "status": response.get("status", "") } def list_meetings(self, user_id: str = "me") -> list: """ List all meetings for a user. Args: user_id: User ID or 'me' for authenticated user. Returns: List of meeting summaries. """ response = self._request("GET", f"/users/{user_id}/meetings") meetings = response.get("meetings", []) return [ { "meeting_id": str(m.get("id", "")), "topic": m.get("topic", ""), "start_time": m.get("start_time", ""), "duration": m.get("duration", 0), "join_url": m.get("join_url", "") } for m in meetings ] def delete_meeting(self, meeting_id: str) -> dict: """ Delete a Zoom meeting. Args: meeting_id: Zoom meeting ID. Returns: Confirmation response. """ self._request("DELETE", f"/meetings/{meeting_id}") return { "success": True, "meeting_id": meeting ...[truncated 1991 chars]
- Remediation
- ## Remediation Suggestions - Validate meeting IDs using Zoom's documented identifier format. If only numeric meeting IDs are supported, enforce a strict expression such as `^[0-9]+$`. - Restrict `user_id` to `me` unless arbitrary user access is explicitly required. Otherwise, validate it against Zoom's documented user identifier format. - Encode every variable URL path segment using `urllib.parse.quote(value, safe="")` after validation. - Reject values containing `/`, `\`, `?`, `#`, percent-encoded delimiters, control characters, or traversal components. - Construct endpoints through dedicated helper functions rather than general string interpolation. - Assign only the minimum Zoom OAuth scopes needed to create, read, list, and delete meetings. - Add tests covering traversal strings, encoded delimiters, query fragments, empty identifiers, oversized identifiers, and malformed Unicode input.
