Skip to content

CSHARP-6214: Implement srvAllowedHostsSuffix URI option and Public Suffix List validation - #2109

Open
adelinowona wants to merge 1 commit into
mongodb:mainfrom
adelinowona:csharp6214
Open

CSHARP-6214: Implement srvAllowedHostsSuffix URI option and Public Suffix List validation#2109
adelinowona wants to merge 1 commit into
mongodb:mainfrom
adelinowona:csharp6214

Conversation

@adelinowona

@adelinowona adelinowona commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Implements the srvAllowedHostsSuffix URI option and the Public Suffix List guardrail that bounds how broad the configured suffix may be.

Specs: Initial DNS Seedlist Discovery and Public Suffix List.

What it does

srvAllowedHostsSuffix lets a user state the parent domain that hosts returned by an SRV lookup are validated against, instead of having it inferred from the SRV hostname. The value is normalized in the order the spec mandates — strip leading/trailing dots, convert to Punycode, ASCII lowercase, reject if the result is a public suffix, prepend a dot — and rejected on a non-SRV scheme, mirroring the existing srvServiceName check.

Because the option relaxes a DNS-spoofing safeguard, the spec requires the value not be a public suffix. That check is backed by the Public Suffix List, vendored as an embedded resource with a hand-rolled matcher (Core/Misc/PublicSuffixList.cs).

DnsMonitor previously used lookupDomainName for two purposes: building the SRV query name and validating returned hosts. Those are now separate — the option MUST NOT affect which records are queried, only which parent domain returned hosts are checked against.

@adelinowona
adelinowona requested a review from a team as a code owner September 1, 2026 00:15
@adelinowona
adelinowona requested review from papafe and a lite review from Copilot September 1, 2026 00:15
@adelinowona adelinowona added the feature Adds new user-facing functionality. label Sep 1, 2026
@adelinowona
adelinowona requested review from BorisDog and sanych-sun and removed request for papafe September 1, 2026 00:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning

  • Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.

Pull request overview

Implements the srvAllowedHostsSuffix URI option (including spec-mandated normalization and Public Suffix List validation) and wires it through client/cluster settings into SRV polling so that SRV host validation can be constrained to a user-configured parent domain without affecting which SRV records are queried.

Changes:

  • Added srvAllowedHostsSuffix parsing, validation, and normalization (trim dots → IDN/Punycode → lowercase → reject public suffix → prepend dot) plus updated SRV-host parent-domain validation to optionally use the configured suffix.
  • Vendored the Public Suffix List as an embedded resource and introduced a small matcher (PublicSuffixList) with prose tests.
  • Propagated the option through MongoUrlBuilder / MongoUrl / MongoClientSettingsClusterSettingsDnsMonitor and updated relevant unit tests/mocks.

Reviewed changes

Copilot reviewed 43 out of 44 changed files in this pull request and generated no comments.

Show a summary per file
File Description
THIRD-PARTY-NOTICES Adds MPL 2.0 notice for the embedded Public Suffix List.
.gitattributes Pins LF line endings for the vendored PSL data file to keep embedded bytes stable across platforms.
src/MongoDB.Driver/MongoDB.Driver.csproj Embeds public_suffix_list.dat with an explicit LogicalName for stable resource loading.
src/MongoDB.Driver/Core/Misc/public_suffix_list.dat Vendored PSL rules file used to reject overly-broad suffixes.
src/MongoDB.Driver/Core/Misc/PublicSuffixList.cs Adds PSL matcher/loader backed by the embedded resource.
src/MongoDB.Driver/Core/Configuration/ConnectionString.cs Parses srvAllowedHostsSuffix, normalizes it, and uses it for SRV host parent-domain validation.
src/MongoDB.Driver/MongoUrlBuilder.cs Adds SrvAllowedHostsSuffix option support (validation + serialization).
src/MongoDB.Driver/MongoUrl.cs Surfaces SrvAllowedHostsSuffix on MongoUrl.
src/MongoDB.Driver/MongoClientSettings.cs Adds SrvAllowedHostsSuffix setting, validation, cloning/equality/hash propagation, and cluster-key propagation.
src/MongoDB.Driver/Core/Configuration/ClusterSettings.cs Stores/exposes SrvAllowedHostsSuffix and passes it through With(...).
src/MongoDB.Driver/ClusterKey.cs Adds SrvAllowedHostsSuffix to the key for cluster identity comparisons.
src/MongoDB.Driver/ClusterRegistry.cs Copies SrvAllowedHostsSuffix from ClusterKey into ClusterSettings (fixing SRV polling ignoring it).
src/MongoDB.Driver/Core/Clusters/IDnsMonitorFactory.cs Extends factory contract to accept srvAllowedHostsSuffix.
src/MongoDB.Driver/Core/Clusters/DnsMonitorFactory.cs Passes srvAllowedHostsSuffix through to DnsMonitor.
src/MongoDB.Driver/Core/Clusters/DnsMonitor.cs Separates SRV query name from host-validation suffix; validates hosts against configured suffix when present.
src/MongoDB.Driver/Core/Clusters/MultiServerCluster.cs Passes SrvAllowedHostsSuffix into the DNS monitor.
src/MongoDB.Driver/Core/Clusters/LoadBalancedCluster.cs Passes SrvAllowedHostsSuffix into the DNS monitor.
tests/MongoDB.Driver.Tests/Specifications/public-suffix-list/PublicSuffixListTests.cs Adds PSL prose tests (including internationalized rule handling).
tests/MongoDB.Driver.Tests/MongoUrlBuilderTests.cs Adds MongoUrlBuilder tests for SrvAllowedHostsSuffix (including public-suffix rejection and non-SRV scheme rejection).
tests/MongoDB.Driver.Tests/Core/Configuration/ConnectionStringTests.cs Adds unit tests verifying normalization of srvAllowedHostsSuffix (dots/case/IDN).
tests/MongoDB.Driver.Tests/ClusterRegistryTests.cs Asserts cluster settings now receive SrvAllowedHostsSuffix.
tests/MongoDB.Driver.Tests/ClusterKeyTests.cs Adds equality coverage for SrvAllowedHostsSuffix in ClusterKey test scaffolding.
tests/MongoDB.Driver.Tests/Core/Clusters/DnsMonitorTests.cs Updates constructor usage for new DnsMonitor parameter.
tests/MongoDB.Driver.Tests/Core/Clusters/DnsMonitorFactoryTests.cs Updates factory tests for new parameter.
tests/MongoDB.Driver.Tests/Core/Clusters/MultiServerClusterTests.cs Updates mock IDnsMonitorFactory signature usage.
tests/MongoDB.Driver.Tests/Core/Clusters/LoadBalancedClusterTests.cs Updates mock IDnsMonitorFactory signature usage.
specifications/connection-string/tests/invalid-uris.yml Spec test updates (content excluded by policy).
specifications/connection-string/tests/invalid-uris.json Spec test updates (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-with_dot.yml Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-tld-only.yml Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-mismatch.yml Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-with_dot.json Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-tld-only.json Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-mismatch.json Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-period-only.yml Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-trailing-dot.yml Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-period-only.json Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-trailing-dot.json Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-without_dot_pass.yml Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-without_dot_fail.yml Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-case-insensitive.yml Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-without_dot_pass.json Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-without_dot_fail.json Spec test additions (content excluded by policy).
specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-case-insensitive.json Spec test additions (content excluded by policy).
Files excluded by content exclusion policy (18)
  • specifications/connection-string/tests/invalid-uris.json
  • specifications/connection-string/tests/invalid-uris.yml
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-case-insensitive.json
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-case-insensitive.yml
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-mismatch.json
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-mismatch.yml
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-period-only.json
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-period-only.yml
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-tld-only.json
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-tld-only.yml
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-trailing-dot.json
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-trailing-dot.yml
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-with_dot.json
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-with_dot.yml
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-without_dot_fail.json
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-without_dot_fail.yml
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-without_dot_pass.json
  • specifications/initial-dns-seedlist-discovery/tests/replica-set/srvAllowedHostsSuffix-without_dot_pass.yml

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Optional<int> srvMaxHosts = default,
Optional<string> srvServiceName = default(Optional<string>))
Optional<string> srvServiceName = default(Optional<string>),
Optional<string> srvAllowedHostsSuffix = default(Optional<string>))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Isn't adding new optional parameter considered to be a breaking change?


namespace MongoDB.Driver.Core.Misc;

internal static class PublicSuffixList

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Have you considered usage of some 3rd party package to handle the public suffix list? The problem with the embedded list that there is no way to populate it other then change the file and make a new version.
Should we use https://github.com/nager/Nager.PublicSuffix instead? This package can download the latest official list from publicsuffix.org

}
if (_srvAllowedHostsSuffix != null)
{
query.AppendFormat("srvAllowedHostsSuffix={0}&", _srvAllowedHostsSuffix);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we encode _srvAllowedHostsSuffix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Adds new user-facing functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants