T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/handler.py:71- Finding
Unrestricted Local Audio File Read and External Transmission
- Content
View full analysis
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: HighVulnerable 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_pathis passed directly tolibrosa.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
- An attacker reaches an integration that invokes
handle_request()and permits control ofaudio_path. - The at ...[truncated 1076 chars]
- An attacker reaches an integration that invokes
- Remediation
View 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_NOFOLLOWwhere supported, and verify the opened descriptor withfstat(). - 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.
