Skip to content

Sending a request disables TLS certificate verification for the whole extension host process #142

Description

@creomobile

What happens

When the extension sends a request, it sets NODE_TLS_REJECT_UNAUTHORIZED=0 on the shared VS Code extension host process. From that moment every extension in the window — and every child process any of them spawns — runs with TLS certificate verification disabled, until the window is reloaded.

Where

// TODO: Properly handle certificates. VS Code's @vscode/proxy-agent patches
// https.request and overrides agent TLS settings. As a workaround, we disable
// TLS verification at the process level for now.
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

// TODO: Properly handle certificates. VS Code's @vscode/proxy-agent patches
// https.request and overrides agent TLS settings. As a workaround, we disable
// TLS verification at the process level for now.
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

The reason for the workaround isn't in question — @vscode/proxy-agent does override agent-level TLS options, which is why setting rejectUnauthorized on the agent alone didn't resolve #48 / #53. What this report is about is its blast radius, which is wider than the problem it solves, in three separate ways:

  1. It is unconditional. rejectUnauthorized is destructured from httpsAgentOptions on the line directly above and then never used, and agentOpts hardcodes rejectUnauthorized: false. Verification is therefore off for every request, including for users who never asked to disable it.
  2. It is process-wide, not request-wide. process.env is shared by every extension in the extension host, so the change reaches unrelated extensions and anything they spawn.
  3. It is never restored. The previous value is neither saved nor put back.

Why it matters in practice

In our setup another extension launches a CLI as a child of the extension host. After any Bruno request, that CLI — and every tool it runs, in our case pnpm, wrangler and firebase-tools — inherits NODE_TLS_REJECT_UNAUTHORIZED=0. So package installs and deployments silently stop verifying certificates, in a window where nothing in our own configuration ever set that variable.

Steps to reproduce

  1. Open VS Code with the Bruno extension and any extension that spawns a child process.
  2. Have that extension spawn a process and check its environment — the variable is unset.
  3. Send any request from a Bruno collection.
  4. Spawn the process again — it now reports NODE_TLS_REJECT_UNAUTHORIZED=0.

One diagnostic note that may save someone time: /proc/<pid>/environ reports the environment a process started with, so the extension host itself looks clean there while its children do not. That is what makes this hard to trace back to an extension.

Suggested direction

At a minimum, gating the assignment on the collection's SSL-verification setting would confine it to users who actually asked for it. A proper fix would keep verification per request — for example by bypassing the patched https.request with a custom agent or dispatcher — rather than relying on process-wide state. (Saving and restoring the variable around each request would not be safe here, since requests can overlap.)

For reference, the main monorepo already does the per-agent version: in bruno-requests, src/utils/http-https-agents.ts defaults rejectUnauthorized to true and takes the value from the request's own options.

Environment

Bruno extension 5.0.2 · VS Code 1.134.0 (stable) · extension host Node 24.18.1 · Ubuntu 26.04 (WSL2), Remote-WSL

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions