From 0a73825ebe7b1d32fd277dcede1d75505aeda207 Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Thu, 30 Dec 2021 20:32:06 +0000 Subject: [PATCH 01/11] Added algorithm-choice support to JWT Verify --- src/core/operations/JWTVerify.mjs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/core/operations/JWTVerify.mjs b/src/core/operations/JWTVerify.mjs index 604edc9c..e2b183d0 100644 --- a/src/core/operations/JWTVerify.mjs +++ b/src/core/operations/JWTVerify.mjs @@ -26,12 +26,19 @@ class JWTVerify extends Operation { this.infoURL = "https://wikipedia.org/wiki/JSON_Web_Token"; this.inputType = "string"; this.outputType = "JSON"; + let algOptions = JWT_ALGORITHMS.slice(0, JWT_ALGORITHMS.length - 1); + algOptions.push("Any"); this.args = [ { name: "Public/Secret Key", type: "text", value: "secret" }, + { + name: "Algorithm", + type: "option", + value: algOptions + } ]; } @@ -41,9 +48,21 @@ class JWTVerify extends Operation { * @returns {string} */ run(input, args) { - const [key] = args; - const algos = JWT_ALGORITHMS; - algos[algos.indexOf("None")] = "none"; + const [key, alg] = args; + switch (alg) { + case "Any": + const algos = JWT_ALGORITHMS; + break; + case "None": + const algos = [ "none" ]; + default: + const algIndex = JWT_ALGORITHMS.indexOf(alg); + if (algIndex === -1) { + throw new OperationError("The JWT verification algorithm provided is not supported."); + } + const algos = JWT_ALGORITHMS[]; + break; + } try { const verified = jwt.verify(input, key, { algorithms: algos }); From b713be5a9ef421498436cc31237a75e12cff276c Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Thu, 30 Dec 2021 20:36:30 +0000 Subject: [PATCH 02/11] Fixed compilation error --- src/core/operations/JWTVerify.mjs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/core/operations/JWTVerify.mjs b/src/core/operations/JWTVerify.mjs index e2b183d0..71859619 100644 --- a/src/core/operations/JWTVerify.mjs +++ b/src/core/operations/JWTVerify.mjs @@ -49,18 +49,15 @@ class JWTVerify extends Operation { */ run(input, args) { const [key, alg] = args; + let algos = []; switch (alg) { case "Any": - const algos = JWT_ALGORITHMS; + algos = JWT_ALGORITHMS; break; case "None": - const algos = [ "none" ]; + algos.push("none"); default: - const algIndex = JWT_ALGORITHMS.indexOf(alg); - if (algIndex === -1) { - throw new OperationError("The JWT verification algorithm provided is not supported."); - } - const algos = JWT_ALGORITHMS[]; + algos.push(alg); break; } From d27094574f559635ad26925f7d2329434d46727f Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Thu, 30 Dec 2021 20:45:37 +0000 Subject: [PATCH 03/11] Update JWTVerify.mjs --- src/core/operations/JWTVerify.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/operations/JWTVerify.mjs b/src/core/operations/JWTVerify.mjs index 71859619..2fe09c34 100644 --- a/src/core/operations/JWTVerify.mjs +++ b/src/core/operations/JWTVerify.mjs @@ -26,8 +26,8 @@ class JWTVerify extends Operation { this.infoURL = "https://wikipedia.org/wiki/JSON_Web_Token"; this.inputType = "string"; this.outputType = "JSON"; - let algOptions = JWT_ALGORITHMS.slice(0, JWT_ALGORITHMS.length - 1); - algOptions.push("Any"); + this.algOptions = JWT_ALGORITHMS; + this.algOptions.push("Any"); this.args = [ { name: "Public/Secret Key", @@ -37,7 +37,7 @@ class JWTVerify extends Operation { { name: "Algorithm", type: "option", - value: algOptions + value: this.algOptions } ]; } From 6456e5860f08ec1d6dc39757e9494c974e157261 Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Thu, 30 Dec 2021 20:48:43 +0000 Subject: [PATCH 04/11] Fixed compilation error I thought that the previous commit would fix the issue but hadn't properly read the error. --- src/core/operations/JWTVerify.mjs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/operations/JWTVerify.mjs b/src/core/operations/JWTVerify.mjs index 2fe09c34..7d9aba91 100644 --- a/src/core/operations/JWTVerify.mjs +++ b/src/core/operations/JWTVerify.mjs @@ -26,8 +26,8 @@ class JWTVerify extends Operation { this.infoURL = "https://wikipedia.org/wiki/JSON_Web_Token"; this.inputType = "string"; this.outputType = "JSON"; - this.algOptions = JWT_ALGORITHMS; - this.algOptions.push("Any"); + let algOptions = JWT_ALGORITHMS; + algOptions.push("Any"); this.args = [ { name: "Public/Secret Key", @@ -37,7 +37,7 @@ class JWTVerify extends Operation { { name: "Algorithm", type: "option", - value: this.algOptions + value: algOptions } ]; } @@ -56,6 +56,7 @@ class JWTVerify extends Operation { break; case "None": algos.push("none"); + break; default: algos.push(alg); break; From 53a7debf9aaaedb30e808832dbbeb69489ad18b5 Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Thu, 30 Dec 2021 20:51:05 +0000 Subject: [PATCH 05/11] Update JWTVerify.mjs --- src/core/operations/JWTVerify.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/JWTVerify.mjs b/src/core/operations/JWTVerify.mjs index 7d9aba91..90563776 100644 --- a/src/core/operations/JWTVerify.mjs +++ b/src/core/operations/JWTVerify.mjs @@ -26,7 +26,7 @@ class JWTVerify extends Operation { this.infoURL = "https://wikipedia.org/wiki/JSON_Web_Token"; this.inputType = "string"; this.outputType = "JSON"; - let algOptions = JWT_ALGORITHMS; + const algOptions = JWT_ALGORITHMS; algOptions.push("Any"); this.args = [ { From e5497fcd5aee72fae2138e020f1c261adfbba3a1 Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Thu, 30 Dec 2021 21:04:02 +0000 Subject: [PATCH 06/11] Argument naming consistency 'JWT Sign' uses 'Signing algorithm' as oppose to 'Algorithm' --- src/core/operations/JWTVerify.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/JWTVerify.mjs b/src/core/operations/JWTVerify.mjs index 90563776..6b06d914 100644 --- a/src/core/operations/JWTVerify.mjs +++ b/src/core/operations/JWTVerify.mjs @@ -35,7 +35,7 @@ class JWTVerify extends Operation { value: "secret" }, { - name: "Algorithm", + name: "Signing algorithm", type: "option", value: algOptions } From 14ea150be472ad09dc543731a864aa441a7070fe Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Thu, 30 Dec 2021 22:52:09 +0000 Subject: [PATCH 07/11] Added @author --- src/core/operations/JWTVerify.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/operations/JWTVerify.mjs b/src/core/operations/JWTVerify.mjs index 6b06d914..65daa4b8 100644 --- a/src/core/operations/JWTVerify.mjs +++ b/src/core/operations/JWTVerify.mjs @@ -1,5 +1,6 @@ /** * @author gchq77703 [] + * @author Michael Rowley [michaellrowley@protonmail.com] * @copyright Crown Copyright 2018 * @license Apache-2.0 */ From 8332e39b6b62ff019f83bb78783fd95fce18ffa7 Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Fri, 31 Dec 2021 22:03:23 +0000 Subject: [PATCH 08/11] Revert "Added @author" This reverts commit 14ea150be472ad09dc543731a864aa441a7070fe. --- src/core/operations/JWTVerify.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/operations/JWTVerify.mjs b/src/core/operations/JWTVerify.mjs index 65daa4b8..6b06d914 100644 --- a/src/core/operations/JWTVerify.mjs +++ b/src/core/operations/JWTVerify.mjs @@ -1,6 +1,5 @@ /** * @author gchq77703 [] - * @author Michael Rowley [michaellrowley@protonmail.com] * @copyright Crown Copyright 2018 * @license Apache-2.0 */ From d23d98d2a0ac66da87ec6daa70c1d8c30c48ec97 Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Mon, 21 Mar 2022 20:50:43 +0000 Subject: [PATCH 09/11] Updated algorithm selection --- src/core/lib/JWT.mjs | 3 +-- src/core/operations/JWTSign.mjs | 3 ++- src/core/operations/JWTVerify.mjs | 19 +++---------------- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/core/lib/JWT.mjs b/src/core/lib/JWT.mjs index fee7fec5..57a82d21 100644 --- a/src/core/lib/JWT.mjs +++ b/src/core/lib/JWT.mjs @@ -19,6 +19,5 @@ export const JWT_ALGORITHMS = [ "RS512", "ES256", "ES384", - "ES512", - "None" + "ES512" ]; diff --git a/src/core/operations/JWTSign.mjs b/src/core/operations/JWTSign.mjs index af46908e..813b8b26 100644 --- a/src/core/operations/JWTSign.mjs +++ b/src/core/operations/JWTSign.mjs @@ -26,6 +26,7 @@ class JWTSign extends Operation { this.infoURL = "https://wikipedia.org/wiki/JSON_Web_Token"; this.inputType = "JSON"; this.outputType = "string"; + const algorithmList = JWT_ALGORITHMS.concat(["None"]); this.args = [ { name: "Private/Secret Key", @@ -35,7 +36,7 @@ class JWTSign extends Operation { { name: "Signing algorithm", type: "option", - value: JWT_ALGORITHMS + value: algorithmList } ]; } diff --git a/src/core/operations/JWTVerify.mjs b/src/core/operations/JWTVerify.mjs index 6b06d914..3d86ec31 100644 --- a/src/core/operations/JWTVerify.mjs +++ b/src/core/operations/JWTVerify.mjs @@ -26,8 +26,7 @@ class JWTVerify extends Operation { this.infoURL = "https://wikipedia.org/wiki/JSON_Web_Token"; this.inputType = "string"; this.outputType = "JSON"; - const algOptions = JWT_ALGORITHMS; - algOptions.push("Any"); + const algorithmList = JWT_ALGORITHMS.concat(["Any"]); this.args = [ { name: "Public/Secret Key", @@ -37,7 +36,7 @@ class JWTVerify extends Operation { { name: "Signing algorithm", type: "option", - value: algOptions + value: algorithmList } ]; } @@ -49,19 +48,7 @@ class JWTVerify extends Operation { */ run(input, args) { const [key, alg] = args; - let algos = []; - switch (alg) { - case "Any": - algos = JWT_ALGORITHMS; - break; - case "None": - algos.push("none"); - break; - default: - algos.push(alg); - break; - } - + let algos = (alg == "Any" ? JWT_ALGORITHMS : alg); try { const verified = jwt.verify(input, key, { algorithms: algos }); From da77362b14cc6f9cb9a1ac817e09029b6cb5269c Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Tue, 22 Mar 2022 07:49:01 +0000 Subject: [PATCH 10/11] Added tests --- tests/operations/tests/JWTVerify.mjs | 57 +++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/tests/operations/tests/JWTVerify.mjs b/tests/operations/tests/JWTVerify.mjs index 0a0817cc..48cee153 100644 --- a/tests/operations/tests/JWTVerify.mjs +++ b/tests/operations/tests/JWTVerify.mjs @@ -50,38 +50,77 @@ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEVs/o5+uQbTjL3chynL4wXgUg2R9 q9UU8I5mEovUf86QZ7kOBIjJwqnzD1omageEHWwHdBO6B+dFabmdT9POxg== -----END PUBLIC KEY-----`; +const signedInputs = { + HS: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.0ha6-j4FwvEIKPVZ-hf3S_R9Hy_UtXzq4dnedXcUrXk", + RS: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.MjEJhtZk2nXzigi24piMzANmrj3mILHJcDl0xOjl5a8EgdKVL1oaMEjTkMQp5RA8YrqeRBFaX-BGGCKOXn5zPY1DJwWsBUyN9C-wGR2Qye0eogH_3b4M9EW00TPCUPXm2rx8URFj7Wg9VlsmrGzLV2oKkPgkVxuFSxnpO3yjn1Y", + ES: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.WkECT51jSfpRkcpQ4x0h5Dwe7CFBI6u6Et2gWp91HC7mpN_qCFadRpsvJLtKubm6cJTLa68xtei0YrDD8fxIUA" +}; + TestRegister.addTests([ { name: "JWT Verify: HS", - input: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.0ha6-j4FwvEIKPVZ-hf3S_R9Hy_UtXzq4dnedXcUrXk", + input: signedInputs.HS, expectedOutput: outputObject, recipeConfig: [ { op: "JWT Verify", - args: [hsKey], + args: [hsKey, "HS256"], } - ], + ] + }, + { + name: "JWT Verify: Invalid HS", + input: signedInputs.HS, + expectedOutput: "JsonWebTokenError: invalid algorithm", + recipeConfig: [ + { + op: "JWT Verify", + args: [hsKey, "RS256"], + } + ] }, { name: "JWT Verify: RS", - input: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.MjEJhtZk2nXzigi24piMzANmrj3mILHJcDl0xOjl5a8EgdKVL1oaMEjTkMQp5RA8YrqeRBFaX-BGGCKOXn5zPY1DJwWsBUyN9C-wGR2Qye0eogH_3b4M9EW00TPCUPXm2rx8URFj7Wg9VlsmrGzLV2oKkPgkVxuFSxnpO3yjn1Y", + input: signedInputs.RS, expectedOutput: outputObject, recipeConfig: [ { op: "JWT Verify", - args: [rsPub], + args: [rsPub, "RS256"], } - ], + ] + }, + { + name: "JWT Verify: Invalid RS", + input: signedInputs.RS, + expectedOutput: "JsonWebTokenError: invalid algorithm", + recipeConfig: [ + { + op: "JWT Verify", + args: [rsPub, "ES256"], + } + ] }, { name: "JWT Verify: ES", - input: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.WkECT51jSfpRkcpQ4x0h5Dwe7CFBI6u6Et2gWp91HC7mpN_qCFadRpsvJLtKubm6cJTLa68xtei0YrDD8fxIUA", + input: signedInputs.ES, expectedOutput: outputObject, recipeConfig: [ { op: "JWT Verify", - args: [esPub], + args: [esPub, "ES256"], } - ], + ] + }, + { + name: "JWT Verify: Invalid ES", + input: signedInputs.ES, + expectedOutput: "JsonWebTokenError: invalid algorithm", + recipeConfig: [ + { + op: "JWT Verify", + args: [esPub, "HS256"], + } + ] } ]); From 44af3fee38ec27e5194cc5d8dae3c048a451b5e2 Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Tue, 22 Mar 2022 08:14:06 +0000 Subject: [PATCH 11/11] Fixed compilation warnings --- src/core/operations/JWTVerify.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/JWTVerify.mjs b/src/core/operations/JWTVerify.mjs index 3d86ec31..fada2f56 100644 --- a/src/core/operations/JWTVerify.mjs +++ b/src/core/operations/JWTVerify.mjs @@ -48,7 +48,7 @@ class JWTVerify extends Operation { */ run(input, args) { const [key, alg] = args; - let algos = (alg == "Any" ? JWT_ALGORITHMS : alg); + const algos = (alg === "Any" ? JWT_ALGORITHMS : alg); try { const verified = jwt.verify(input, key, { algorithms: algos });