From 70af9085941f79dc673a2389bdcc4dcb9a4579c3 Mon Sep 17 00:00:00 2001 From: alphadev4 Date: Wed, 22 Nov 2023 18:25:19 +0500 Subject: [PATCH 1/8] SAAS-20313/Front-Door-https-only --- exports.js | 4 +- helpers/azure/api.js | 5 + helpers/azure/locations.js | 3 +- plugins/azure/frontdoor/frontDoorHttpsOnly.js | 66 +++++++++ .../frontdoor/frontDoorHttpsOnly.spec.js | 128 ++++++++++++++++++ 5 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 plugins/azure/frontdoor/frontDoorHttpsOnly.js create mode 100644 plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js diff --git a/exports.js b/exports.js index 53c1523d03..cfe6becd0c 100644 --- a/exports.js +++ b/exports.js @@ -989,7 +989,9 @@ module.exports = { 'eventHubMinimumTLSversion' : require(__dirname + '/plugins/azure/eventhub/eventHubMinimumTLSversion.js'), 'accessLogsEnabled' : require(__dirname + '/plugins/azure/frontdoor/accessLogsEnabled.js'), - 'frontDoorMinimumTlsVersion' : require(__dirname + '/plugins/azure/frontdoor/frontDoorMinimumTlsVersion.js') + 'frontDoorMinimumTlsVersion' : require(__dirname + '/plugins/azure/frontdoor/frontDoorMinimumTlsVersion.js'), + 'frontDootHttpsOnly' : require(__dirname + '/plugins/azure/frontdoor/frontDootHttpsOnly.js'), + }, github: { 'publicKeysRotated' : require(__dirname + '/plugins/github/users/publicKeysRotated.js'), diff --git a/helpers/azure/api.js b/helpers/azure/api.js index 0c44596e9d..7b742773f6 100644 --- a/helpers/azure/api.js +++ b/helpers/azure/api.js @@ -478,6 +478,11 @@ var calls = { url: 'https://graph.microsoft.com/v1.0/servicePrincipals', graph: true } + }, + classicFrontDoors: { + list: { + url: 'https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Network/frontDoors?api-version=2019-05-01' + } } }; diff --git a/helpers/azure/locations.js b/helpers/azure/locations.js index 46dd902f36..88c33057dc 100644 --- a/helpers/azure/locations.js +++ b/helpers/azure/locations.js @@ -118,5 +118,6 @@ module.exports = { bastionHosts: locations, applications: ['global'], eventGrid: locations, - eventHub: locations + eventHub: locations, + classicFrontDoors: ['global'], }; diff --git a/plugins/azure/frontdoor/frontDoorHttpsOnly.js b/plugins/azure/frontdoor/frontDoorHttpsOnly.js new file mode 100644 index 0000000000..6afb1e5d7b --- /dev/null +++ b/plugins/azure/frontdoor/frontDoorHttpsOnly.js @@ -0,0 +1,66 @@ +const async = require('async'); +const helpers = require('../../../helpers/azure'); + +module.exports = { + title: 'Front Door HTTPS only', + category: 'Front Door', + domain: 'Content Delivery', + description: 'Ensures HTTPS Only is enabled for Front Door Classic profile, redirecting all HTTP traffic to HTTPS.', + more_info: 'By using the HTTPS only protocol, you ensure that your sensitive data is delivered securely via TLS/SSL encryption.', + recommended_action: 'Ensure that Front Door (classic) under the frontend hosts section has HTTP to HTTPS redirect rule.', + link: 'https://learn.microsoft.com/en-us/azure/frontdoor/front-door-how-to-redirect-https', + apis: ['classicFrontDoors:list'], + + run: function(cache, settings, callback) { + const results = []; + const source = {}; + const locations = helpers.locations(settings.govcloud); + async.each(locations.classicFrontDoors, (location, rcb) => { + const classicFrontDoors = + helpers.addSource(cache, source, + ['classicFrontDoors', 'list', location]); + + if (!classicFrontDoors) return rcb(); + + if (classicFrontDoors.err || !classicFrontDoors.data) { + helpers.addResult(results, 3, + 'Unable to query Front Door profiles: ' + helpers.addError(classicFrontDoors), location); + return rcb(); + } + + if (!classicFrontDoors.data.length) { + helpers.addResult(results, 0, 'No existing Classic Front Door profiles found', location); + return rcb(); + } + + classicFrontDoors.data.forEach(function(frontDoor) { + if (!frontDoor.id || !frontDoor.routingRules) return; + + var ruleFound = false; + for (var rule of frontDoor.routingRules) { + var ruleProperties = rule.properties? rule.properties : {}; + if (ruleProperties.acceptedProtocols && ruleProperties.acceptedProtocols[0].toLowerCase() =='http') { + if (ruleProperties.routeConfiguration && + ruleProperties.routeConfiguration.redirectType && + ruleProperties.routeConfiguration.redirectProtocol && + ruleProperties.routeConfiguration.redirectType.toLowerCase() == 'moved' && + ruleProperties.routeConfiguration.redirectProtocol.toLowerCase() == 'httpsonly') { + ruleFound = true; + break; + } + } + } + + if (ruleFound) { + helpers.addResult(results, 0, 'Classic Front Door profile is configured to use HTTPS only', location, frontDoor.id); + } else { + helpers.addResult(results, 2, 'Classic Front Door profile is not configured to use HTTPS only', location, frontDoor.id); + } + + }); + rcb(); + }, function() { + callback(null, results, source); + }); + } +}; \ No newline at end of file diff --git a/plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js b/plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js new file mode 100644 index 0000000000..3ecf66460e --- /dev/null +++ b/plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js @@ -0,0 +1,128 @@ +var expect = require('chai').expect; +var frontDoorHttpsOnly = require('./frontDoorHttpsOnly.js'); + +const classicFrontDoors = [ + { + id: '/subscriptions/1234567890/resourcegroups/meerab-rg/providers/Microsoft.Network/frontdoors/aquatest', + type: 'Microsoft.Network/frontdoors', + name: 'aquatest', + location: 'Global', + tags: {}, + routingRules: [ + { + "id": "/subscriptions/1234567890/resourcegroups/meerab-rg/providers/Microsoft.Network/Frontdoors/aquatest/RoutingRules/test-instance", + "name": "test-instance", + "type": "Microsoft.Network/Frontdoors/RoutingRules", + "properties": { + "routeConfiguration": { + "redirectType": "Moved", + "redirectProtocol": "HttpsOnly", + }, + "resourceState": "Enabled", + "acceptedProtocols": [ + "Http" + ] + } + }, + { + "id": "/subscriptions/1234567890/resourcegroups/meerab-rg/providers/Microsoft.Network/Frontdoors/aquatest/RoutingRules/rule2", + "name": "rule2", + "type": "Microsoft.Network/Frontdoors/RoutingRules", + "properties": { + "routeConfiguration": { + "redirectType": "Found", + "redirectProtocol": "HttpOnly", + }, + "acceptedProtocols": [ + "Https" + ], + } + } + ] + }, + { + id: '/subscriptions/1234567890/resourcegroups/meerab-rg/providers/Microsoft.Network/frontdoors/aquatest', + type: 'Microsoft.Network/frontdoors', + name: 'aquatest', + location: 'Global', + tags: {}, + routingRules: [ + { + "id": "/subscriptions/1234567890/resourcegroups/meerab-rg/providers/Microsoft.Network/Frontdoors/aquatest/RoutingRules/rule2", + "name": "rule2", + "type": "Microsoft.Network/Frontdoors/RoutingRules", + "properties": { + "routeConfiguration": { + "redirectType": "Found", + "redirectProtocol": "HttpOnly", + }, + "acceptedProtocols": [ + "Https" + ], + } + } + ] + } +]; + +const createCache = (classicFrontDoors) => { + return { + classicFrontDoors: { + list: { + 'global': { + data: classicFrontDoors + } + } + } + }; +}; + +const createErrorCache = () => { + return { + classicFrontDoors: { + list: { + 'global': { + data:{} + } + } + } + }; +}; +describe('frontDoorHttpsOnly', function () { + describe('run', function () { + + it('should give pass result if no classic Front Door profiles found', function (done) { + const cache = createErrorCache(); + frontDoorHttpsOnly.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].message).to.include('No existing Azure Classic Front Door profiles found'); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should give pass result if classic Front Door profile is configured to use Https only', function (done) { + const cache = createCache([classicFrontDoors[0]]); + frontDoorHttpsOnly.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].message).to.include('Classic Front Door profile is configured to use HTTPS only'); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should give fail result if classic Front Door profile is not configured to use Https only', function (done) { + const cache = createCache([classicFrontDoors[1]]); + frontDoorHttpsOnly.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].message).to.include('Classic Front Door profile is not configured to use HTTPS only'); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + }); +}); \ No newline at end of file From 884a5cc6239b293127b99dacbbf459f767377225 Mon Sep 17 00:00:00 2001 From: alphadev4 <113519745+alphadev4@users.noreply.github.com> Date: Wed, 22 Nov 2023 18:29:14 +0500 Subject: [PATCH 2/8] Update exports.js --- exports.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exports.js b/exports.js index cfe6becd0c..557f0fd7d9 100644 --- a/exports.js +++ b/exports.js @@ -990,7 +990,7 @@ module.exports = { 'accessLogsEnabled' : require(__dirname + '/plugins/azure/frontdoor/accessLogsEnabled.js'), 'frontDoorMinimumTlsVersion' : require(__dirname + '/plugins/azure/frontdoor/frontDoorMinimumTlsVersion.js'), - 'frontDootHttpsOnly' : require(__dirname + '/plugins/azure/frontdoor/frontDootHttpsOnly.js'), + 'frontDootHttpsOnly' : require(__dirname + '/plugins/azure/frontdoor/frontDoorHttpsOnly.js'), }, github: { From cadd244b580ea6955093eb1e92ea2e4c06c50bd1 Mon Sep 17 00:00:00 2001 From: alphadev4 <113519745+alphadev4@users.noreply.github.com> Date: Wed, 22 Nov 2023 20:23:16 +0500 Subject: [PATCH 3/8] Update plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js --- plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js b/plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js index 3ecf66460e..22d19fe0f0 100644 --- a/plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js +++ b/plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js @@ -96,7 +96,7 @@ describe('frontDoorHttpsOnly', function () { frontDoorHttpsOnly.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(0); - expect(results[0].message).to.include('No existing Azure Classic Front Door profiles found'); + expect(results[0].message).to.include('No existing Classic Front Door profiles found'); expect(results[0].region).to.equal('global'); done(); }); From 95dd19e66c2572aacd6d8959b29de2083024e532 Mon Sep 17 00:00:00 2001 From: alphadev4 Date: Thu, 23 Nov 2023 16:57:22 +0500 Subject: [PATCH 4/8] removed classic --- plugins/azure/frontdoor/frontDoorHttpsOnly.js | 6 +++--- plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/azure/frontdoor/frontDoorHttpsOnly.js b/plugins/azure/frontdoor/frontDoorHttpsOnly.js index 6afb1e5d7b..503491cb46 100644 --- a/plugins/azure/frontdoor/frontDoorHttpsOnly.js +++ b/plugins/azure/frontdoor/frontDoorHttpsOnly.js @@ -29,7 +29,7 @@ module.exports = { } if (!classicFrontDoors.data.length) { - helpers.addResult(results, 0, 'No existing Classic Front Door profiles found', location); + helpers.addResult(results, 0, 'No existing Front Door profiles found', location); return rcb(); } @@ -52,9 +52,9 @@ module.exports = { } if (ruleFound) { - helpers.addResult(results, 0, 'Classic Front Door profile is configured to use HTTPS only', location, frontDoor.id); + helpers.addResult(results, 0, 'Front Door profile is configured to use HTTPS only', location, frontDoor.id); } else { - helpers.addResult(results, 2, 'Classic Front Door profile is not configured to use HTTPS only', location, frontDoor.id); + helpers.addResult(results, 2, 'Front Door profile is not configured to use HTTPS only', location, frontDoor.id); } }); diff --git a/plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js b/plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js index 22d19fe0f0..c3061d0639 100644 --- a/plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js +++ b/plugins/azure/frontdoor/frontDoorHttpsOnly.spec.js @@ -96,7 +96,7 @@ describe('frontDoorHttpsOnly', function () { frontDoorHttpsOnly.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(0); - expect(results[0].message).to.include('No existing Classic Front Door profiles found'); + expect(results[0].message).to.include('No existing Front Door profiles found'); expect(results[0].region).to.equal('global'); done(); }); @@ -107,7 +107,7 @@ describe('frontDoorHttpsOnly', function () { frontDoorHttpsOnly.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(0); - expect(results[0].message).to.include('Classic Front Door profile is configured to use HTTPS only'); + expect(results[0].message).to.include('Front Door profile is configured to use HTTPS only'); expect(results[0].region).to.equal('global'); done(); }); @@ -118,7 +118,7 @@ describe('frontDoorHttpsOnly', function () { frontDoorHttpsOnly.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(2); - expect(results[0].message).to.include('Classic Front Door profile is not configured to use HTTPS only'); + expect(results[0].message).to.include('Front Door profile is not configured to use HTTPS only'); expect(results[0].region).to.equal('global'); done(); }); From 37bfa8f409c24d82c671f1a39378c3ba39afdd23 Mon Sep 17 00:00:00 2001 From: alphadev4 <113519745+alphadev4@users.noreply.github.com> Date: Thu, 23 Nov 2023 17:39:27 +0500 Subject: [PATCH 5/8] Apply suggestions from code review --- exports.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exports.js b/exports.js index 557f0fd7d9..42453bdaff 100644 --- a/exports.js +++ b/exports.js @@ -990,7 +990,7 @@ module.exports = { 'accessLogsEnabled' : require(__dirname + '/plugins/azure/frontdoor/accessLogsEnabled.js'), 'frontDoorMinimumTlsVersion' : require(__dirname + '/plugins/azure/frontdoor/frontDoorMinimumTlsVersion.js'), - 'frontDootHttpsOnly' : require(__dirname + '/plugins/azure/frontdoor/frontDoorHttpsOnly.js'), + 'frontDoorHttpsOnly' : require(__dirname + '/plugins/azure/frontdoor/frontDoorHttpsOnly.js'), }, github: { From eff8ab0708a0891eafb7c0850dae7fb382c264a5 Mon Sep 17 00:00:00 2001 From: alphadev4 <113519745+alphadev4@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:28:21 +0500 Subject: [PATCH 6/8] Apply suggestions from code review --- plugins/azure/frontdoor/frontDoorHttpsOnly.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/azure/frontdoor/frontDoorHttpsOnly.js b/plugins/azure/frontdoor/frontDoorHttpsOnly.js index 503491cb46..e18d4b9743 100644 --- a/plugins/azure/frontdoor/frontDoorHttpsOnly.js +++ b/plugins/azure/frontdoor/frontDoorHttpsOnly.js @@ -5,9 +5,9 @@ module.exports = { title: 'Front Door HTTPS only', category: 'Front Door', domain: 'Content Delivery', - description: 'Ensures HTTPS Only is enabled for Front Door Classic profile, redirecting all HTTP traffic to HTTPS.', + description: 'Ensures HTTPS Only is enabled for Front Door classic profile, redirecting all HTTP traffic to HTTPS.', more_info: 'By using the HTTPS only protocol, you ensure that your sensitive data is delivered securely via TLS/SSL encryption.', - recommended_action: 'Ensure that Front Door (classic) under the frontend hosts section has HTTP to HTTPS redirect rule.', + recommended_action: 'Modify the Front Door classic profile and add HTTP to HTTPS redirect rule under the frontend hosts section.', link: 'https://learn.microsoft.com/en-us/azure/frontdoor/front-door-how-to-redirect-https', apis: ['classicFrontDoors:list'], From adc4ca7d175483970d5262e51e882a8563a69ea3 Mon Sep 17 00:00:00 2001 From: mehakseedat63 <87388442+mehakseedat63@users.noreply.github.com> Date: Fri, 1 Dec 2023 03:06:31 +0500 Subject: [PATCH 7/8] Update plugins/azure/frontdoor/frontDoorHttpsOnly.js --- plugins/azure/frontdoor/frontDoorHttpsOnly.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/azure/frontdoor/frontDoorHttpsOnly.js b/plugins/azure/frontdoor/frontDoorHttpsOnly.js index e18d4b9743..e573dc4b9c 100644 --- a/plugins/azure/frontdoor/frontDoorHttpsOnly.js +++ b/plugins/azure/frontdoor/frontDoorHttpsOnly.js @@ -33,7 +33,7 @@ module.exports = { return rcb(); } - classicFrontDoors.data.forEach(function(frontDoor) { + classicFrontDoors.data.forEach(frontDoor => { if (!frontDoor.id || !frontDoor.routingRules) return; var ruleFound = false; From d4e2e047aea52dba6dc949862f40457e3183d603 Mon Sep 17 00:00:00 2001 From: mehakseedat63 <87388442+mehakseedat63@users.noreply.github.com> Date: Fri, 1 Dec 2023 03:06:37 +0500 Subject: [PATCH 8/8] Update plugins/azure/frontdoor/frontDoorHttpsOnly.js --- plugins/azure/frontdoor/frontDoorHttpsOnly.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/azure/frontdoor/frontDoorHttpsOnly.js b/plugins/azure/frontdoor/frontDoorHttpsOnly.js index e573dc4b9c..8a1739a387 100644 --- a/plugins/azure/frontdoor/frontDoorHttpsOnly.js +++ b/plugins/azure/frontdoor/frontDoorHttpsOnly.js @@ -7,7 +7,7 @@ module.exports = { domain: 'Content Delivery', description: 'Ensures HTTPS Only is enabled for Front Door classic profile, redirecting all HTTP traffic to HTTPS.', more_info: 'By using the HTTPS only protocol, you ensure that your sensitive data is delivered securely via TLS/SSL encryption.', - recommended_action: 'Modify the Front Door classic profile and add HTTP to HTTPS redirect rule under the frontend hosts section.', + recommended_action: 'Modify the Front Door classic profile and add HTTP to HTTPS redirect rule under the frontend hosts section.', link: 'https://learn.microsoft.com/en-us/azure/frontdoor/front-door-how-to-redirect-https', apis: ['classicFrontDoors:list'],