feat(NODE-7830): add srvAllowedHostsSuffix and srvHostValidator options - #5065
Open
PavelSafronov wants to merge 3 commits into
Open
PavelSafronov wants to merge 3 commits into
PavelSafronov wants to merge 3 commits into
Conversation
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
HostAddress reparsing defeats the intended cross-version handling on older supported Node releases, and the declared upstream prerequisite remains open.
Review effort: Balanced
Findings: 2
Open (2)
What changed in this PR
Adds configurable SRV host validation and normalized DNS-name comparison throughout initial discovery and polling.
Changes:
- Adds
srvAllowedHostsSuffixand synchronoussrvHostValidatoroptions. - Normalizes SRV names to lowercase A-label form without trailing dots.
- Adds unit, integration, type, and upstream conformance coverage.
The declared DRIVERS-3664 prerequisite remains open and blocked.
| File | Description |
|---|---|
src/connection_string.ts |
Parses options and validates initial SRV results. |
src/mongo_client.ts |
Exposes and documents the new options. |
src/sdam/srv_polling.ts |
Applies validation during SRV polling. |
src/sdam/topology.ts |
Passes options into the SRV poller. |
src/utils.ts |
Adds DNS normalization and shared verification. |
test/mongodb_bundled.ts |
Exposes required test helpers. |
test/integration/initial-dns-seedlist-discovery/initial_dns_seedlist_discovery.prose.test.ts |
Covers initial discovery behavior. |
test/unit/assorted/polling_srv_records_for_mongos_discovery.prose.test.ts |
Covers validator polling behavior. |
test/unit/connection_string.test.ts |
Tests parsing, normalization, and validation. |
test/unit/sdam/srv_polling.test.ts |
Tests poller filtering and normalization. |
test/unit/utils.test.ts |
Tests DNS normalization. |
test/types/community/client.test-d.ts |
Verifies public option types. |
test/tools/uri_spec_runner.ts |
Supports the new URI option. |
test/spec/uri-options/srv-options.yml |
Adds upstream YAML URI fixture. |
test/spec/uri-options/srv-options.json |
Adds upstream JSON URI fixture. |
test/spec/polling-srv-records-for-mongos-discovery/README.md |
Vendors polling prose tests. |
test/spec/initial-dns-seedlist-discovery/README.md |
Vendors discovery prose tests. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-without_dot_pass.yml |
Adds suffix success fixture. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-without_dot_pass.json |
Adds suffix success fixture. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-without_dot_fail.yml |
Adds suffix rejection fixture. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-without_dot_fail.json |
Adds suffix rejection fixture. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-with_dot.yml |
Covers leading-dot suffixes. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-with_dot.json |
Covers leading-dot suffixes. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-trailing-dot.yml |
Covers trailing-dot normalization. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-trailing-dot.json |
Covers trailing-dot normalization. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-tld-only.yml |
Covers single-label rejection. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-tld-only.json |
Covers single-label rejection. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-psl-public-suffix.yml |
Covers public suffix rejection. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-psl-public-suffix.json |
Covers public suffix rejection. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-psl-public-suffix-capitalized.yml |
Covers normalized public suffix rejection. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-psl-public-suffix-capitalized.json |
Covers normalized public suffix rejection. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-psl-not-public-suffix.yml |
Covers accepted registrable suffixes. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-psl-not-public-suffix.json |
Covers accepted registrable suffixes. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-period-only.yml |
Covers empty normalized suffixes. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-period-only.json |
Covers empty normalized suffixes. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-mismatch.yml |
Covers suffix mismatches. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-mismatch.json |
Covers suffix mismatches. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-case-insensitive.yml |
Covers case-insensitive suffixes. |
test/spec/initial-dns-seedlist-discovery/replica-set/srvAllowedHostsSuffix-case-insensitive.json |
Covers case-insensitive suffixes. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| const hostAddresses = addresses.map(({ name, port }) => { | ||
| const host = normalizeDnsName(name); | ||
| verifySrvHost(host, lookupAddress, options); | ||
| return HostAddress.fromString(`${host}:${port ?? 27017}`); |
| const name = normalizeDnsName(record.name); | ||
| // A validator that throws is treated as rejecting the host, so polling continues | ||
| verifySrvHost(name, this.srvHost, this); | ||
| finalAddresses.push({ ...record, name }); |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Description
Summary of Changes
Add two new ways to customize DNS resolution:
srvAllowedHostsSuffixandsrvHostValidator.We are also modifying the behavior of the Driver for all
mongodb+srvusers: SRV host names are now normalized before comparison (lowercased, trailing dot removed, international names converted toxn--form). As a result, a connection string whose SRV host name differs in case from the host names DNS returns, such asmongodb+srv://TEST1.TEST.BUILD.10GEN.CC, now passes SRV verification instead of failing with "Server record does not share hostname with parent URI".Notes for Reviewers
This implements the following DRIVERS tickets:
The specifications include this SHOULD step that we skip:
This is a SHOULD, so Node/Java/C# do not implement the Public Suffix List (PSL), only Python has added PSL support to their driver so far.
DRIVERS-3664 is open to make some changes to the relevant specs, current work should not be merged before 3664 is reviewed and merged.
For this work, we aren't pulling in all the specifications changes from
main, they will be done with their respective NODE tickets:pingupdates, NODE-4083uri-with-uppercase-hostnameupdates, NODE-5439, blocked on NODE-3757An unrelated test fix adds some entries to
test/mongodb_bundled.ts. Once we complete NODE-7850, these missing entries will cause a build failure, so in the future it won't be possible to get into this state.Host name conversion follows the WHATWG URL Standard's domain parser; the spec allows drivers to choose their IDNA processing standard. The URL Standard was updated in June 2026 to return ASCII names lowercased even when their
xn--labels are not valid A-labels, but Node.js only picked this up in 24.20.0 (nodejs/node#64790, Ada 4.0.0), so earlier Node.js versions reject such names inurl.domainToASCII. To behave the same on every Node.js version, and to keep accepting host names thatmainaccepts today, we lowercase ASCII names ourselves instead of relying onurl.domainToASCII.Release Highlight
Configurable SRV host validation
This release adds two new methods of validating DNS:
srvAllowedHostsSuffix- A host name suffix that every host returned by the SRV lookup must end with. This option can be configured on the client or the connection string.srvHostValidator- A synchronous function that decides whether a host returned by the SRV lookup may be used. This option can only be configured on the client. This function must accept a string and has to return a boolean; returning anything else, including the Promise returned by anasyncfunction, will result in an error.Warning
Modifying the default SRV domain name validation can create vulnerabilities.
SRV host names are now compared in a normalized form (case-insensitively, without a trailing dot, and with internationalized names in
xn--form). Connection strings whose SRV host name differs in case from the host names returned by DNS, such asmongodb+srv://TEST1.TEST.BUILD.10GEN.CC, previously failed SRV verification and now connect.Double check the following
npm run check:lint)type(NODE-xxxx)[!]: descriptionfeat(NODE-1234)!: rewriting everything in coffeescript