T09 · Insecure Skill Coding Practices
- Location
tts_service.py:237- Finding
Unrestricted local file upload permits disclosure of non-audio files
- Content
View full analysis
Vulnerability Details
File Location:
tts_service.py:237-251
Additional Affected Copies:scripts/tts_service.py:228-240,tts-voice-generator/tts_service.py:238-250, andtts-voice-generator/scripts/tts_service.py:228-240
Vulnerability Type: Arbitrary local file disclosure through unrestricted upload
Risk Level: HighVulnerable Code
python url = f"{self.base_url}/sys/openapi/tts/upload" try: # Construct parameters biz = style_name if style_name else "default" with open(file_path, 'rb') as f: files = {'file': f} data = {'biz': biz} if audio_text: data['audio_text'] = audio_text # Copy headers and let requests set Content-Type upload_headers = { k: v for k, v in self.headers.items() if k.lower() != 'content-type' } response = requests.post( url, files=files, data=data, headers=upload_headers, timeout=self.timeout )The CLI wrapper only checks that the supplied path exists:
python if not os.path.exists(file_path): print(f"Error: file does not exist: {file_path}") return service = TTSService(base_url, api_key) result = service.upload_audio(file_path, "uploaded_audio")Technical Analysis
The Skill documentation states that uploads should be WAV or MP3 audio files. The implementation does not enforce that restriction.
upload_audio()accepts an arbitrary path, opens the target as raw binary data, and transmits it to the remote upload endpoint.There is no validation of:
- The resolved file path or its containing directory
- The filename extension
- The file signature or actual media format
- The MIME type
- Whether the path is a regular file or a symbolic link
- File size
- Whether the user explicitly approved the resolved path
Consequen ...[truncated 1703 chars]
- Remediation
View remediation
Remediation Suggestions
- Resolve the path with
Path.resolve()and reject paths outside explicitly approved upload directories. - Require explicit user confirmation that displays the fully resolved path before transmitting the file.
- Permit only regular files and reject symbolic links, devices, directories, sockets, and other special filesystem objects.
- Apply an extension allowlist limited to
.wavand.mp3. - Validate file signatures and parse the file with a trusted audio library; do not rely solely on the extension or caller-provided MIME type.
- Set a strict maximum file size and, where practical, enforce expected duration and audio-stream constraints.
- Set an explicit validated MIME type in the multipart upload.
- Return an error before opening or transmitting any file that fails validation.
- Apply the fix consistently to all duplicated service implementations to prevent an older copy from remaining exploitable.
- Add automated tests for sensitive paths, symbolic links, renamed non-audio files, oversized files, and malformed media.
- Resolve the path with
