Improving the Node.js Driver’s SCRAM-SHA-256 Support
Cross posted from the MongoDB Blog
MongoDB always strives to offer best-in-class features, functionality, and security. A number of authentication mechanisms currently exist to verify the identity of a connecting client to your cluster, and when using the Salted Challenge Response Authentication Mechanism (SCRAM
) there are two possible hashing functions: SCRAM-SHA-1
and SCRAM-SHA-256
.
The MongoDB Driver Authentication Specification outlines that when attempting to authenticate using SCRAM:
“If
SCRAM-SHA-256
is present in the list of mechanism, then it MUST be used as the default; otherwise,SCRAM-SHA-1
MUST be used as the default […]”.
A MongoDB Server (mongos
or mongod
) can be configured with a list of possible authenticationMechanisms
. As a result, MongoDB can be configured to return new authentication mechanisms which can upgrade already running applications to more secure authentication. This is the case when SCRAM-SHA-256
is added to a cluster that previously only supported SCRAM-SHA-1
.
Prior to hashing passwords with SHA-256
, they will first be prepared using SASLprep. The MongoDB Node.js driver leverages an external library (saslprep
) for this functionality, which was an optional dependency and only used if available. Though a number of checks were in place to ensure the library was available (and loaded), an edge case was found where these checks could fail and report availability incorrectly.
Potential Issue
Most applications won’t experience this issue, however if your Node.js project is being bundled using an alternate bundler (such as webpack
) it’s possible a variation of this issue may surface.
If your application was affected, it would be unable to connect to your MongoDB cluster. The stack trace from the error that would be thrown should include a call to continueScramConversation
similar to the following examples:
1
2
3
4
5
6
7
8
9
{
"errorType": "TypeError",
"errorMessage": "saslprep is not a function",
"stack": [
"TypeError: saslprep is not a function",
" at continueScramConversation ([...]/index.js:xxx:yyy)",
[...]
]
}
1
2
TypeError: l is not a function
at continueScramConversation (/app/webpack:[...]/mongodb/lib/core/auth/scram.js:xxx:yy)
Note that Mongoose applications can also be affected, as Mongoose wraps the Node.js driver:
1
2
TypeError: (0 , o.saslprep) is not a function
at continueScramConversation (/app/webpack:[...]/mongoose/node_modules/mongodb/lib/cmap/auth/scram.js:xxx:yy)
Next Steps
The underlying issue was addressed in versions 5.7.0, 4.17.0 and 3.7.4 of the MongoDB Node.js driver, so depending on the version of the driver being used by your application a minor version update will address this.
Upgrading your application’s libraries and deploying to production may not always be possible in a timely fashion. If this is the case and you happen to hit the issue described above a workaround would be to append the authMechanism
option to your connection string with a value of SCRAM-SHA-1
as follows:
1
mongodb+srv://xyz.mongodb.net/test?authMechanism=SCRAM-SHA-1
This will force the driver to attempt authorization using the SCRAM-SHA-1
hashing algorithm. Note that connection string changes would still require the application to be restarted for those changes to take effect.
Comments powered by Disqus.