T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/handler.py:71
- Finding
- Unrestricted Local Audio File Read and External Transmission## Vulnerability Details **File Location**: `scripts/handler.py`, lines 71–80; request propagation occurs at lines 137–143 and 180–185 **Vulnerability Type**: Arbitrary local file access through an unvalidated audio path **Risk Level**: High ### Vulnerable Code ```python elif audio_path: # Convert audio to PCM and send import librosa y, sr = librosa.load(audio_path, sr=SAMPLE_RATE_IN) # Send as realtime audio input await session.send_realtime_input( audio=types.Blob( data=y.tobytes(), mime_type=f"audio/pcm;rate={SAMPLE_RATE_IN}" ) ) ``` The path originates directly from request data: ```python audio_path = request_data.get("audio_path") system_instruction = request_data.get("system_instruction") result = asyncio.run(_process_with_gemini( audio_path=audio_path, text_input=text_input, system_instruction=system_instruction )) ``` ### Technical Analysis The caller-controlled `audio_path` is passed directly to `librosa.load()` without canonicalization, directory containment checks, ownership checks, symlink rejection, or validation that the file was uploaded by the current requester. The file is opened with the privileges of the skill process. If the service account can read a local audio-decodable file, an untrusted caller can potentially cause that file to be loaded. Its decoded contents are then sent to the external Gemini API through `session.send_realtime_input()`. This creates a confused-deputy condition: the caller can exercise the process's filesystem privileges even when the caller does not have direct access to the selected file. Successful exploitation requires the target file to exist, be readable by the skill process, and be decodable by the audio processing stack. ### Attack Path 1. An attacker reaches an integration that invokes `handle_request()` and permits control of `audio_path`. 2. The at ...[truncated 1076 chars]
- Remediation
- ## Remediation Suggestions - Do not accept arbitrary filesystem paths from request data. Accept an opaque upload identifier and resolve it through trusted server-side metadata. - Store uploaded audio in a dedicated directory owned by the service and configured with restrictive permissions. - Resolve the candidate path with `Path.resolve()` and verify that it remains within the dedicated upload directory. - Reject absolute paths, traversal components, symbolic links, non-regular files, device files, sockets, and named pipes. - Open files using mechanisms that prevent symlink following, such as `O_NOFOLLOW` where supported, and verify the opened descriptor with `fstat()`. - Confirm that the file belongs to the current request or authenticated user before processing it. - Enforce strict maximum file sizes, processing timeouts, and accepted media types. Validate file content rather than relying only on its extension. - Run the skill under a dedicated, unprivileged operating-system account that cannot read unrelated application or user data. - Clearly disclose that accepted audio is transmitted to Google Gemini and apply the required retention and consent controls.
