Skip to content

fix(analysis): bound temporal decode size and duration - #121

Merged
seonghobae merged 4 commits into
developfrom
codex/fix-temporal-analyzer-memory-vulnerability
Jun 10, 2026
Merged

fix(analysis): bound temporal decode size and duration#121
seonghobae merged 4 commits into
developfrom
codex/fix-temporal-analyzer-memory-vulnerability

Conversation

@seonghobae

Copy link
Copy Markdown
Collaborator

Motivation

  • The temporal analyzer previously used librosa.load without duration or file-size guards which allowed decoding arbitrarily large local audio files into memory and created a local DoS vector when the CLI invoked analysis early in the flow.
  • The change aims to ensure temporal analysis enforces conservative, testable bounds so callers (including the CLI) cannot trigger unbounded CPU/memory work by supplying huge files.

Description

  • Added MAX_AUDIO_FILE_BYTES = 100 * 1024 * 1024 and MAX_ANALYSIS_DURATION_SECONDS = 15 * 60 and validate Path.stat().st_size to reject oversized files before any decode.
  • Bound decoding by passing duration=MAX_ANALYSIS_DURATION_SECONDS into librosa.load and normalize audio_path to a Path for reliable stat checks.
  • Added regression tests in services/analysis-engine/tests/test_temporal.py to assert oversized files are rejected before librosa.load is called and that the duration kwarg is passed into librosa.load.
  • Security Notes: untrusted local audio paths are validated at the analyzer boundary, violations raise ValueError so existing CLI exception handling preserves safe failure, no new sensitive logging is added, and test points cover the protections.

Testing

  • Ran uv run --project services/analysis-engine pytest services/analysis-engine/tests/test_temporal.py services/analysis-engine/tests/test_cli.py which executed the temporal and CLI tests.
  • Test result: 21 passed (with harmless deprecation warnings) and no regressions observed.

Codex Task

@coderabbitai

coderabbitai Bot commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@seonghobae, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 31 minutes and 1 second. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7a35b2f8-b7bd-48c3-a790-ce1b831c4528

📥 Commits

Reviewing files that changed from the base of the PR and between b785ee4 and 0e7e2e7.

📒 Files selected for processing (2)
  • services/analysis-engine/src/bandscope_analysis/temporal/analyzer.py
  • services/analysis-engine/tests/test_temporal.py
📝 Walkthrough

Walkthrough

TemporalAnalyzer.analyze 메서드에 두 가지 하드 리밋이 추가되었습니다. 입력 파일의 바이트 크기를 확인하여 MAX_AUDIO_FILE_BYTES를 초과하면 ValueError를 발생시키고, librosa 디코딩 시 MAX_ANALYSIS_DURATION_SECONDS로 분석 지속 시간을 제한합니다.

Changes

Cohort / File(s) Summary
Temporal Analyzer Core
services/analysis-engine/src/bandscope_analysis/temporal/analyzer.py
두 개의 모듈 레벨 상수 추가: MAX_AUDIO_FILE_BYTES (100MB) 및 MAX_ANALYSIS_DURATION_SECONDS (900초). analyze 메서드에서 파일 크기 검증 및 librosa 디코딩 시 duration 제한 추가.
Temporal Analyzer Tests
services/analysis-engine/tests/test_temporal.py
파일 크기 초과 시 librosa.load 호출 방지 검증과 duration 파라미터 전달 검증을 위한 두 개의 새 단위 테스트 추가.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Poem

🐰 파일의 크기를 점검하고,
시간의 경계를 그으니,
안전한 분석의 길이 열렸네!
무한을 제어하는 지혜,
토끼가 박수를 치며 춤을 춘다 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main change: adding bounds to temporal decode size and duration in the analysis engine.
Description check ✅ Passed The description provides detailed motivation, implementation details, security considerations, and testing information directly related to the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-temporal-analyzer-memory-vulnerability
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch codex/fix-temporal-analyzer-memory-vulnerability

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@services/analysis-engine/src/bandscope_analysis/temporal/analyzer.py`:
- Around line 44-57: The code does a TOCTOU by calling path.stat() then later
calling librosa.load(path_str); instead open the file once and use the same file
handle to both check size and decode to prevent replacement: use Path.open() to
get a file object, obtain size via fileobj.seek(0,2)/tell() or
os.fstat(fileobj.fileno()) and compare with MAX_AUDIO_FILE_BYTES, then pass that
same file object to librosa.load (it accepts a file-like object) with the
existing TARGET_SR and MAX_ANALYSIS_DURATION_SECONDS; replace usages of
path.stat() and path_str with the single file handle so the check and load occur
on the same descriptor.

In `@services/analysis-engine/tests/test_temporal.py`:
- Line 107: The failing Ruff E501 is caused by an overlong line where
monkeypatch.setattr is called with an inline lambda for librosa.beat.beat_track;
break the long statement into multiple shorter lines (under 100 chars) by either
defining a small helper function (e.g., def fake_beat_track(y, sr): return
np.array([120.0]), np.array([0])) and passing that to monkeypatch.setattr, or
assign the lambda to a named variable before calling monkeypatch.setattr; update
the call in test_temporal.py to use the helper or named variable to satisfy the
line-length limit while keeping the same behavior.
- Line 113: Replace the magic number assertion in test_temporal.py—assert
captured_kwargs["duration"] == 15 * 60—with a direct comparison to the
implementation constant from the module under test: import the appropriate
constant (the duration/timeout constant used by the code that populates
captured_kwargs, e.g., DURATION_SECONDS or DEFAULT_TIMEOUT) and assert
captured_kwargs["duration"] == <IMPORTED_CONSTANT>; remove the literal 15 * 60
so the test tracks the implementation constant.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d3ecdc96-7696-455b-beaf-681dcb290b14

📥 Commits

Reviewing files that changed from the base of the PR and between f6cbd3b and b785ee4.

📒 Files selected for processing (2)
  • services/analysis-engine/src/bandscope_analysis/temporal/analyzer.py
  • services/analysis-engine/tests/test_temporal.py

Comment thread services/analysis-engine/src/bandscope_analysis/temporal/analyzer.py Outdated
Comment thread services/analysis-engine/tests/test_temporal.py Outdated
Comment thread services/analysis-engine/tests/test_temporal.py Outdated
@seonghobae
seonghobae changed the base branch from develop to main April 28, 2026 12:14
@seonghobae
seonghobae changed the base branch from main to develop April 28, 2026 15:47
@seonghobae
seonghobae enabled auto-merge June 10, 2026 13:50
@seonghobae

Copy link
Copy Markdown
Collaborator Author

@coderabbitai resolve

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Comments resolved and changes approved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant