diff --git a/exports.js b/exports.js index 53c1523d03..e8099e5e76 100644 --- a/exports.js +++ b/exports.js @@ -285,6 +285,8 @@ module.exports = { 'elbv2InsecureCiphers' : require(__dirname + '/plugins/aws/elbv2/elbv2InsecureCiphers.js'), 'elbv2TLSVersionCipherEnabled' : require(__dirname + '/plugins/aws/elbv2/elbv2TLSVersionCipherEnabled.js'), 'elbv2crosszoneLoadBalancing' : require(__dirname + '/plugins/aws/elbv2/elbv2crosszoneLoadBalancing.js'), + 'albSecurityGroup' : require(__dirname + '/plugins/aws/elbv2/albSecurityGroup'), + 'elasticacheDefaultPorts' : require(__dirname + '/plugins/aws/elasticache/elasticacheDefaultPorts.js'), 'emrClusterLogging' : require(__dirname + '/plugins/aws/emr/emrClusterLogging.js'), diff --git a/plugins/aws/elbv2/albSecurityGroup.js b/plugins/aws/elbv2/albSecurityGroup.js new file mode 100644 index 0000000000..095e2faf8d --- /dev/null +++ b/plugins/aws/elbv2/albSecurityGroup.js @@ -0,0 +1,55 @@ +var async = require('async'); +var helpers = require('../../../helpers/aws'); + +module.exports = { + title: 'ALB Security Group', + category: 'ELBv2', + domain: 'Content Delivery', + description: 'Ensures that Application Load Balancer has security group associated.', + more_info: 'It is a security best practice to always have application load balancers associated with security groups to avoid any data loss or unauthorized access.', + link: 'https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-update-security-groups.html', + recommended_action: 'Modify Application Load Balancer and add security group.', + apis: ['ELBv2:describeLoadBalancers'], + + run: function(cache, settings, callback) { + var results = []; + var source = {}; + var regions = helpers.regions(settings); + + async.each(regions.elbv2, function(region, rcb){ + var describeLoadBalancers = helpers.addSource(cache, source, + ['elbv2', 'describeLoadBalancers', region]); + + if (!describeLoadBalancers) return rcb(); + + if (describeLoadBalancers.err || !describeLoadBalancers.data) { + helpers.addResult(results, 3, + 'Unable to query for load balancers: ' + helpers.addError(describeLoadBalancers), + region); + return rcb(); + } + + if (!describeLoadBalancers.data.length) { + helpers.addResult(results, 0, 'No load balancers found', region); + return rcb(); + } + + for (let alb of describeLoadBalancers.data){ + + if (!alb.LoadBalancerArn || (!alb.Type || alb.Type.toLowerCase() !== 'application')) { + continue; + } + + if (alb.SecurityGroups && alb.SecurityGroups.length){ + helpers.addResult(results, 0, 'Application Load Balancer has security group associated', region, alb.LoadBalancerArn); + } else { + helpers.addResult(results, 2, 'Application Load Balancer does not have security group associated', region, alb.LoadBalancerArn); + } + } + + rcb(); + }, function(){ + callback(null, results, source); + }); + } +}; \ No newline at end of file diff --git a/plugins/aws/elbv2/albSecurityGroup.spec.js b/plugins/aws/elbv2/albSecurityGroup.spec.js new file mode 100644 index 0000000000..5d28005eda --- /dev/null +++ b/plugins/aws/elbv2/albSecurityGroup.spec.js @@ -0,0 +1,124 @@ +var expect = require('chai').expect; +const albSecurityGroup = require('./albSecurityGroup'); + +const loadBalancers = [ + { + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-east-1:111122223333:loadbalancer/app/test-lb-43/8e680c7bace394a7", + "DNSName": "test-lb-43-148538634.us-east-1.elb.amazonaws.com", + "CanonicalHostedZoneId": "Z35SXDOTRQ7X7K", + "CreatedTime": "2020-08-30T22:55:21.030Z", + "LoadBalancerName": "test-lb-43", + "Scheme": "internet-facing", + "VpcId": "vpc-99de2fe4", + "State": { + "Code": "active" + }, + "Type": "application", + "SecurityGroups": [ + "sg-06cccc47e5b3e1ee9" + ], + "IpAddressType": "ipv4" + }, + { + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-east-1:111122223333:loadbalancer/app/test-lb-43/8e680c7bace394a8", + "DNSName": "test-lb-43-148538634.us-east-1.elb.amazonaws.com", + "CanonicalHostedZoneId": "Z35SXDOTRQ7X7K", + "CreatedTime": "2020-08-30T22:55:21.030Z", + "LoadBalancerName": "test-lb-43", + "Scheme": "internet-facing", + "VpcId": "vpc-99de2fe4", + "State": { + "Code": "active" + }, + "Type": "application", + "SecurityGroups": [], + "IpAddressType": "ipv4" + } +]; + + +const createCache = (elbv2) => { + return { + elbv2:{ + describeLoadBalancers: { + 'us-east-1': { + data: elbv2 + }, + }, + }, + }; +}; + +const createErrorCache = () => { + return { + elbv2: { + describeLoadBalancers: { + 'us-east-1': { + err: { + message: 'error describing load balancers' + }, + }, + }, + } + }; +}; + +const createNullCache = () => { + return { + elbv2: { + describeLoadBalancers: { + 'us-east-1': null, + }, + }, + }; +}; + +describe('albSecurityGroup', function () { + describe('run', function () { + it('should PASS if load balancer has security groups associated', function (done) { + const cache = createCache([loadBalancers[0]]); + albSecurityGroup.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('us-east-1'); + expect(results[0].message).include('Application Load Balancer has security group associated'); + done(); + }); + }); + + it('should FAIL if load balancer does not have security groups associated', function (done) { + const cache = createCache([loadBalancers[1]]); + albSecurityGroup.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].region).to.equal('us-east-1'); + expect(results[0].message).include('Application Load Balancer does not have security group associated'); + done(); + }); + }); + + it('should UNKNOWN if error while describing load balancers', function (done) { + const cache = createErrorCache(); + albSecurityGroup.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(3); + expect(results[0].region).to.equal('us-east-1'); + expect(results[0].message).include('Unable to query for load balancers:'); + done(); + }); + }); + + it('should PASS if no load balancer found', function (done) { + const cache = createCache([]); + albSecurityGroup.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('us-east-1'); + expect(results[0].message).include('No load balancers found'); + done(); + }); + }); + + + }); +});