Severity: MEDIUM
Description
The /v1/audio/transcriptions endpoint at routes/audio.py:49-51 reads the entire uploaded file into memory with no size limit:
with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
content = await file.read() # No size limit!
tmp.write(content)
tmp_path = tmp.name
Additionally:
- No content-type validation is performed on the uploaded file
- The file is written to disk with a
.wav suffix regardless of actual content
- No
max_length or size check is applied
Impact
A malicious client can upload a multi-gigabyte file to exhaust server memory, causing:
- OOM kill of the server process
- macOS memory pressure causing system-wide slowdown
- Potential crash of the MLX inference engine (GPU state corruption)
Reproduction
# Create a 2GB file
dd if=/dev/zero of=/tmp/large.wav bs=1M count=2048
# Upload to server — reads 2GB into memory
curl -X POST http://localhost:8000/v1/audio/transcriptions \
-H "Authorization: Bearer test123" \
-F "file=@/tmp/large.wav" \
-F "model=whisper-small"
Clean up:
Fix
Add size validation before reading the file body:
MAX_AUDIO_SIZE = 25 * 1024 * 1024 # 25 MB
# Read in chunks to check size
content = b""
async for chunk in file.stream():
content += chunk
if len(content) > MAX_AUDIO_SIZE:
raise HTTPException(status_code=413, detail="File too large")
Or use FastAPI's File() with max_length parameter, or check Content-Length header before reading.
File
vllm_mlx/routes/audio.py:49-51
Severity: MEDIUM
Description
The
/v1/audio/transcriptionsendpoint atroutes/audio.py:49-51reads the entire uploaded file into memory with no size limit:Additionally:
.wavsuffix regardless of actual contentmax_lengthor size check is appliedImpact
A malicious client can upload a multi-gigabyte file to exhaust server memory, causing:
Reproduction
Clean up:
Fix
Add size validation before reading the file body:
Or use FastAPI's
File()withmax_lengthparameter, or checkContent-Lengthheader before reading.File
vllm_mlx/routes/audio.py:49-51