Skip to content

fix(security): make MCP_UPLOAD_BASE_DIR mandatory for all upload tools - #420

Merged
gaurav-singh-9227 merged 5 commits into
browserstack:mainfrom
SavioBS629:security/mandatory-upload-basedir
Sep 16, 2026
Merged

gaurav-singh-9227 merged 5 commits into
browserstack:mainfrom
SavioBS629:security/mandatory-upload-basedir

Conversation

@SavioBS629

Copy link
Copy Markdown
Collaborator

Problem

Directory containment in validateUploadPath was opt-in: the base-dir prefix check only ran if (options.allowedBaseDir), and MCP_UPLOAD_BASE_DIR is unset by default. With it unset, any caller-supplied absolute path to a non-hidden, allow-listed-extension file was accepted, streamed to BrowserStack, and returned as a signed download URL — an arbitrary file read / exfiltration on a default install (GHSA-j4xm-vw5v-c87v).

A previous change added a refuse gate only to the upload-PRD tool (upload-file.ts). The other three upload paths go through the same shared validator and remained exposed:

Tool File
takeAppScreenshotuploadApp appautomate.ts:149
uploadEspressoAppuploadFileToBrowserStack appautomate.ts:183
runAppLiveSession → app upload applive-utils/upload-app.ts:20

Fix

Make containment mandatory in validateUploadPath itself: refuse the upload unless allowedBaseDir is configured, then enforce that the canonicalised path lives inside it. Because all four upload tools share this validator, one change closes the gap uniformly (rather than three separate per-tool gates).

⚠️ Behavior change

App Automate app upload, Espresso app upload, and App Live sessions now require MCP_UPLOAD_BASE_DIR to be set — the same requirement already in place for the upload-PRD tool. Uploads are restricted to that directory.

Testing

  • npm run lint, tsc --noEmit, and vitest run pass. Added validator cases: refuses when no base dir is configured, refuses when the configured base dir doesn't exist, plus the existing containment/extension/hidden-path/size/symlink coverage.
  • Pre-existing unrelated flakes in buildFailureThemes / tfaRcaCollaboration are present on main and untouched.

🤖 Generated with Claude Code

SavioBS629 and others added 2 commits September 15, 2026 18:48
Directory containment in validateUploadPath was opt-in: the base-dir
prefix check only ran when allowedBaseDir was set, and MCP_UPLOAD_BASE_DIR
is unset by default. With it unset, any caller-supplied absolute path to a
non-hidden, allow-listed-extension file was accepted and streamed to
BrowserStack — an arbitrary file read/exfiltration on a default install
(GHSA-j4xm-vw5v-c87v).

Only the upload-PRD tool (upload-file.ts) had its own refuse gate; the
App Automate (uploadApp, uploadEspressoApp) and App Live (app upload)
paths went through the same opt-in validator and remained exposed.

Make containment mandatory in validateUploadPath itself: refuse the
upload unless allowedBaseDir is configured, then enforce that the
canonical path lives inside it. This covers every upload tool uniformly
via the single shared validator.

Behavior change: App Automate app upload, Espresso app upload, and App
Live sessions now require MCP_UPLOAD_BASE_DIR to be set (same requirement
already in place for the upload-PRD tool).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…e message

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited), Workspace UI (inherited)

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 8bb0afab-13fc-4148-88a2-64325c56d9ac

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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

SavioBS629 and others added 3 commits September 16, 2026 18:41
…oad types

Address review feedback on the mandatory upload base-dir change:

- README: add an "Enabling File & App Uploads" section explaining
  MCP_UPLOAD_BASE_DIR — what it is, an example env entry, and the four
  tools that require it (uploadProductRequirementFile, takeAppScreenshot,
  runAppTestsOnBrowserStack, runAppLiveSession). Without this the change
  looks like the upload tools "just broke" on a default install.
- upload-validator: make `allowedBaseDir` a required key (value may be
  undefined) so every call site must consciously thread the configured
  base dir — a missing one becomes a compile error instead of a silent
  runtime always-refuse.
- App/test path tool descriptions now note the file must live inside
  MCP_UPLOAD_BASE_DIR, so the model doesn't confidently pass paths that
  will be refused.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gaurav-singh-9227
gaurav-singh-9227 merged commit b089124 into browserstack:main Sep 16, 2026
2 checks passed
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.

2 participants