From cb73ff7fd7860870b0e8dbe4b19e110b423e759c Mon Sep 17 00:00:00 2001 From: AkhtarAmir <31914988+AkhtarAmir@users.noreply.github.com> Date: Mon, 11 Nov 2024 16:45:40 +0500 Subject: [PATCH] Revised unAttachedDiskByokEncryptionEnabled (#2104) * Revised unAttachedDiskByokEncryptionEnabled * Apply suggestions from code review suggested changes Co-authored-by: Fatima <66124862+fatima99s@users.noreply.github.com> * Update unAttachedDiskByokEncryptionEnabled.js * Update unAttachedDiskByokEncryptionEnabled.js * Update unAttachedDiskByokEncryptionEnabled.js * Apply suggestions from code review --------- Co-authored-by: AkhtarAmir Co-authored-by: Fatima <66124862+fatima99s@users.noreply.github.com> Co-authored-by: alphadev4 <113519745+alphadev4@users.noreply.github.com> --- exports.js | 1 + .../unAttachedDiskByokEncryptionEnabled.js | 53 +++++++++++ ...nAttachedDiskByokEncryptionEnabled.spec.js | 88 +++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 plugins/azure/virtualmachines/unAttachedDiskByokEncryptionEnabled.js create mode 100644 plugins/azure/virtualmachines/unAttachedDiskByokEncryptionEnabled.spec.js diff --git a/exports.js b/exports.js index 8acd341e9e..ec1b8c3306 100644 --- a/exports.js +++ b/exports.js @@ -804,6 +804,7 @@ module.exports = { 'vmDiskHasTags' : require(__dirname + '/plugins/azure/virtualmachines/vmDiskHasTags.js'), 'snapshotHasTags' : require(__dirname + '/plugins/azure/virtualmachines/snapshotHasTags.js'), 'unattachedDiskWithDefaultEncryption': require(__dirname + '/plugins/azure/virtualmachines/unattachedDiskWithDefaultEncryption.js'), + 'unAttachedDiskByokEncryptionEnabled': require(__dirname + '/plugins/azure/virtualmachines/unAttachedDiskByokEncryptionEnabled.js'), 'snapshotPublicAccessDisabled' : require(__dirname + '/plugins/azure/virtualmachines/snapshotPublicAccessDisabled.js'), 'snapshotByokEncryptionEnabled' : require(__dirname + '/plugins/azure/virtualmachines/snapshotByokEncryptionEnabled.js'), 'systemAssignedIdentityEnabled' : require(__dirname + '/plugins/azure/virtualmachines/systemAssignedIdentityEnabled.js'), diff --git a/plugins/azure/virtualmachines/unAttachedDiskByokEncryptionEnabled.js b/plugins/azure/virtualmachines/unAttachedDiskByokEncryptionEnabled.js new file mode 100644 index 0000000000..ed2663b9fa --- /dev/null +++ b/plugins/azure/virtualmachines/unAttachedDiskByokEncryptionEnabled.js @@ -0,0 +1,53 @@ +var async = require('async'); + +var helpers = require('../../../helpers/azure'); + +module.exports = { + title: 'Unattached Disk Volumes BYOK Encryption Enabled', + category: 'Virtual Machines', + domain: 'Compute', + severity: 'Medium', + description: 'Ensures that unattached Azure virtual machine disks have BYOK (Customer-Managed Key) encryption enabled.', + more_info: 'Encrypting virtual machine disk volumes helps protect and safeguard your data to meet organizational security and compliance commitments. Having unattached disks with default encryption type can lead to data leakage.', + recommended_action: 'Delete remove unattached disks or enable BYOK encryption for them.', + link: 'https://learn.microsoft.com/en-us/azure/virtual-machines/windows/disk-encryption-key-vault', + apis: ['disks:list'], + realtime_triggers: ['microsoftcompute:disks:write', 'microsoftcompute:disks:delete'], + + run: function(cache, settings, callback) { + var results = []; + var source = {}; + var locations = helpers.locations(settings.govcloud); + + async.each(locations.disks, function(location, rcb) { + + var disks = helpers.addSource(cache, source, ['disks', 'list', location]); + + if (!disks) return rcb(); + + if (disks.err || !disks.data) { + helpers.addResult(results, 3, 'Unable to query for VM disk volumes: ' + helpers.addError(disks), location); + return rcb(); + } + if (!disks.data.length) { + helpers.addResult(results, 0, 'No existing VM disk volumes found', location); + return rcb(); + } + + for (let disk of disks.data) { + if (!disk.id) continue; + if (disk.diskState && disk.diskState.toLowerCase() === 'unattached') { + if (disk.encryption && disk.encryption.type && + disk.encryption.type === 'EncryptionAtRestWithPlatformKey') { + helpers.addResult(results, 2, 'Unattached disk volume has BYOK encryption disabled', location, disk.id); + } else { + helpers.addResult(results, 0, 'Unattached disk volume has BYOK encryption enabled', location, disk.id); + } + } + } + rcb(); + }, function() { + callback(null, results, source); + }); + } +}; diff --git a/plugins/azure/virtualmachines/unAttachedDiskByokEncryptionEnabled.spec.js b/plugins/azure/virtualmachines/unAttachedDiskByokEncryptionEnabled.spec.js new file mode 100644 index 0000000000..c6a55fea04 --- /dev/null +++ b/plugins/azure/virtualmachines/unAttachedDiskByokEncryptionEnabled.spec.js @@ -0,0 +1,88 @@ +var expect = require('chai').expect; +var diskUnattachedAndDefaultEncryption = require('./unattachedDiskWithDefaultEncryption'); + +const disks = [ + { + 'name': 'test', + 'id': '/subscriptions/123/resourceGroups/aqua-resource-group/providers/Microsoft.Compute/disks/test', + 'type': 'Microsoft.Compute/disks', + 'location': 'eastus', + 'encryption': { + 'type': 'EncryptionAtRestWithCustomerKey' + }, + 'diskState': 'Reserved' + }, + { + 'name': 'test', + 'id': '/subscriptions/123/resourceGroups/aqua-resource-group/providers/Microsoft.Compute/disks/test', + 'type': 'Microsoft.Compute/disks', + 'location': 'eastus', + 'encryption': { + 'type': 'EncryptionAtRestWithPlatformKey', + 'diskEncryptionSetId': '/subscriptions/123/resourceGroups/AQUA-RESOURCE-GROUP/providers/Microsoft.Compute/diskEncryptionSets/test-encrypt-set' + }, + 'diskState': 'unattached' + } +]; + +const createCache = (disks) => { + const disk = {}; + if (disks) { + disk['data'] = disks; + } + return { + disks: { + list: { + 'eastus': disk + } + } + }; +}; + +describe('diskUnattachedAndDefaultEncryption', function() { + describe('run', function() { + it('should give passing result if no disk volumes found', function(done) { + const cache = createCache([]); + diskUnattachedAndDefaultEncryption.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 VM disk volumes found'); + expect(results[0].region).to.equal('eastus'); + done(); + }); + }); + + it('should give unknown result if unable to query for disk volumes', function(done) { + const cache = createCache(); + diskUnattachedAndDefaultEncryption.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(3); + expect(results[0].message).to.include('Unable to query for VM disk volumes'); + expect(results[0].region).to.equal('eastus'); + done(); + }); + }); + + it('should give failing result if Disk volume is unattached and encrypted with default encryption key', function(done) { + const cache = createCache([disks[1]]); + diskUnattachedAndDefaultEncryption.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].message).to.include('Disk volume is unattached and encrypted with default encryption key'); + expect(results[0].region).to.equal('eastus'); + done(); + }); + }); + + it('should give passing result if Disk volume is attached or encrypted with BYO', function(done) { + const cache = createCache([disks[0]]); + diskUnattachedAndDefaultEncryption.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].message).to.include('Disk volume is attached or encrypted with BYOK'); + expect(results[0].region).to.equal('eastus'); + done(); + }); + }); + }); +}); \ No newline at end of file