diff --git a/CHANGELOG.yaml b/CHANGELOG.yaml index 53d141676..b07dd64b8 100644 --- a/CHANGELOG.yaml +++ b/CHANGELOG.yaml @@ -3,6 +3,7 @@ unreleased: - GH-1522 Add support for referencing pre-defined collection requests using `pm.execution.runRequest` fixed bugs: - GH-1523 Fixed downloadedBytes tracking for redirected requests + - GH-1524 Fixed a bug where incorrect digest auth header was getting used to compute hash. chores: - Updated dependencies diff --git a/lib/authorizer/digest.js b/lib/authorizer/digest.js index 985cc37d9..cd0fa6518 100644 --- a/lib/authorizer/digest.js +++ b/lib/authorizer/digest.js @@ -136,13 +136,33 @@ _extractField = function (string, regexp) { * there can be more than one header with the same key. So need to loop over and check each one. * * @param {VariableList} headers - + * @param {String} selectedAlgorithm - The user opted algorithm (MD5, SHA-256 etc) * @private */ -function _getDigestAuthHeader (headers) { - return headers.find(function (property) { +function _getDigestAuthHeader (headers, selectedAlgorithm) { + const digestAuthHeaders = headers.filter(function (property) { return (property.key.toLowerCase() === WWW_AUTHENTICATE) && (_.startsWith(String(property.value).toLowerCase(), DIGEST_PREFIX.toLowerCase())); }); + + let headerWithMatchingOptedAlgorithm; + + if (selectedAlgorithm) { + const targetAlgorithm = selectedAlgorithm.toLowerCase(); + + headerWithMatchingOptedAlgorithm = digestAuthHeaders.find(function (header) { + const headerValue = String(header.value).toLowerCase(); + + if (!headerValue.includes('algorithm=')) { + // This is an MD5 header. Ref: https://datatracker.ietf.org/doc/html/rfc7616 + return targetAlgorithm === 'md5'; + } + + return headerValue.includes(`algorithm=${targetAlgorithm}`); + }); + } + + return headerWithMatchingOptedAlgorithm || digestAuthHeaders[0]; } /** @@ -314,6 +334,7 @@ module.exports = { var code, nonceCount, + algorithm, realm, nonce, qop, @@ -323,7 +344,9 @@ module.exports = { code = response.code; nonceCount = auth.get('nonceCount'); - authHeader = _getDigestAuthHeader(response.headers); + algorithm = auth.get('algorithm'); + + authHeader = _getDigestAuthHeader(response.headers, algorithm); // If code is forbidden or unauthorized, and an auth header exists, // we can extract the realm & the nonce, and replay the request.