Skip to content

Harden extension against local network and webview attacks - #40

Open
godronus wants to merge 2 commits into
mainfrom
fix/security-advisories
Open

Harden extension against local network and webview attacks#40
godronus wants to merge 2 commits into
mainfrom
fix/security-advisories

Conversation

@godronus

@godronus godronus commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Security hardening across six advisories:

Webview (SA-001, SA-002):

  • Add Content-Security-Policy with per-render nonce to debugger webview
  • Fix postMessage bridge: gate iframe commands on event.source + event.origin check
  • Replace postMessage(data, '*') with postMessage(data, FRAME_ORIGIN) on host responses
  • Restrict openExternal to http/https schemes only; refuse other URI handlers

Debugger server auth (SA-003):

  • Generate per-session token on DebuggerServerManager construction
  • Inject FASTEDGE_DEBUG_TOKEN and FASTEDGE_BIND_HOST=127.0.0.1 into forked server
  • Add x-fastedge-token header to all extension-side /api/* fetch calls
  • Deliver token to iframe via URL fragment (#token=...) for frontend auth

Autorun trigger file (SA-004):

  • Skip execution in untrusted workspaces
  • Require explicit user confirmation before running any trigger command
  • Remove commandArgs forwarding from trigger file

Port file trust (SA-006):

  • Gate .debug-port reuse on vscode.workspace.isTrusted; always spawn fresh in untrusted workspaces

MCP server config (SA-005):

  • Mask API key input (password: true)
  • Pin Docker image via mcp-server.version file injected at build time by esbuild
  • chmod 0600 on written mcp.json for local file URIs

Cleanup:

  • Delete src/dotenv/ — superseded by server-side dotenv handling in fastedge-test
  • Add MCP_INTEGRATION.md context doc covering version pinning mechanism
  • Add vitest.config.ts to mirror esbuild define for MCP_SERVER_VERSION
  • Add tests: webview HTML security properties, trigger file guards, mcpJson image pin

Security hardening across six advisories:

Webview (SA-001, SA-002):
- Add Content-Security-Policy with per-render nonce to debugger webview
- Fix postMessage bridge: gate iframe commands on event.source + event.origin check
- Replace postMessage(data, '*') with postMessage(data, FRAME_ORIGIN) on host responses
- Restrict openExternal to http/https schemes only; refuse other URI handlers

Debugger server auth (SA-003):
- Generate per-session token on DebuggerServerManager construction
- Inject FASTEDGE_DEBUG_TOKEN and FASTEDGE_BIND_HOST=127.0.0.1 into forked server
- Add x-fastedge-token header to all extension-side /api/* fetch calls
- Deliver token to iframe via URL fragment (#token=...) for frontend auth

Autorun trigger file (SA-004):
- Skip execution in untrusted workspaces
- Require explicit user confirmation before running any trigger command
- Remove commandArgs forwarding from trigger file

Port file trust (SA-006):
- Gate .debug-port reuse on vscode.workspace.isTrusted; always spawn fresh in untrusted workspaces

MCP server config (SA-005):
- Mask API key input (password: true)
- Pin Docker image via mcp-server.version file injected at build time by esbuild
- chmod 0600 on written mcp.json for local file URIs

Cleanup:
- Delete src/dotenv/ — superseded by server-side dotenv handling in fastedge-test
- Add MCP_INTEGRATION.md context doc covering version pinning mechanism
- Add vitest.config.ts to mirror esbuild define for __MCP_SERVER_VERSION__
- Add tests: webview HTML security properties, trigger file guards, mcpJson image pin
Copilot AI lite review requested due to automatic review settings September 7, 2026 12:34

Copilot AI 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.

🟡 Changes recommended

The debugger server reuse path can select an existing server whose auth token won’t match the new per-instance token, which can break authenticated /api/* calls and iframe auth after extension host restarts.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR hardens the FastEdge VS Code extension against webview/message-bridge abuse, local-network debugger server exposure, and insecure MCP config handling by adding stricter isolation (CSP + origin gating), per-session auth tokens, and safer file/secret practices.

Changes:

  • Webview hardening: per-render CSP nonce, stricter postMessage bridge checks/target origins, and openExternal restricted to http/https.
  • Debugger server auth & trust: per-session token injected into the server process + added to extension /api/* calls; .debug-port reuse gated by workspace trust.
  • MCP config hardening: pin MCP Docker image tag via build-time injected __MCP_SERVER_VERSION__, mask API key input, and apply best-effort chmod 0600 for local mcp.json; adds Vitest coverage and docs.
File summaries
File Description
vitest.config.ts Injects __MCP_SERVER_VERSION__ into tests to mirror esbuild behavior.
src/globals.d.ts Declares build-time injected constant for TypeScript.
src/dotenv/index.ts Removes deprecated dotenv logic (superseded by server-side handling).
src/debugger/DebuggerWebviewProvider.ts Adds CSP nonce, origin-gated message bridge, token propagation, and http/https-only openExternal.
src/debugger/DebuggerWebviewProvider.test.ts Tests for key webview HTML security properties (CSP nonce, non-wildcard origins, token fragment).
src/debugger/DebuggerServerManager.ts Adds per-instance token injection and trust-gated .debug-port reuse; sends token on /api/* calls.
src/commands/mcpJson.ts Pins MCP Docker image version via injected constant; masks API key input; best-effort chmod 0600 on local mcp.json.
src/commands/mcpJson.test.ts Verifies pinned MCP image tag (not :latest).
src/autorun/triggerFileHandler.ts Exports trigger executor; blocks execution in untrusted workspaces; adds user confirmation; removes arg forwarding.
src/autorun/triggerFileHandler.test.ts Tests untrusted-workspace guard, confirmation gating, and “no args forwarded” invariant.
mcp-server.version Single source of truth for the pinned MCP server image tag.
esbuild/build-ext.js Reads mcp-server.version and injects __MCP_SERVER_VERSION__ at build time.
context/features/MCP_INTEGRATION.md Documents MCP generation and the version pinning/bump process.
context/CONTEXT_INDEX.md Adds a task entry for bumping the pinned MCP server version.
Review details
  • Files reviewed: 13/14 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/debugger/DebuggerServerManager.ts
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI 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.

🟡 Changes recommended

The trigger file handler decodes workspace.fs.readFile() via .toString(), which is not reliable UTF-8 decoding for a generic Uint8Array and can break command parsing.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 13/14 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment on lines +85 to 88
export async function executeTriggerFile(
uri: vscode.Uri,
outputChannel: vscode.OutputChannel,
): Promise<void> {
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