Skip to content

fix: handle bracketed IPv6 hosts in req.subdomains - #7566

Closed
DipanshuAmbilkar03 wants to merge 1 commit into
expressjs:masterfrom
DipanshuAmbilkar03:fix/subdomains-ipv6-dotted-host
Closed

DipanshuAmbilkar03 wants to merge 1 commit into
expressjs:masterfrom
DipanshuAmbilkar03:fix/subdomains-ipv6-dotted-host

Conversation

@DipanshuAmbilkar03

Copy link
Copy Markdown

Fixes #7532

The bug

req.subdomains returns ["0", "[::ffff:127"] for a request whose Host header is [::ffff:127.0.0.1]. With subdomain offset set to 0 it returns ["1]", "0", "0", "[::ffff:127"].

Root cause

req.hostname keeps the brackets around IPv6 literals (host[0] === '[' path), but node:net's isIP() does not accept a bracketed address:

isIP('[::ffff:127.0.0.1]') // 0
isIP('::ffff:127.0.0.1')   // 6

Because the IP check failed, the getter fell through to hostname.split('.').reverse() and split the IPv6 literal on its embedded IPv4 dots. [::1] only appeared to work by accident, since it contains no dots and was dropped by slice(offset).

Fix

Strip the brackets before the isIP() check, while keeping the original bracketed host in the returned array. This preserves the documented behaviour that an offset of 0 returns the whole host (["[::ffff:127.0.0.1]"]), matching the existing [::1] case.

Tests

Added two regression tests in test/req.subdomains.js:

  • [::ffff:127.0.0.1] with the default offset returns []
  • [::ffff:127.0.0.1] with subdomain offset of 0 returns ["[::ffff:127.0.0.1]"]

Both fail before the change and pass after it. Full suite: 1292 passing, ESLint clean.

IPv6 literals in the Host header are bracketed (e.g.
`[::ffff:127.0.0.1]`), which `node:net`'s `isIP()` does not accept.
The `subdomains` getter therefore treated such hosts as domain names
and split them on the dots, returning `["0", "[::ffff:127"]` instead
of `[]`.

Strip the brackets before the IP check while keeping the original
bracketed host in the returned array, so `subdomain offset` of 0 still
yields `["[::ffff:127.0.0.1]"]`.

Adds regression tests for both the default and the zero offset.
@krzysdz

krzysdz commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Duplicate of #7533

@krzysdz krzysdz marked this as a duplicate of #7533 Oct 27, 2026
@krzysdz krzysdz closed this Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

req.subdomains splits an IPv6 host that contains dots

2 participants