Skip to content

fix: harden dashboard and inspect local control planes#1346

Open
Muhtasham wants to merge 4 commits into
vercel-labs:mainfrom
Muhtasham:feat/harden-dashboard-cors
Open

fix: harden dashboard and inspect local control planes#1346
Muhtasham wants to merge 4 commits into
vercel-labs:mainfrom
Muhtasham:feat/harden-dashboard-cors

Conversation

@Muhtasham
Copy link
Copy Markdown
Contributor

@Muhtasham Muhtasham commented May 10, 2026

Summary

  • build on upstream Require same-origin stream commands #1355, which already fixed the per-session /api/command relay issue from Per-session /api/command should require same-origin or token auth #1344
  • reject cross-origin requests before dispatching dashboard control-plane POST routes (/api/exec, /api/sessions, /api/kill)
  • stop emitting wildcard CORS on standalone dashboard API responses
  • require same-origin Origin or Referer before /api/sessions can spawn browser sessions
  • require same-origin Origin for dashboard WebSocket proxy routes when a browser Origin is present
  • require a generated capability token and local browser Origin for inspect-mode DevTools WebSocket handshakes
  • add unit coverage for shared same-origin HTTP helpers, dashboard WebSocket origin checks, /api/sessions rejection, and inspect-mode token/origin checks

Fixes #1345.
Fixes #1347.

Validation

  • cargo fmt --manifest-path cli/Cargo.toml -- --check
  • cargo test --manifest-path cli/Cargo.toml native::stream::http::tests -- --test-threads=1 --nocapture
  • cargo test --manifest-path cli/Cargo.toml native::stream:: -- --test-threads=1 --nocapture
  • cargo test --manifest-path cli/Cargo.toml native::inspect_server::tests -- --nocapture
  • cargo clippy --manifest-path cli/Cargo.toml -- -D warnings
  • Runtime dashboard smoke on port 4860: evil-origin preflight and POST to /api/exec now return 403 without CORS; same-origin POST still returns 200.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 10, 2026

@Muhtasham is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

@Muhtasham Muhtasham force-pushed the feat/harden-dashboard-cors branch from e461dbf to f84bd5e Compare May 10, 2026 17:58
Copy link
Copy Markdown
Contributor

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

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

Additional Suggestion:

WebSocket connections in dashboard.rs lack DNS rebinding protection that was added to http.rs, allowing attackers to bypass same-origin checks via DNS rebinding attacks.

Fix on Vercel

@Muhtasham
Copy link
Copy Markdown
Contributor Author

Additional Suggestion:

WebSocket connections in dashboard.rs lack DNS rebinding protection that was added to http.rs, allowing attackers to bypass same-origin checks via DNS rebinding attacks.

Fix on Vercel

Thanks for flagging this. I independently reached the same conclusion during a follow-up security pass: the dashboard WebSocket proxy was still using an older Host/Origin authority match that did not include the DNS-rebinding hardening added for the HTTP routes.

I pushed 183e74a, which moves the dashboard WebSocket stream check onto the same hardened helper and adds a regression test for:

  • Host: evil.example:<port>
  • Origin: http://evil.example:<port>

Validation run locally:

  • cargo fmt --manifest-path cli/Cargo.toml -- --check
  • cargo clippy --manifest-path cli/Cargo.toml -- -D warnings
  • cargo test --manifest-path cli/Cargo.toml native::stream:: -- --nocapture

That focused stream suite passes with the new regression coverage.

@Muhtasham Muhtasham changed the title fix: restrict dashboard control-plane CORS fix: harden dashboard and inspect local control planes May 10, 2026
@Muhtasham
Copy link
Copy Markdown
Contributor Author

Muhtasham commented May 10, 2026

Follow-up:

  • Confirmed the dashboard HTTP and dashboard WebSocket paths are now covered by the same-origin hardening in this PR.
  • Found one separate local-control-plane gap in agent-browser inspect: the DevTools /ws proxy path was independent from the dashboard stream path.
  • Opened Harden inspect-mode DevTools WebSocket handshakes #1347 to track that gap and pushed 31e6dee to address it in this PR.

The new patch tokenizes the generated inspect DevTools ws= URL, validates that token during the WebSocket handshake, and rejects non-local browser Origin values before creating a DevTools session.

Validation run:

  • cargo fmt --manifest-path cli/Cargo.toml -- --check
  • cargo test --manifest-path cli/Cargo.toml native::inspect_server::tests -- --nocapture
  • cargo test --manifest-path cli/Cargo.toml native::stream:: -- --nocapture
  • cargo clippy --manifest-path cli/Cargo.toml -- -D warnings

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.

Harden inspect-mode DevTools WebSocket handshakes Dashboard privileged POST routes should reject cross-origin requests

1 participant