Safeguard
Security

https-proxy-agent: What It Does and How to Use It Safely

A practical security review of https-proxy-agent, the Node.js module that tunnels HTTPS through an HTTP proxy, plus the advisories worth knowing before you pin a version.

Marcus Chen
DevSecOps Engineer
6 min read

https-proxy-agent is a small Node.js module that lets an HTTPS request tunnel through an HTTP(S) proxy, and while the current releases are healthy, older pinned versions carry real vulnerabilities you should upgrade away from. If you run anything that talks to the internet from behind a corporate proxy, you are almost certainly shipping this package, often three or four levels deep in your dependency tree.

This guide covers what the module does, the advisories that have affected it, and how to keep it from becoming the weak link in an outbound connection.

What https-proxy-agent actually does

Node's http and https clients accept a custom agent that controls how sockets get opened. The https proxy agent implements that interface. When you make an HTTPS request through it, the agent first opens a plain connection to the proxy, issues an HTTP CONNECT to establish a tunnel to the real destination, and then performs the TLS handshake with the target server over that tunnel.

A minimal usage looks like this:

const { HttpsProxyAgent } = require('https-proxy-agent');

const agent = new HttpsProxyAgent('http://proxy.internal:3128');

fetch('https://api.example.com/status', { agent })
  .then((res) => res.text())
  .then(console.log);

The important detail for security is that the TLS session is negotiated end-to-end with the destination, not terminated at the proxy. When the module works correctly, the proxy sees only the CONNECT host:443 line, not the encrypted payload.

Where it shows up in your tree

You rarely install https-proxy-agent on purpose. It arrives through tooling. It has been a transitive dependency of the Angular CLI, various AWS and Azure SDK helpers, serverless, and dozens of build tools that need to respect an HTTPS_PROXY environment variable. Run this to see whether you have it and where it comes from:

npm ls https-proxy-agent

Because it is usually transitive, the version you get is dictated by whatever pinned it, which is exactly how stale, vulnerable copies survive in otherwise up-to-date projects.

The advisories worth knowing

Two historical issues shaped the module's security story.

The first is CVE-2018-3739, a denial-of-service flaw. Versions before 2.2.0 passed an unsanitized proxy.auth option to the legacy Buffer() constructor. Depending on the type of the input, that constructor could allocate uninitialized memory or throw in ways that let a caller degrade the process. The fix was to move to the safe Buffer.from() API, and the patched release is 2.2.0.

The second was a "machine-in-the-middle" class advisory patched in the 3.0.0 line. The concern there was that basic-auth proxy credentials and other header material could be exposed to an attacker positioned on the network path to the proxy. It was tracked publicly through the Angular CLI issue tracker, which pulled a lot of downstream projects onto the fixed version.

The practical takeaway is not the specific numbers but the pattern: anything pinned below the 3.x line is old enough to be a liability. Current releases are on the 9.x line and are listed as clean in the Snyk vulnerability database. If you cannot verify the exact version a dependency resolves to, treat that as its own finding.

Configuration mistakes that undo the module

The module can be perfectly patched and still leak if you wire it up carelessly.

Do not disable certificate verification to "make the proxy work." Setting NODE_TLS_REJECT_UNAUTHORIZED=0 or passing rejectUnauthorized: false turns the tunnel into an unauthenticated channel, which defeats the reason you use HTTPS at all. If your proxy does TLS interception with a corporate root CA, add that CA to your trust store instead:

export NODE_EXTRA_CA_CERTS=/etc/ssl/corp-root.pem

Be deliberate about where the proxy URL comes from. Reading it from HTTPS_PROXY is fine, but if that value is attacker-influenced (for example, derived from request data in a server-side-request-fetch feature), you have handed an attacker control over where your outbound traffic goes. Validate and allowlist proxy hosts the same way you would any other outbound target.

Keep credentials out of the URL string when you can. Embedding user:pass@ in the proxy URL means those secrets end up in logs, process listings, and error traces. Prefer a Proxy-Authorization header assembled at request time from a secret manager.

Keeping it healthy over time

Pin and monitor rather than pin and forget. Because this package is almost always transitive, a lockfile is what actually determines your exposure. Regenerate and audit it regularly:

npm audit
npm audit fix

For deeper visibility, a software composition analysis pass will surface the transitive path and tell you which direct dependency is holding you on an old version. An SCA tool such as Safeguard can flag a stale https proxy agent copy that npm audit misses when the advisory data lags. If the culprit is a build tool you cannot upgrade quickly, an overrides block in package.json lets you force a safe version:

{
  "overrides": {
    "https-proxy-agent": "^9.0.0"
  }
}

Test after forcing an override. Agent internals changed between major versions (the export went from a default to a named HttpsProxyAgent), so a naive bump can break a dependency that imported it the old way.

When to reach for something else

Modern Node has an increasingly capable built-in fetch stack backed by undici, which has its own proxy support through ProxyAgent. For new code that only needs simple tunneling and targets a current Node LTS, using the platform primitive removes one dependency from your tree entirely. That said, https-proxy-agent remains the pragmatic choice when a library you depend on already speaks the classic agent interface, and its current releases are well maintained.

Whichever you choose, the discipline is the same: know your resolved version, keep TLS verification on, and treat the proxy URL as untrusted input if any part of it can be influenced from outside. For a broader look at auditing Node dependencies, our dependency scanning guide walks through the workflow end to end.

FAQ

Is https-proxy-agent safe to use in 2025?

Yes, on current releases. The 9.x line has no known open advisories. The risk lives in old pinned versions, so the safe move is to confirm the resolved version in your lockfile and force an upgrade if a transitive dependency is holding you below 3.0.0.

How do I find which dependency installed https-proxy-agent?

Run npm ls https-proxy-agent. It prints the dependency path so you can see which direct package pulled it in, which tells you what to upgrade or override.

Does the proxy see my HTTPS traffic?

No, not when the module is used correctly. It uses an HTTP CONNECT tunnel and negotiates TLS end-to-end with the destination, so the proxy only sees the target host and port, not the encrypted payload. That protection disappears if you disable certificate verification.

Should I switch to undici's ProxyAgent instead?

If you are on a current Node LTS and only need basic tunneling, using the built-in undici proxy support removes a dependency. Keep https-proxy-agent when an existing library already expects the classic agent interface.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.