From 078aa0fc6505c98b040af3830de3cba122e8faa6 Mon Sep 17 00:00:00 2001 From: Anton Nikitiuk Date: Tue, 14 Jul 2026 20:38:44 +0300 Subject: [PATCH 1/2] Disable CA Pinning: Add constructor parameter --- lib/main.js | 9 ++++++--- tests/main.js | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/lib/main.js b/lib/main.js index 3394b9f..3a264d3 100644 --- a/lib/main.js +++ b/lib/main.js @@ -7,11 +7,12 @@ const _PACKAGE_VERSION = require('../package.json').version const SIGNATURE_VERSION_2 = 2 const SIGNATURE_VERSION_5 = 5 -function Client (ikey, skey, host, sigVersion = SIGNATURE_VERSION_2) { +function Client (ikey, skey, host, sigVersion = SIGNATURE_VERSION_2, enableCAPinning = true) { this.ikey = ikey this.skey = skey this.host = host this.sigVersion = sigVersion + this.enableCAPinning = enableCAPinning } Client.prototype.apiCall = function (method, path, params, callback) { @@ -52,8 +53,10 @@ Client.prototype.apiCall = function (method, path, params, callback) { 'host': this.host, 'method': method, 'path': path, - 'headers': headers, - 'ca': constants.DUO_PINNED_CERT + 'headers': headers + } + if (this.enableCAPinning) { + options.ca = constants.DUO_PINNED_CERT } _request_with_backoff(options, body, callback) } diff --git a/tests/main.js b/tests/main.js index 407bb4f..8343317 100644 --- a/tests/main.js +++ b/tests/main.js @@ -2,8 +2,10 @@ var assert = require('assert') var nock = require('nock') var sinon = require('sinon') +var https = require('https') var duo_api = require('../lib/main.js') var duo_sig = require('../lib/duo_sig') +var constants = require('../lib/constants') var IKEY = 'DIXXXXXXXXXXXXXXXXXX' var SKEY = 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef' @@ -189,3 +191,47 @@ describe('Signature Checks', function () { }) }) }) + +describe('CA Pinning Configuration', function () { + var requestSpy + + beforeEach(function () { + requestSpy = sinon.spy(https, 'request') + nock('https://' + API_HOSTNAME) + .get('/foo/bar') + .reply(200, {'response': {foo: 'bar'}, stat: 'OK'}) + }) + + afterEach(function () { + requestSpy.restore() + }) + + it('CA pinning is enabled by default', function (done) { + var client = new duo_api.Client(IKEY, SKEY, API_HOSTNAME) + assert.strictEqual(client.enableCAPinning, true) + client.jsonApiCall('GET', '/foo/bar', {}, function (resp) { + var options = requestSpy.firstCall.args[0] + assert.strictEqual(options.ca, constants.DUO_PINNED_CERT) + done() + }) + }) + + it('CA pinning can be disabled via constructor parameter', function (done) { + var client = new duo_api.Client(IKEY, SKEY, API_HOSTNAME, duo_api.SIGNATURE_VERSION_2, false) + assert.strictEqual(client.enableCAPinning, false) + client.jsonApiCall('GET', '/foo/bar', {}, function (resp) { + var options = requestSpy.firstCall.args[0] + assert.strictEqual(options.ca, undefined) + done() + }) + }) + + it('TLS verification is still enforced when CA pinning is disabled', function (done) { + var client = new duo_api.Client(IKEY, SKEY, API_HOSTNAME, duo_api.SIGNATURE_VERSION_2, false) + client.jsonApiCall('GET', '/foo/bar', {}, function (resp) { + var options = requestSpy.firstCall.args[0] + assert.strictEqual(options.rejectUnauthorized, undefined) + done() + }) + }) +}) From e871e93e2aa8946215df011aa2e0340dffb0717a Mon Sep 17 00:00:00 2001 From: Anton Nikitiuk Date: Thu, 16 Jul 2026 09:34:50 +0300 Subject: [PATCH 2/2] Explicitly enforce TLS verification to override NODE_TLS_REJECT_UNAUTHORIZED env var --- lib/main.js | 3 ++- tests/main.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/main.js b/lib/main.js index 3a264d3..d899f0b 100644 --- a/lib/main.js +++ b/lib/main.js @@ -53,7 +53,8 @@ Client.prototype.apiCall = function (method, path, params, callback) { 'host': this.host, 'method': method, 'path': path, - 'headers': headers + 'headers': headers, + 'rejectUnauthorized': true } if (this.enableCAPinning) { options.ca = constants.DUO_PINNED_CERT diff --git a/tests/main.js b/tests/main.js index 8343317..a5daad3 100644 --- a/tests/main.js +++ b/tests/main.js @@ -230,7 +230,7 @@ describe('CA Pinning Configuration', function () { var client = new duo_api.Client(IKEY, SKEY, API_HOSTNAME, duo_api.SIGNATURE_VERSION_2, false) client.jsonApiCall('GET', '/foo/bar', {}, function (resp) { var options = requestSpy.firstCall.args[0] - assert.strictEqual(options.rejectUnauthorized, undefined) + assert.strictEqual(options.rejectUnauthorized, true) done() }) })