diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index fe360b18b69..dc12be9765b 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -2,9 +2,9 @@ name: "CodeQL" on: push: - branches: [ "main", "5.x" ] + branches: [ "main", "v7.1.x" ] pull_request: - branches: [ "main", "5.x" ] + branches: [ "main", "v7.1.x" ] jobs: analyze: diff --git a/src/utils.ts b/src/utils.ts index 397850649d5..e96864e162b 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -83,13 +83,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 dc393fe0990..98b23ec2863 100644 --- a/test/unit/utils.test.ts +++ b/test/unit/utils.test.ts @@ -4,6 +4,7 @@ import { ObjectId } from 'bson'; import { expect } from 'chai'; import * as sinon from 'sinon'; +import { DEFAULT_ALLOWED_HOSTS } from '../../src/cmap/auth/mongo_credentials'; import { LEGACY_HELLO_COMMAND } from '../../src/constants'; import { MongoInvalidArgumentError, MongoRuntimeError } from '../../src/error'; import { decorateWithExplain, Explain } from '../../src/explain'; @@ -148,6 +149,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; @@ -221,6 +242,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; + }); + }); }); });