Skip to content

NO_PROXY domain suffix can be used to evade proxy by a non-subdomain #62907

@ChALkeR

Description

@ChALkeR

Doc says: https://nodejs.org/api/http.html#no-proxy-format

.example.com - Domain suffix match (matches sub.example.com)

But .example.com also matches totally-not-example.com.

Also (more trivially verifiable), .ample.com matches example.com:

% cat deepview-broken-proxy.js
require('node:https').request('https://example.com', (res) => {
  console.log('status:', res.statusCode)
  process.exit(0)
}).end()
% HTTPS_PROXY='http://10.0.0.0:1' node --use-env-proxy deepview-broken-proxy.js 
node:events:487
      throw er; // Unhandled 'error' event
      ^

Error [ERR_PROXY_TUNNEL]: Connection to establish proxy tunnel timed out after 5000ms
...
% HTTPS_PROXY='http://10.0.0.0:1' NO_PROXY='.ample.com' node --use-env-proxy deepview-broken-proxy.js
status: 200

https://github.com/nodejs/node/blob/HEAD/lib/internal/http.js#L161

Details

In ProxyConfig#shouldUseProxy (the transitive helper that checkShouldUseProxy always delegates to), the .suffix bypass-list rule uses host.endsWith(suffix) after stripping the leading dot. This matches across domain-label boundaries: a NO_PROXY=.example.com rule causes checkShouldUseProxy(..., { host: 'evilexample.com' }) to return false (bypass proxy) because 'evilexample.com'.endsWith('example.com') is true. An attacker who can choose/influence the target hostname can therefore route traffic around a proxy that was meant to intercept all *.example.com traffic. The check should require the character immediately preceding the suffix to be . (or the host to equal the suffix exactly), e.g. host === suffix || host.endsWith('.' + suffix) — or reuse the same form as the *.example.com branch (which is already safe because its effective suffix retains the leading dot).

Metadata

Metadata

Assignees

No one assigned

    Labels

    experimentalIssues and PRs related to experimental features.httpIssues or PRs related to the http subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions