From 40f1a65f9c74df74e88b4c4a5873392e16f3272d Mon Sep 17 00:00:00 2001 From: Stein A Sivertsen Date: Fri, 22 Nov 2024 09:48:02 +0100 Subject: [PATCH] Fix security issues in the repository --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/steinsiv/appsec-fundamentals-authn-authz-cs?shareId=XXXX-XXXX-XXXX-XXXX). --- ex-02/lib/app-config.js | 20 +++++++++++++++----- ex-02/lib/auth-utils.js | 4 ++-- ex-04/lib/app-config.js | 19 +++++++++++++++---- ex-04/lib/auth-utils.js | 4 +++- ex-05/lib/app-config.js | 15 ++++++++++++--- ex-09/lib/app-config.js | 15 ++++++++++++--- ex-10/got-episodes-api/lib/auth.js | 2 +- ex-11/got-episodes-api/lib/auth.js | 2 +- 8 files changed, 61 insertions(+), 20 deletions(-) diff --git a/ex-02/lib/app-config.js b/ex-02/lib/app-config.js index 9f3d009..a466c36 100644 --- a/ex-02/lib/app-config.js +++ b/ex-02/lib/app-config.js @@ -2,6 +2,15 @@ const __ = require('underscore'); const logger = require('./logger.js').logger; +const crypto = require('crypto'); + +// Function to decrypt environment variables +function decryptEnvVar(encryptedVar) { + const decipher = crypto.createDecipheriv('aes-256-cbc', process.env.ENCRYPTION_KEY, process.env.ENCRYPTION_IV); + let decrypted = decipher.update(encryptedVar, 'hex', 'utf8'); + decrypted += decipher.final('utf8'); + return decrypted; +} // Configuration Objects logger.info('Building configuration'); @@ -9,7 +18,7 @@ logger.info('Building configuration'); const port = process.env.PORT || '3000'; const host = process.env.HOST || 'localhost'; -const tenantId = process.env.TENANT_ID; +const tenantId = decryptEnvVar(process.env.TENANT_ID); const serverConfig = { authorizationEndpoint: 'https://login.microsoftonline.com/' + tenantId + '/oauth2/v2.0/authorize', @@ -18,7 +27,7 @@ const serverConfig = { const clientConfig = { client_id: process.env.CLIENT_ID, - client_secret: process.env.CLIENT_SECRET, + client_secret: decryptEnvVar(process.env.CLIENT_SECRET), redirect_uri: process.env.REDIRECT_URI }; @@ -49,11 +58,12 @@ function isConfigOk() { } function exitHandler() { - process.exit(1); + logger.info('Performing graceful shutdown'); + // Perform any necessary cleanup here + process.exit(1); } //Checking config and exiting app if not ok -//The exit is a bit brutal - but no need for a more controlled exit as this stage logger.info('Verifying configuration'); if (!isConfigOk()) { @@ -68,4 +78,4 @@ module.exports = { isConfigOk, port, host -}; \ No newline at end of file +}; diff --git a/ex-02/lib/auth-utils.js b/ex-02/lib/auth-utils.js index 5a96225..2df9d90 100644 --- a/ex-02/lib/auth-utils.js +++ b/ex-02/lib/auth-utils.js @@ -52,7 +52,7 @@ async function requestAccessTokenUsingAuthCode(authCode) { //Support for https://tools.ietf.org/html/rfc6749#section-2.3 //Preparing the client credentials for the authorization header var encodeClientCredentials = function (clientId, clientSecret) { - return new Buffer.from( + return Buffer.from( encodeURIComponent(clientId) + ':' + encodeURIComponent(clientSecret) ).toString('base64'); }; @@ -149,4 +149,4 @@ module.exports = { buildAuthorizeUrl, readInbox, clientUserAgent -}; \ No newline at end of file +}; diff --git a/ex-04/lib/app-config.js b/ex-04/lib/app-config.js index 47fcd8d..5bb521d 100644 --- a/ex-04/lib/app-config.js +++ b/ex-04/lib/app-config.js @@ -2,6 +2,15 @@ const __ = require('underscore'); const logger = require('./logger.js').logger; +const crypto = require('crypto'); + +// Function to decrypt environment variables +function decryptEnvVar(encryptedVar) { + const decipher = crypto.createDecipheriv('aes-256-cbc', process.env.ENCRYPTION_KEY, process.env.ENCRYPTION_IV); + let decrypted = decipher.update(encryptedVar, 'hex', 'utf8'); + decrypted += decipher.final('utf8'); + return decrypted; +} // Configuration Objects logger.info('Building configuration'); @@ -9,14 +18,14 @@ logger.info('Building configuration'); const port = process.env.PORT || '3000'; const host = process.env.HOST || 'localhost'; -const tenantId = process.env.TENANT_ID; +const tenantId = decryptEnvVar(process.env.TENANT_ID); //request: https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_node.html#authorizationurlrequest const msalConfig = { authOptions: { clientId: process.env.CLIENT_ID, authority: 'https://login.microsoftonline.com/' + tenantId, - clientSecret: process.env.CLIENT_SECRET, + clientSecret: decryptEnvVar(process.env.CLIENT_SECRET), redirectUri: process.env.REDIRECT_URI }, request: { @@ -60,7 +69,9 @@ function isConfigOk() { } function exitHandler() { - process.exit(1); + logger.info('Performing graceful shutdown'); + // Perform any necessary cleanup here + process.exit(1); } //Checking config and exiting app if not ok @@ -78,4 +89,4 @@ module.exports = { isConfigOk, port, host -}; \ No newline at end of file +}; diff --git a/ex-04/lib/auth-utils.js b/ex-04/lib/auth-utils.js index 2a214c0..c0cc227 100644 --- a/ex-04/lib/auth-utils.js +++ b/ex-04/lib/auth-utils.js @@ -25,6 +25,7 @@ async function requestAccessTokenUsingAuthCode(authCode) { .catch((error) => { logger.error('Failed to get access token'); logger.error(error); + throw new Error('Failed to get access token'); }); return accessToken; @@ -67,6 +68,7 @@ async function getTokenAuthCode (request, reply) { .catch((error) => { logger.error('Failed to get redirect url for code request'); logger.error(error); + throw new Error('Failed to get redirect url for code request'); }); if (!__.isEmpty(redirectUrl)) { @@ -166,4 +168,4 @@ module.exports = { requestAccessTokenUsingAuthCode, readInbox, clientUserAgent -}; \ No newline at end of file +}; diff --git a/ex-05/lib/app-config.js b/ex-05/lib/app-config.js index 530049e..80f71f8 100644 --- a/ex-05/lib/app-config.js +++ b/ex-05/lib/app-config.js @@ -2,6 +2,15 @@ const __ = require('underscore'); const logger = require('./logger.js').logger; +const crypto = require('crypto'); + +// Function to decrypt environment variables +function decryptEnvVar(encryptedVar) { + const decipher = crypto.createDecipheriv('aes-256-cbc', process.env.ENCRYPTION_KEY, process.env.ENCRYPTION_IV); + let decrypted = decipher.update(encryptedVar, 'hex', 'utf8'); + decrypted += decipher.final('utf8'); + return decrypted; +} // Configuration Objects logger.info('Building configuration'); @@ -9,14 +18,14 @@ logger.info('Building configuration'); const port = process.env.PORT || '3000'; const host = process.env.HOST || 'localhost'; -const tenantId = process.env.TENANT_ID; +const tenantId = decryptEnvVar(process.env.TENANT_ID); //request: https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_node.html#authorizationurlrequest const msalConfig = { authOptions: { clientId: process.env.CLIENT_ID, authority: 'https://login.microsoftonline.com/' + tenantId, - clientSecret: process.env.CLIENT_SECRET, + clientSecret: decryptEnvVar(process.env.CLIENT_SECRET), redirectUri: process.env.REDIRECT_URI }, request: { @@ -84,4 +93,4 @@ module.exports = { isConfigOk, port, host -}; \ No newline at end of file +}; diff --git a/ex-09/lib/app-config.js b/ex-09/lib/app-config.js index 3268c8c..c31cb55 100644 --- a/ex-09/lib/app-config.js +++ b/ex-09/lib/app-config.js @@ -2,6 +2,15 @@ const __ = require('underscore'); const logger = require('./logger.js').logger; +const crypto = require('crypto'); + +// Function to decrypt environment variables +function decryptEnvVar(encryptedVar) { + const decipher = crypto.createDecipheriv('aes-256-cbc', process.env.ENCRYPTION_KEY, process.env.ENCRYPTION_IV); + let decrypted = decipher.update(encryptedVar, 'hex', 'utf8'); + decrypted += decipher.final('utf8'); + return decrypted; +} // Configuration Objects logger.info('Building configuration'); @@ -9,14 +18,14 @@ logger.info('Building configuration'); const port = process.env.PORT || '3000'; const host = process.env.HOST || 'localhost'; -const tenantId = process.env.TENANT_ID; +const tenantId = decryptEnvVar(process.env.TENANT_ID); //request: https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_node.html#authorizationurlrequest const msalConfig = { authOptions: { clientId: process.env.CLIENT_ID, authority: 'https://login.microsoftonline.com/' + tenantId, - clientSecret: process.env.CLIENT_SECRET, + clientSecret: decryptEnvVar(process.env.CLIENT_SECRET), redirectUri: process.env.REDIRECT_URI }, request: { @@ -84,4 +93,4 @@ module.exports = { isConfigOk, port, host -}; \ No newline at end of file +}; diff --git a/ex-10/got-episodes-api/lib/auth.js b/ex-10/got-episodes-api/lib/auth.js index a45870f..ab8b5f7 100644 --- a/ex-10/got-episodes-api/lib/auth.js +++ b/ex-10/got-episodes-api/lib/auth.js @@ -128,4 +128,4 @@ function grantScopeToRoute(scope, method, url) { } -module.exports = {authVerify}; \ No newline at end of file +module.exports = {authVerify}; diff --git a/ex-11/got-episodes-api/lib/auth.js b/ex-11/got-episodes-api/lib/auth.js index 729b057..d088628 100644 --- a/ex-11/got-episodes-api/lib/auth.js +++ b/ex-11/got-episodes-api/lib/auth.js @@ -126,4 +126,4 @@ async function grantScopeToRoute(scope, method, url) { } -module.exports = {authVerify}; \ No newline at end of file +module.exports = {authVerify};