From 1d02d975f02fb3589bd59a27e6a53e434016d6b8 Mon Sep 17 00:00:00 2001 From: Pavel Safronov Date: Mon, 23 Mar 2026 13:13:00 -0700 Subject: [PATCH] fix(NODE-7478): OIDC host allowlist fix --- src/utils.ts | 24 +++++++++++++++++++----- test/unit/utils.test.ts | 29 +++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index c85767242b6..92aa8f84917 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -69,13 +69,27 @@ export function isUint8Array(value: unknown): value is Uint8Array { */ export function hostMatchesWildcards(host: string, wildcards: string[]): boolean { for (const wildcard of wildcards) { - if ( - host === wildcard || - (wildcard.startsWith('*.') && host?.endsWith(wildcard.substring(2, wildcard.length))) || - (wildcard.startsWith('*/') && host?.endsWith(wildcard.substring(2, wildcard.length))) - ) { + // Exact match always wins + if (host === wildcard) { return true; } + + // Wildcard match with leading *. + if (wildcard.startsWith('*.')) { + const suffix = wildcard.substring(2); + // Exact match or strict subdomain match + if (host === suffix || host.endsWith(`.${suffix}`)) { + return true; + } + } + // Wildcard match with leading */ + if (wildcard.startsWith('*/')) { + const suffix = wildcard.substring(2); + // Exact match or strict subpath match + if (host === suffix || host.endsWith(`/${suffix}`)) { + return true; + } + } } return false; } diff --git a/test/unit/utils.test.ts b/test/unit/utils.test.ts index e0783eb5302..931521dd285 100644 --- a/test/unit/utils.test.ts +++ b/test/unit/utils.test.ts @@ -10,6 +10,7 @@ import { checkParentDomainMatch, compareObjectId, decorateWithExplain, + DEFAULT_ALLOWED_HOSTS, Explain, hasAtomicOperators, HostAddress, @@ -149,6 +150,26 @@ describe('driver utils', function () { }); }); + context('when the wildcard starts with *.', function () { + it('returns false', function () { + expect(hostMatchesWildcards('test-mongodb.com', ['*.mongodb.com', 'test2'])).to.be + .false; + }); + }); + + context('when using default allowed hosts', function () { + it('returns false', function () { + for (const host of DEFAULT_ALLOWED_HOSTS) { + // Only test the wildcard hosts, the non-wildcard hosts are tested in other test cases + if (!host.startsWith('*.')) { + continue; + } + const wrongHost = host.replace('*.', 'test-'); + expect(hostMatchesWildcards(wrongHost, DEFAULT_ALLOWED_HOSTS)).to.be.false; + } + }); + }); + context('when the host matches a FQDN', function () { it('returns true', function () { expect(hostMatchesWildcards('mongodb.net', ['*.mongodb.net', 'other'])).to.be.true; @@ -222,6 +243,14 @@ describe('driver utils', function () { .to.be.false; }); }); + + context('when the host does not match partial matches', function () { + it('returns false', function () { + expect( + hostMatchesWildcards('/tmp/test-mongodb-27017.sock', ['*/mongodb-27017.sock', 'test2']) + ).to.be.false; + }); + }); }); });