Skip to content

fix[notask]: harden benchmark servers against RCE, path traversal, injection, DoS, and CSRF#1086

Merged
sharmaraju352 merged 6 commits into
mainfrom
fix/benchmark-server-security-hardening
Mar 25, 2026
Merged

fix[notask]: harden benchmark servers against RCE, path traversal, injection, DoS, and CSRF#1086
sharmaraju352 merged 6 commits into
mainfrom
fix/benchmark-server-security-hardening

Conversation

@sharmaraju352

Copy link
Copy Markdown
Contributor

Summary

  • Fix 5 security vulnerabilities in the whispercpp and parakeet benchmark servers identified during security audit
  • Addresses: Remote Code Execution, arbitrary file read, CLI argument injection, unbounded request body, and wildcard CORS

Findings Addressed

1. 🔴 Critical — RCE via dynamic require() of user-controlled package name

Both runAddon.js files accepted a user-controlled lib field, ran npm install on it, then require()'d it. Added ALLOWED_LIBS allowlist — rejects any library not in the list before ensurePackage() is called.

2. 🔴 Critical — Arbitrary file read via user-controlled file paths

The inputs array and config.path were passed to fs.readFileSync() without validation. Added validateFilePath() that resolves the path and verifies existence before any file I/O.

3. :large_orange_circle: High — CLI argument injection in runAddon.cli.js

User-supplied file paths were passed directly to spawn('ffmpeg', ...). Added validatePath() + -- argument separator to prevent flag injection, and fixed .replace('.raw', '.wav') to use regex anchor \.raw$.

4. :large_orange_circle: High — No request body size limit in parakeet helper.js

The parakeet server's processJsonRequest() had no size limit (the whisper server already had one). Added 1 MB cap matching the whisper implementation.

5. :large_orange_circle: High — Wildcard CORS (Access-Control-Allow-Origin: *)

Both servers allowed any origin. Replaced with dynamic origin validation that only allows localhost and 127.0.0.1 origins, with Vary: Origin header.

Files Changed (6)

File Fixes
whispercpp/benchmarks/server/src/services/runAddon.js #1, #2
whispercpp/benchmarks/server/src/services/runAddon.cli.js #3
whispercpp/benchmarks/server/src/server.js #5
parakeet/benchmarks/server/src/services/runAddon.js #1, #2
parakeet/benchmarks/server/src/server.js #5
parakeet/benchmarks/server/src/utils/helper.js #4

How was it tested?

  • Whisper unit tests (before & after): 24/24 pass, 90/90 assertions
  • Parakeet unit tests (before & after): 11/11 pass, 55/55 assertions
  • SDK integration (before & after): whispercpp-filesystem.ts produces identical output
  • Lint: All 6 files pass standard linter with zero errors
  • Benchmark server changes are JS-only — no native addon rebuild needed

Made with Cursor

…jection, DoS, and CSRF

Security audit identified 5 vulnerabilities in the whispercpp and
parakeet benchmark servers:

1. RCE via dynamic require() of user-controlled package name — add
   ALLOWED_LIBS allowlist to both runAddon.js files
2. Arbitrary file read via unsanitized inputs paths — add
   validateFilePath() that resolves and checks existence
3. CLI argument injection via crafted file paths — add path validation
   and -- separator in runAddon.cli.js ffmpeg args
4. No request body size limit in parakeet helper.js — add 1 MB cap
   matching the whisper server implementation
5. Wildcard CORS (Access-Control-Allow-Origin: *) — restrict to
   localhost/127.0.0.1 origins in both server.js files

Made-with: Cursor
@sharmaraju352 sharmaraju352 requested review from a team as code owners March 23, 2026 10:54
GustavoA1604
GustavoA1604 previously approved these changes Mar 23, 2026
@github-actions

github-actions Bot commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

Tier-based Approval Status

**PR Tier:** TIER1

**Current Status:** ✅ APPROVED

**Requirements:**
- 1 Team Member approval ✅ (1/1)
- 1 Team Lead OR Management approval ✅ (1/1)



---
*This comment is automatically updated when reviews change.*

@ogad-tether

Copy link
Copy Markdown
Contributor

the hardening is incomplete. validateFilePath() still allows reading any existing file, the whisper version field still feeds npm install, and the ffmpeg -i -- file change is likely wrong.

1. validateFilePath now restricts to ALLOWED_AUDIO_DIRS (cwd, models,
   examples) instead of just checking existence — prevents reading
   arbitrary files outside the benchmark directory
2. Remove ensurePackage/npm install entirely — the ALLOWED_LIBS check
   already prevents arbitrary packages, so just use getPackageVersion
   for version reporting on pre-installed packages
3. Revert ffmpeg -- syntax — -i expects the filename as immediate next
   arg, -- is not valid between a flag and its value
4. Remove unused spawn/version destructuring to fix lint errors

Made-with: Cursor
@sharmaraju352

Copy link
Copy Markdown
Contributor Author

/review

@sharmaraju352

Copy link
Copy Markdown
Contributor Author

/review

@sharmaraju352 sharmaraju352 merged commit 3f7894c into main Mar 25, 2026
48 of 54 checks passed
@sharmaraju352 sharmaraju352 deleted the fix/benchmark-server-security-hardening branch March 25, 2026 06:30
Proletter pushed a commit that referenced this pull request May 24, 2026
…jection, DoS, and CSRF (#1086)

* fix[notask]: harden benchmark servers against RCE, path traversal, injection, DoS, and CSRF

Security audit identified 5 vulnerabilities in the whispercpp and
parakeet benchmark servers:

1. RCE via dynamic require() of user-controlled package name — add
   ALLOWED_LIBS allowlist to both runAddon.js files
2. Arbitrary file read via unsanitized inputs paths — add
   validateFilePath() that resolves and checks existence
3. CLI argument injection via crafted file paths — add path validation
   and -- separator in runAddon.cli.js ffmpeg args
4. No request body size limit in parakeet helper.js — add 1 MB cap
   matching the whisper server implementation
5. Wildcard CORS (Access-Control-Allow-Origin: *) — restrict to
   localhost/127.0.0.1 origins in both server.js files

Made-with: Cursor

* fix[notask]: address review feedback on benchmark server hardening

1. validateFilePath now restricts to ALLOWED_AUDIO_DIRS (cwd, models,
   examples) instead of just checking existence — prevents reading
   arbitrary files outside the benchmark directory
2. Remove ensurePackage/npm install entirely — the ALLOWED_LIBS check
   already prevents arbitrary packages, so just use getPackageVersion
   for version reporting on pre-installed packages
3. Revert ffmpeg -- syntax — -i expects the filename as immediate next
   arg, -- is not valid between a flag and its value
4. Remove unused spawn/version destructuring to fix lint errors

Made-with: Cursor

---------

Co-authored-by: Raju <raju.sharma>
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.

3 participants