Skip to content

Commit ae79ac5

Browse files
fix up
1 parent bea037e commit ae79ac5

File tree

4 files changed

+33
-20
lines changed

4 files changed

+33
-20
lines changed

src/connection_string.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ import { ReadPreference, type ReadPreferenceMode } from './read_preference';
3434
import { ServerMonitoringMode } from './sdam/monitor';
3535
import type { TagSet } from './sdam/server_description';
3636
import {
37+
checkParentDomainMatch,
3738
DEFAULT_PK_FACTORY,
3839
emitWarning,
3940
HostAddress,
4041
isRecord,
41-
matchesParentDomain,
4242
parseInteger,
4343
setDifference,
4444
squashError
@@ -81,9 +81,7 @@ export async function resolveSRVRecord(options: MongoOptions): Promise<HostAddre
8181
}
8282

8383
for (const { name } of addresses) {
84-
if (!matchesParentDomain(name, lookupAddress)) {
85-
throw new MongoAPIError('Server record does not share hostname with parent URI');
86-
}
84+
checkParentDomainMatch(name, lookupAddress);
8785
}
8886

8987
const hostAddresses = addresses.map(r => HostAddress.fromString(`${r.name}:${r.port ?? 27017}`));

src/sdam/srv_polling.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { clearTimeout, setTimeout } from 'timers';
33

44
import { MongoRuntimeError } from '../error';
55
import { TypedEventEmitter } from '../mongo_types';
6-
import { HostAddress, matchesParentDomain, squashError } from '../utils';
6+
import { checkParentDomainMatch, HostAddress, squashError } from '../utils';
77

88
/**
99
* @internal
@@ -127,8 +127,11 @@ export class SrvPoller extends TypedEventEmitter<SrvPollerEvents> {
127127

128128
const finalAddresses: dns.SrvRecord[] = [];
129129
for (const record of srvRecords) {
130-
if (matchesParentDomain(record.name, this.srvHost)) {
130+
try {
131+
checkParentDomainMatch(record.name, this.srvHost);
131132
finalAddresses.push(record);
133+
} catch (error) {
134+
squashError(error);
132135
}
133136
}
134137

src/utils.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import type { FindCursor } from './cursor/find_cursor';
1818
import type { Db } from './db';
1919
import {
2020
type AnyError,
21+
MongoAPIError,
2122
MongoCompatibilityError,
2223
MongoInvalidArgumentError,
2324
MongoNetworkTimeoutError,
@@ -1131,16 +1132,18 @@ export function parseUnsignedInteger(value: unknown): number | null {
11311132
}
11321133

11331134
/**
1134-
* Determines whether a provided address matches the provided parent domain.
1135+
* This function throws a MongoAPIError in the event that either of the following is true:
1136+
* * If the provided address domain does not match the provided parent domain
1137+
* * If the parent domain contains less than three `.` separated parts and the provided address does not contain at least one more domain level than its parent
11351138
*
11361139
* If a DNS server were to become compromised SRV records would still need to
11371140
* advertise addresses that are under the same domain as the srvHost.
11381141
*
11391142
* @param address - The address to check against a domain
11401143
* @param srvHost - The domain to check the provided address against
1141-
* @returns Whether the provided address matches the parent domain
1144+
* @returns void
11421145
*/
1143-
export function matchesParentDomain(address: string, srvHost: string): boolean {
1146+
export function checkParentDomainMatch(address: string, srvHost: string): void {
11441147
// Remove trailing dot if exists on either the resolved address or the srv hostname
11451148
const normalizedAddress = address.endsWith('.') ? address.slice(0, address.length - 1) : address;
11461149
const normalizedSrvHost = srvHost.endsWith('.') ? srvHost.slice(0, srvHost.length - 1) : srvHost;
@@ -1151,16 +1154,22 @@ export function matchesParentDomain(address: string, srvHost: string): boolean {
11511154
// Add leading dot back to string so
11521155
// an srvHostDomain = '.trusted.site'
11531156
// will not satisfy an addressDomain that endsWith '.fake-trusted.site'
1154-
const addressDomain = `.${normalizedAddress.replace(allCharacterBeforeFirstDot, '')}`;
1157+
const addressDomain = srvIsLessThanThreeParts
1158+
? normalizedAddress
1159+
: `.${normalizedAddress.replace(allCharacterBeforeFirstDot, '')}`;
11551160
const srvHostDomain = srvIsLessThanThreeParts
11561161
? normalizedSrvHost
11571162
: `.${normalizedSrvHost.replace(allCharacterBeforeFirstDot, '')}`;
11581163

1159-
return (
1160-
addressDomain.endsWith(srvHostDomain) &&
1161-
(!srvIsLessThanThreeParts ||
1162-
normalizedAddress.split('.').length > normalizedSrvHost.split('.').length)
1163-
);
1164+
if (!addressDomain.endsWith(srvHostDomain)) {
1165+
throw new MongoAPIError('Server record does not share hostname with parent URI');
1166+
}
1167+
if (
1168+
srvIsLessThanThreeParts &&
1169+
normalizedAddress.split('.').length <= normalizedSrvHost.split('.').length
1170+
) {
1171+
throw new MongoAPIError('Server record does not have least one more domain than parent URI');
1172+
}
11641173
}
11651174

11661175
interface RequestOptions {

test/integration/initial-dns-seedlist-discovery/initial_dns_seedlist_discovery.prose.test.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import * as dns from 'dns';
2-
import sinon = require('sinon');
3-
41
import { expect } from 'chai';
2+
import * as dns from 'dns';
3+
import * as sinon from 'sinon';
54

65
import { MongoAPIError, Server, ServerDescription, Topology } from '../../mongodb';
76
import { topologyWithPlaceholderClient } from '../../tools/utils';
@@ -156,7 +155,9 @@ describe(
156155
.connect()
157156
.catch(e => e);
158157
expect(err).to.be.instanceOf(MongoAPIError);
159-
expect(err.message).to.equal('Server record does not share hostname with parent URI');
158+
expect(err.message).to.equal(
159+
'Server record does not have least one more domain than parent URI'
160+
);
160161
});
161162

162163
it('an SRV with two domain levels causes a runtime error', async function () {
@@ -175,7 +176,9 @@ describe(
175176
.connect()
176177
.catch(e => e);
177178
expect(err).to.be.instanceOf(MongoAPIError);
178-
expect(err.message).to.equal('Server record does not share hostname with parent URI');
179+
expect(err.message).to.equal(
180+
'Server record does not have least one more domain than parent URI'
181+
);
179182
});
180183
}
181184
);

0 commit comments

Comments
 (0)