summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatteo Collina <hello@matteocollina.com>2021-08-04 18:40:00 +0200
committerBeth Griggs <bgriggs@redhat.com>2021-08-09 17:19:09 +0100
commit1780bbc3291357f7c3370892eb311fc7a62afe8d (patch)
tree98aad4177f90978844485dc0384036e255c20198
parent9cd1f531034a91536f230be9647de865303d0e34 (diff)
downloadnode-new-1780bbc3291357f7c3370892eb311fc7a62afe8d.tar.gz
tls: validate "rejectUnauthorized: undefined"
Incomplete validation of rejectUnauthorized parameter (Low) If the Node.js https API was used incorrectly and "undefined" was passed in for the "rejectUnauthorized" parameter, no error was returned and connections to servers with an expired certificate would have been accepted. CVE-ID: CVE-2021-22939 Refs: https://nvd.nist.gov/vuln/detail/CVE-2021-22939 Refs: https://hackerone.com/reports/1278254 PR-URL: https://github.com/nodejs-private/node-private/pull/276 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Akshay K <iit.akshay@gmail.com> Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Richard Lau <rlau@redhat.com>
-rw-r--r--lib/_tls_wrap.js17
-rw-r--r--test/parallel/test-tls-client-reject.js13
2 files changed, 29 insertions, 1 deletions
diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js
index 1982261b80..9ab6a198ff 100644
--- a/lib/_tls_wrap.js
+++ b/lib/_tls_wrap.js
@@ -1516,7 +1516,15 @@ function onConnectSecure() {
this.authorized = false;
this.authorizationError = verifyError.code || verifyError.message;
- if (options.rejectUnauthorized) {
+ // rejectUnauthorized property can be explicitly defined as `undefined`
+ // causing the assignment to default value (`true`) fail. Before assigning
+ // it to the tlssock connection options, explicitly check if it is false
+ // and update rejectUnauthorized property. The property gets used by
+ // TLSSocket connection handler to allow or reject connection if
+ // unauthorized.
+ // This check is potentially redundant, however it is better to keep it
+ // in case the option object gets modified somewhere.
+ if (options.rejectUnauthorized !== false) {
this.destroy(verifyError);
return;
}
@@ -1598,6 +1606,13 @@ exports.connect = function connect(...args) {
pskCallback: options.pskCallback,
});
+ // rejectUnauthorized property can be explicitly defined as `undefined`
+ // causing the assignment to default value (`true`) fail. Before assigning
+ // it to the tlssock connection options, explicitly check if it is false
+ // and update rejectUnauthorized property. The property gets used by TLSSocket
+ // connection handler to allow or reject connection if unauthorized
+ options.rejectUnauthorized = options.rejectUnauthorized !== false;
+
tlssock[kConnectOptions] = options;
if (cb)
diff --git a/test/parallel/test-tls-client-reject.js b/test/parallel/test-tls-client-reject.js
index d41ad806ea..ea10ef6da2 100644
--- a/test/parallel/test-tls-client-reject.js
+++ b/test/parallel/test-tls-client-reject.js
@@ -72,6 +72,19 @@ function rejectUnauthorized() {
}, common.mustNotCall());
socket.on('data', common.mustNotCall());
socket.on('error', common.mustCall(function(err) {
+ rejectUnauthorizedUndefined();
+ }));
+ socket.end('ng');
+}
+
+function rejectUnauthorizedUndefined() {
+ console.log('reject unauthorized undefined');
+ const socket = tls.connect(server.address().port, {
+ servername: 'localhost',
+ rejectUnauthorized: undefined
+ }, common.mustNotCall());
+ socket.on('data', common.mustNotCall());
+ socket.on('error', common.mustCall(function(err) {
authorized();
}));
socket.end('ng');