Skip to content

fix(#340): Eliminate HTTPS DNS rebinding TOCTOU gap with pinned agent#341

Merged
radaghastly merged 1 commit into
monteslu:feat/249-custom-rest-endpointsfrom
luthien-m:fix/340-https-dns-rebinding
Mar 9, 2026
Merged

fix(#340): Eliminate HTTPS DNS rebinding TOCTOU gap with pinned agent#341
radaghastly merged 1 commit into
monteslu:feat/249-custom-rest-endpointsfrom
luthien-m:fix/340-https-dns-rebinding

Conversation

@luthien-m
Copy link
Copy Markdown
Collaborator

Summary

Eliminates the HTTPS DNS rebinding TOCTOU gap identified in #340 (from PR #283 review).

Problem

assertNotPrivateUrl() resolves DNS to validate the IP is not private, but for HTTPS URLs the subsequent fetch() re-resolves DNS independently. An attacker controlling DNS could return a public IP on first lookup and a private IP on second (DNS rebinding).

Solution

Use https.Agent with a custom lookup function that returns the pre-resolved IP. This pins DNS at the connection level while preserving TLS certificate validation via SNI.

Changes

src/services/customServiceService.js

  • assertNotPrivateUrl() returns { agent } for HTTPS — single-use https.Agent with pinned DNS
  • Added pinnedRequest() helper for testConnection()
  • Agent destroyed after use

src/routes/custom-proxy.js

  • Added fetchWithAgent() — wraps http(s).request in a fetch-like interface
  • Proxy uses it when pinned agent is provided (HTTPS case)
  • HTTP path unchanged (direct IP pinning in URL)

All tests pass, lint clean.

Fixes #340

…ed agent

Uses https.Agent with a custom lookup function that returns the
pre-resolved IP address, eliminating the DNS rebinding window for
HTTPS requests while preserving TLS certificate validation via SNI.

- assertNotPrivateUrl() now returns a single-use https.Agent for HTTPS
- custom-proxy uses fetchWithAgent() wrapper (http.request with agent)
- testConnection() uses pinnedRequest() helper with the agent
- Node built-in fetch does not support agent option, hence the wrappers

Fixes monteslu#340
Copy link
Copy Markdown
Collaborator

@radaghastly radaghastly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Clean implementation — https.Agent with custom lookup pins DNS at the connection level while preserving TLS cert validation via SNI. The fetchWithAgent wrapper gives a clean fetch-like interface. Both proxy and testConnection paths covered.

Nice work closing the TOCTOU gap properly. 🔒

@radaghastly radaghastly merged commit 0db04ba into monteslu:feat/249-custom-rest-endpoints Mar 9, 2026
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