Skip to content

Commit 2d028af

Browse files
authoredJun 20, 2023
fix(NODE-5356): prevent scram auth from throwing TypeError if saslprep is not a function (#3732)
1 parent 0e1afc0 commit 2d028af

File tree

3 files changed

+69
-124
lines changed

3 files changed

+69
-124
lines changed
 

‎src/cmap/auth/scram.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ class ScramSHA extends AuthProvider {
3030
if (!credentials) {
3131
return callback(new MongoMissingCredentialsError('AuthContext must provide credentials.'));
3232
}
33-
if (cryptoMethod === 'sha256' && saslprep == null) {
33+
if (
34+
cryptoMethod === 'sha256' &&
35+
('kModuleError' in saslprep || typeof saslprep !== 'function')
36+
) {
3437
emitWarning('Warning: no saslprep library specified. Passwords will not be sanitized');
3538
}
3639

@@ -152,7 +155,8 @@ function continueScramConversation(
152155

153156
let processedPassword;
154157
if (cryptoMethod === 'sha256') {
155-
processedPassword = 'kModuleError' in saslprep ? password : saslprep(password);
158+
processedPassword =
159+
'kModuleError' in saslprep || typeof saslprep !== 'function' ? password : saslprep(password);
156160
} else {
157161
try {
158162
processedPassword = passwordDigest(username, password);

‎test/integration/auth/scram_sha_256.test.js

-122
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { expect } from 'chai';
2+
import * as sinon from 'sinon';
3+
4+
import * as deps from '../../../src/deps';
5+
import { type MongoClient } from '../../../src/mongo_client';
6+
7+
describe('SCRAM_SHA_256', function () {
8+
beforeEach(function () {
9+
if (!this.configuration.parameters.authenticationMechanisms.includes('SCRAM-SHA-256')) {
10+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
11+
this.currentTest!.skipReason = 'Test requires that SCRAM-SHA-256 be enabled on the server.';
12+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
13+
this.currentTest!.skip();
14+
}
15+
});
16+
17+
context('when saslprep is not a function', () => {
18+
let client: MongoClient;
19+
20+
beforeEach(function () {
21+
sinon.stub(deps, 'saslprep').value({});
22+
client = this.configuration.newClient({ authMechanism: 'SCRAM-SHA-256' });
23+
});
24+
25+
afterEach(() => {
26+
sinon.restore();
27+
return client.close();
28+
});
29+
30+
it('does not throw an error', { requires: { auth: 'enabled' } }, async function () {
31+
await client.connect();
32+
});
33+
34+
it('emits a warning', { requires: { auth: 'enabled' } }, async function () {
35+
const warnings: Array<Error> = [];
36+
process.once('warning', w => warnings.push(w));
37+
await client.connect();
38+
expect(warnings).to.have.lengthOf(1);
39+
expect(warnings[0]).to.have.property(
40+
'message',
41+
'Warning: no saslprep library specified. Passwords will not be sanitized'
42+
);
43+
});
44+
});
45+
46+
context('when saslprep is a function', () => {
47+
let client: MongoClient;
48+
49+
beforeEach(function () {
50+
client = this.configuration.newClient({ authMechanism: 'SCRAM-SHA-256' });
51+
});
52+
53+
afterEach(() => client.close());
54+
55+
it('calls saslprep', { requires: { auth: 'enabled' } }, async function () {
56+
const spy = sinon.spy(deps, 'saslprep');
57+
58+
await client.connect();
59+
60+
expect(spy).to.have.been.called;
61+
});
62+
});
63+
});

0 commit comments

Comments
 (0)
Please sign in to comment.