T09 · Insecure Skill Coding Practices
- Location
scripts/extract-audio-data.py:91- Finding
Unbounded FPS and Frequency-Band Parameters Can Cause Resource Exhaustion
- Content
View full analysis
Vulnerability Details
File Location:
scripts/extract-audio-data.py, lines 91-112 and 157-160
Vulnerability Type: Uncontrolled resource consumption
Risk Level: MediumVulnerable Code
python duration = len(samples) / SAMPLE_RATE frame_step = SAMPLE_RATE // fps total_frames = int(duration * fps) # Precompute constants hann = np.hanning(FFT_SIZE) band_edges = compute_band_edges(n_bands) freq_per_bin = SAMPLE_RATE / FFT_SIZE n_bins = FFT_SIZE // 2 + 1 half_fft = FFT_SIZE // 2 # Pass 1: extract raw values rms_values = np.zeros(total_frames) band_values = np.zeros((total_frames, n_bands))The command-line validation only enforces lower bounds:
python if args.fps < 1: parser.error("--fps must be at least 1") if args.bands < 1: parser.error("--bands must be at least 1")Technical Analysis
The user-controlled
--fpsand--bandsarguments have no upper bounds. These values directly determine the dimensions of NumPy arrays and the number of FFT-band processing operations:total_framesgrows according to the media duration multiplied byfps.band_valuesallocates approximatelytotal_frames × n_bands × 8bytes with its default NumPy floating-point type.- The processing loop performs work for every frame and every frequency band.
- If
fpsexceedsSAMPLE_RATE, integer division makesframe_stepequal to zero. The program can then repeatedly process the same audio position while still allocating and iterating over an extremely large number of frames.
Although the input is passed to
ffmpegusing an argument array and therefore does not create a shell-command injection issue, unrestricted numeric dimensions allow an invocation to consume excessive memory and CPU.Attack Path
-
An attacker or untrusted automation gains the ability to influence arguments supplied to
extract-audio-data.py. -
The attacker provides a valid media file and an extreme parameter, for example:
bash p
...[truncated 1357 chars]
- Remediation
View remediation
Remediation Suggestions
-
Enforce conservative upper bounds for both arguments. For example, permit only rendering-relevant frame rates and a reasonable number of bands:
python MAX_FPS = 240 MAX_BANDS = 128 if not 1 <= args.fps <= MAX_FPS: parser.error(f"--fps must be between 1 and {MAX_FPS}") if not 1 <= args.bands <= MAX_BANDS: parser.error(f"--bands must be between 1 and {MAX_BANDS}") -
Explicitly reject frame rates above
SAMPLE_RATEsoframe_stepcannot become zero:python if args.fps > SAMPLE_RATE: parser.error(f"--fps must not exceed the sample rate ({SAMPLE_RATE})") -
Calculate estimated memory usage before allocating arrays and reject jobs that exceed a configured budget:
python estimated_bytes = total_frames * 8 estimated_bytes += total_frames * n_bands * 8 MAX_MEMORY_BYTES = 512 * 1024 * 1024 if estimated_bytes > MAX_MEMORY_BYTES: raise ValueError("Requested analysis exceeds the configured memory limit") -
Impose limits on media duration and maximum output frame count, particularly when media files or command-line arguments originate from untrusted users.
-
Avoid retaining all frame data in memory when large inputs must be supported. Process frames incrementally and stream JSON output, or write batches to a temporary output file with controlled size limits.
-
Run extraction jobs with operating-system or container resource controls, including memory, CPU-time, file-size, and execution-time limits.
-
Add automated tests covering extreme
fps,bands, duration, and estimated-output-size combinations to verify that invalid jobs fail before expensive allocations or processing begin.
-
