Skip to content

Integrated Browser: file:// preview is blocked with 403 even when Workspace Trust is disabled (security.workspace.trust.enabled: false) #320830

Description

Does this issue occur when all extensions are disabled?: Yes

  • VS Code Version: 1.124.0
  • OS Version: macOS 14.7.7 (Sonoma), iMac (Late 2013, Intel Core i5, 24 GB RAM)
    • Note: this machine runs Sonoma via OpenCore Legacy Patcher. However, the behavior described below is reproducible from source-level logic that is platform-independent (see Root cause), so it is not specific to this hardware or to macOS.

Summary

When previewing a standalone .html file in the Integrated Browser without any folder/workspace open (empty window), the preview is blocked with:

Forbidden. File does not reside within a trusted folder.

This happens even when Workspace Trust is fully disabled, with the following user settings:

{
  "security.workspace.trust.enabled": false,
  "security.workspace.trust.untrustedFiles": "open",
  "security.workspace.trust.emptyWindow": true
}

Setting security.workspace.trust.enabled: false is an explicit declaration that the user trusts all local content. The editor honors this (files open without any prompt), but the Integrated Browser's file:// handler does not, which is inconsistent. Rendering a file in the sandboxed browser view is arguably a weaker operation than opening it in the editor with full extension/task capabilities, yet only the former is blocked.

Additionally, because the Workspaces: Manage Workspace Trust command is hidden when security.workspace.trust.enabled is false (its precondition requires the setting to be true), the user has no discoverable way to fix the 403: the only UI that could add a trusted folder is unreachable in exactly the configuration that triggers the problem.

Steps to Reproduce

  1. Set "security.workspace.trust.enabled": false in user settings.
  2. Open a new empty VS Code window (no folder/workspace).
  3. Open any local .html file (File > Open...). It opens in the editor without any trust prompt, as expected.
  4. Preview it in the Integrated Browser (e.g. Show Preview in the editor title bar, or navigate to the file:// URL in the browser tab).
  5. The browser renders: Forbidden. File does not reside within a trusted folder. (HTTP 403).
  6. Try to add the folder as trusted: Ctrl/Cmd+Shift+P → "Manage Workspace Trust" — the command does not appear, because Workspace Trust is disabled.

Expected Behavior

With security.workspace.trust.enabled: false, file:// navigation in the Integrated Browser should be allowed (the user has globally opted out of the trust model), or at minimum the empty-window trust settings (security.workspace.trust.emptyWindow, untrustedFiles: "open") should be honored.

Root Cause (from source)

The 403 is returned by the file:// protocol handler in
src/vs/platform/browserView/electron-main/browserSession.ts:

this.electronSession.protocol.handle(Schemas.file, request => {
    const filePath = normalize(URI.parse(request.url).fsPath);
    if (!BrowserSession._trustedFileRoots.findSubstr(filePath)) {
        return new Response(localize('browserSession.untrustedFile',
            'Forbidden. File does not reside within a trusted folder.'), { status: 403 });
    }
    ...
});

_trustedFileRoots is populated by sendTrustedFileRoots() in
src/vs/workbench/contrib/browserView/electron-browser/browserViewWorkbenchService.ts, which only considers:

  1. the current workspace folders (if isWorkspaceTrusted()), and
  2. workspaceTrustManagementService.getTrustedUris() (the persisted "Trusted Folders & Workspaces" list).

The security.workspace.trust.enabled flag is never consulted in this computation. In an empty window there are no workspace folders (so #1 contributes nothing regardless of emptyWindow: true), and a user who has had trust disabled has an empty trusted-URI list (so #2 is empty). The result is an empty root set and an unconditional 403 for every file:// URL.

So the two trust systems are disconnected: the workbench short-circuits to "everything trusted" when the feature is disabled, but the browserView trust-roots computation has no concept of that state.

Workaround (confirmed)

  1. Temporarily set "security.workspace.trust.enabled": true and reload.
  2. Run Workspaces: Manage Workspace Trust → "Trusted Folders & Workspaces" → Add Folder → add a parent folder of the HTML files (e.g. the user home directory).
  3. Set the setting back to false and reload.

The persisted trusted-URI list (content.trust.model.key, application storage) is loaded unconditionally by getTrustedUris(), so the preview keeps working afterwards. This confirms the mechanism, but it relies on undocumented behavior and requires toggling a security setting just to reach the relevant UI.

Suggested Fix

In sendTrustedFileRoots(), when workspaceTrustEnablementService.isWorkspaceTrustEnabled() is false, either treat all local files as trusted (consistent with how the rest of the workbench behaves in that state), or honor the empty-window trust result for the file roots as well.

Metadata

Metadata

Labels

browser-integrationWeb browsing features integrated into VS Code (e.g. integrated browser)bugIssue identified by VS Code Team member as probable buginsiders-releasedPatch has been released in VS Code InsidersverifiedVerification succeeded

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions