Skip to content

DRIVERS-3329: Configurable DNS domain validation for SRV records#1950

Open
sleepyStick wants to merge 9 commits into
mongodb:masterfrom
sleepyStick:DRIVERS-3329
Open

DRIVERS-3329: Configurable DNS domain validation for SRV records#1950
sleepyStick wants to merge 9 commits into
mongodb:masterfrom
sleepyStick:DRIVERS-3329

Conversation

@sleepyStick

@sleepyStick sleepyStick commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Please complete the following before merging:

  • Is the relevant DRIVERS ticket in the PR title?

@rozza rozza left a comment

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.

It looks good, I have one comment about if an invalid srvAllowedHostsSuffix should throw an error explicitly? (if so should we update the yml?)

Also the yml and json has diverged for srvAllowedHostsSuffix-without_dot_pass - which is probably the lint error.

example, `srvAllowedHostsSuffix=.mydomain.net`. If the value does not begin with a `.`, for example,
`srvAllowedHostsSuffix=mydomain.net`, the `.` MUST be automatically prepended prior to validation. If this option is not
present, the domain MUST be inferred from the hostname. This option MUST only be configurable at the level of a
`MongoClient`.

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.

Just to clarify, if a host is invalid eg: ..example.com should this error or just return an empty list of hosts?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

oh good question, my current implementation has it eventually erroring (with a configuration error) when the driver goes to validate the SRV hosts -- i didn't add a new "check valid host" type of function. (though this probably wouldn't be too hard with some regex? if you think it'd be beneficial to add something like this.) My initial thought process was this new parameter is just a user configurable way to denote what the domain should be (as opposed to the previous, now default, logic) -- they should know what they're doing if they're using this param and if they happened to make a typo / silly mistake, the existing "invalid SRV host" error message that occurs when there is an invalid host given the previous logic would still apply.

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.

I think the eventually error part will cover this, so no need for a regex. I can never understand regexes and someone always seems to find a usecase where the regex fails where it shouldn't!

@sleepyStick sleepyStick marked this pull request as ready for review June 16, 2026 19:50
@sleepyStick sleepyStick requested review from a team as code owners June 16, 2026 19:50

#### srvAllowedHostsSuffix

This option is used to validate hosts. If present, its value MUST be treated as the domain for DNS validation. For

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.

Optional: Consider linking to the Querying DNS section, which is where the DNS validation is described.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

added! thanks!

Comment thread source/initial-dns-seedlist-discovery/initial-dns-seedlist-discovery.md Outdated
Comment thread source/initial-dns-seedlist-discovery/initial-dns-seedlist-discovery.md Outdated
@codeowners-service-app

Copy link
Copy Markdown

Assigned vector-of-bool for team dbx-spec-maintainers-connection-string because aclark4life is out of office.

@Jibola Jibola requested a review from rozza June 22, 2026 15:37
sleepyStick and others added 5 commits June 22, 2026 11:40
…covery.md

Co-authored-by: Matt Dale <9760375+matthewdale@users.noreply.github.com>
…covery.md

Co-authored-by: Matt Dale <9760375+matthewdale@users.noreply.github.com>
@sleepyStick sleepyStick requested a review from matthewdale June 22, 2026 19:07

@matthewdale matthewdale 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.

Looks good! 👍

@@ -0,0 +1,6 @@
{
"uri": "mongodb+srv://test12.test.build.10gen.cc/?srvAllowedHostsSuffix=uild.10gen.cc",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Looks like the convention in yml is no quotes around uri

This option is used to validate hosts. If present, its value MUST be treated as the `{domainname}` for
[DNS validation](#querying-dns). For example, `srvAllowedHostsSuffix=.mydomain.net`. If the value does not begin with a
`.`, for example, `srvAllowedHostsSuffix=mydomain.net`, the `.` MUST be automatically prepended prior to validation. If
this option is not present, the`{domainname}` MUST be inferred from the `{hostname}` (as described in

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing space

uri: "mongodb+srv://test12.test.build.10gen.cc/?srvAllowedHostsSuffix=test.build.10gen.cc"
seeds: []
hosts: []
error: true No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Also a convention apparently is new lines at the end of yaml files.

@aclark4life aclark4life left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pending nit fixes LGTM

@sleepyStick sleepyStick requested review from Jibola and ajcvickers June 23, 2026 20:20
@ajcvickers

Copy link
Copy Markdown

Setting srvAllowedHostsSuffix to a public suffix neuters SRV anti-spoofing, turning mongodb+srv:// into an unbounded DNS redirect. A merely broad private domain doesn't make it unbounded, but widens the redirect to anywhere under that domain. There is no PSL/minimum-label guard to prevent either. Example:

Preconditions:

  • Misconfiguration. App sets a too-broad suffix:
    mongodb+srv://mycluster.mongodb.example.com/?srvAllowedHostsSuffix=.com
  • Attacker runs a malicious/compromised resolver, or poisons the cache. (DNSSEC is not enforced per SECURITY-488).
  • Attacker obtains a CA-valid cert for a domain they own.

Step-by-step:

  • Client SRV-queries _mongodb._tcp.mycluster.mongodb.example.com.
  • Attacker forges the SRV response: target db1.attacker-evil.com:27017.
  • Suffix validation passes (db1.attacker-evil.com ends in .com).
  • mongodb+srv forces TLS; the client validates the cert against the SRV-returned name (db1.attacker-evil.com), not the typed name (mycluster.mongodb.example.com).
  • Attacker owns that name and holds a valid cert → TLS verification passes → client connects to the attacker's server.

@ajcvickers

Copy link
Copy Markdown

I think the parsing needs to be much better specified and tested. It's important to understand what DNS entries allow and how to safely handle these things. These should be specified at the spec level, so all drivers will get the parsing correct. For example, most of these are not specified or tested:

  • DNS is case-insensitive. (Also, ASCII-only case-folding.)
  • SRV targets often return trailing dots. For example: host.citi.net. These must be normalized.
  • IDN / punycode / homographs. Don't compare raw Unicode.
  • Probably more... (I'm not an expert, but the above are the obvious ones.)

There needs to be much better test coverage here.

@ajcvickers

Copy link
Copy Markdown
  • When the suffix is set, does the "fewer than three parts" means "at least one more domain level" still apply?
  • SRV polling reuses the same domain-matching and is not touched by this PR, nor mentioned in the decision doc. This seems fundamentally broken.
  • How does setting the new option Interact with srvMaxHosts or a custom srvServiceName?

@ajcvickers ajcvickers left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

From going through the history here, it seems we have acknowledged the security concerns but consciously accepted them and shifted the risk to the customer to meet customer demand. This is a weak security posture: it puts a lot of responsibility on the customer to get everything right, and rejects the safer alternatives (CNAMEs, RFC 4985 SANs).

If we are going to do this, then the risks I have highlighted need to be made front and center so that anyone opting into this is aware that it relaxes the naming-layer anti-spoofing defense and considerably increases their attack surface.

Beyond this, I think there needs to be a product-level guard against the worst misconfigurations (e.g. rejecting public-suffix values) and a fully specified safe-configuration recipe, so "the customer's responsibility" is achievable rather than a trap.

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.

5 participants