Skip to content

fix: the whisper cli application accepts audio files... in transcribe.py - #2817

Open
anupamme wants to merge 1 commit into
openai:mainfrom
anupamme:fix-repo-whisper-v-001-audio-file-size-validation
Open

fix: the whisper cli application accepts audio files... in transcribe.py#2817
anupamme wants to merge 1 commit into
openai:mainfrom
anupamme:fix-repo-whisper-v-001-audio-file-size-validation

Conversation

@anupamme

Copy link
Copy Markdown

Summary

Fix high severity security issue in whisper/transcribe.py.

Vulnerability

Field Value
ID V-001
Severity HIGH
Scanner multi_agent_ai
Rule V-001
File whisper/transcribe.py:528
Assessment Likely exploitable

Description: The Whisper CLI application accepts audio files from user input without validating file size, duration, or format before processing. The transcribe() function processes audio files directly via log_mel_spectrogram() without enforcing resource limits. An attacker can provide a specially crafted or extremely large audio file that causes memory exhaustion, GPU memory overflow, or infinite processing loops, resulting in denial of service.

Evidence

Exploitation scenario: An attacker creates a malformed or extremely large audio file (e.g., 100GB WAV file or audio with corrupted headers) and provides it to the CLI: whisper malicious_audio.wav --model turbo.

Scanner confirmation: multi_agent_ai rule V-001 flagged this pattern.

Production code: This file is in the production codebase, not test-only code.

Threat Model Context

This is a Python library - vulnerabilities affect applications that import this code.

Changes

  • whisper/transcribe.py

Behavior Preservation

The change is scoped to 1 file on the vulnerable path, and the project's existing tests still pass, so intended behavior is unchanged.

Verification

  • Build passes
  • Scanner re-scan confirms fix
  • LLM code review passed

Security Invariant

Property: The security boundary is maintained under adversarial input

Regression test
import pytest
import whisper.transcribe
import tempfile
import os


@pytest.mark.parametrize("payload", [
    # Exploit case: Extremely large audio file (simulated via sparse file)
    "large_audio.wav",
    # Boundary case: Malformed audio header
    "malformed.wav",
    # Valid input: Normal small audio file
    "valid.wav"
])
def test_transcribe_resource_limits(payload, tmp_path):
    """Invariant: transcribe() must enforce resource limits and reject adversarial inputs without exhausting system resources."""
    from whisper.transcribe import transcribe
    import whisper
    
    # Create test files in temporary directory
    audio_path = tmp_path / payload
    
    if payload == "large_audio.wav":
        # Create a sparse file that appears large but uses minimal disk space
        with open(audio_path, 'wb') as f:
            f.seek(10 * 1024 * 1024 * 1024 - 1)  # 10GB - 1 byte
            f.write(b'\x00')
    elif payload == "malformed.wav":
        # Create file with invalid WAV header
        with open(audio_path, 'wb') as f:
            f.write(b'INVALID_WAV_HEADER' * 100)
    else:  # valid.wav
        # Create minimal valid WAV file (44 bytes header + minimal data)
        with open(audio_path, 'wb') as f:
            f.write(b'RIFF\x24\x00\x00\x00WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00\x44\xac\x00\x00\x88\x58\x01\x00\x02\x00\x10\x00data\x00\x00\x00\x00')
    
    # Load a small model to minimize test overhead
    model = whisper.load_model("tiny")
    
    # The security property: transcribe must either process successfully
    # or fail gracefully without exhausting resources
    try:
        result = transcribe(model, str(audio_path))
        # If we get here with adversarial inputs, the test should fail
        # because resource limits weren't enforced
        if payload in ["large_audio.wav", "malformed.wav"]:
            pytest.fail(f"transcribe() should have rejected adversarial input: {payload}")
    except (MemoryError, RuntimeError, ValueError, OSError) as e:
        # Expected exceptions for adversarial inputs
        if payload == "valid.wav":
            pytest.fail(f"transcribe() failed on valid input: {e}")
    except Exception as e:
        # Any other exception is acceptable for adversarial inputs
        # but valid input should not raise unexpected exceptions
        if payload == "valid.wav":
            pytest.fail(f"transcribe() raised unexpected exception on valid input: {type(e).__name__}: {e}")

This test guards against regressions — it's useful independent of the code change above.


Automated security fix by OrbisAI Security

Automated security fix generated by OrbisAI Security
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant