From 6c2672988a5d36491588ca26f00d8860c4527b7d Mon Sep 17 00:00:00 2001 From: AkhtarAmir Date: Tue, 16 Feb 2021 12:10:17 +0500 Subject: [PATCH] Added Google 'Open Redis' plugin --- exports.js | 1 + plugins/google/vpcnetwork/openRedis.js | 47 +++++++++ plugins/google/vpcnetwork/openRedis.spec.js | 109 ++++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 plugins/google/vpcnetwork/openRedis.js create mode 100644 plugins/google/vpcnetwork/openRedis.spec.js diff --git a/exports.js b/exports.js index 364e127dda..02e2bfe65e 100644 --- a/exports.js +++ b/exports.js @@ -584,6 +584,7 @@ module.exports = { 'openOracle' : require(__dirname + '/plugins/google/vpcnetwork/openOracle.js'), 'openPostgreSQL' : require(__dirname + '/plugins/google/vpcnetwork/openPostgreSQL.js'), 'openRDP' : require(__dirname + '/plugins/google/vpcnetwork/openRDP.js'), + 'openRedis' : require(__dirname + '/plugins/google/vpcnetwork/openRedis.js'), 'openRPC' : require(__dirname + '/plugins/google/vpcnetwork/openRPC.js'), 'openSalt' : require(__dirname + '/plugins/google/vpcnetwork/openSalt.js'), 'openSMBoTCP' : require(__dirname + '/plugins/google/vpcnetwork/openSMBoTCP.js'), diff --git a/plugins/google/vpcnetwork/openRedis.js b/plugins/google/vpcnetwork/openRedis.js new file mode 100644 index 0000000000..71cb9672c0 --- /dev/null +++ b/plugins/google/vpcnetwork/openRedis.js @@ -0,0 +1,47 @@ +var async = require('async'); +var helpers = require('../../../helpers/google'); + +module.exports = { + title: 'Open Redis', + category: 'VPC Network', + description: 'Determines if TCP port 6379 for Redis is open to the public', + more_info: 'While some ports such as HTTP and HTTPS are required to be open to the public to function properly, more sensitive services such as Redis should be restricted to known IP addresses.', + link: 'https://cloud.google.com/vpc/docs/using-firewalls', + recommended_action: 'Restrict TCP port 6379 to known IP addresses.', + apis: ['firewalls:list'], + + run: function(cache, settings, callback) { + var results = []; + var source = {}; + var regions = helpers.regions(); + + async.each(regions.firewalls, function(region, rcb){ + let firewalls = helpers.addSource( + cache, source, ['firewalls', 'list', region]); + + if (!firewalls) return rcb(); + + if (firewalls.err || !firewalls.data) { + helpers.addResult(results, 3, 'Unable to query firewall rules: ' + helpers.addError(firewalls), region); + return rcb(); + } + + if (!firewalls.data.length) { + helpers.addResult(results, 0, 'No firewall rules found', region); + return rcb(); + } + + let ports = { + 'tcp': [6379] + }; + + let service = 'Redis'; + + helpers.findOpenPorts(firewalls.data, ports, service, region, results); + + rcb(); + }, function(){ + callback(null, results, source); + }); + } +} \ No newline at end of file diff --git a/plugins/google/vpcnetwork/openRedis.spec.js b/plugins/google/vpcnetwork/openRedis.spec.js new file mode 100644 index 0000000000..1f92dc3efd --- /dev/null +++ b/plugins/google/vpcnetwork/openRedis.spec.js @@ -0,0 +1,109 @@ +var expect = require('chai').expect; +const openRedis = require('./openRedis'); + +const firewalls = [ + { + "id": "4111718641158512144", + "creationTimestamp": "2021-02-25T00:34:07.519-08:00", + "name": "openall", + "description": "Open All Ports", + "network": "https://www.googleapis.com/compute/v1/projects/aqua-dev-akhtar/global/networks/app-vpc", + "priority": 1000, + "sourceRanges": [ "0.0.0.0/0" ], + "allowed": [{ "IPProtocol": "tcp", "ports": [ "6379" ]}], + "direction": "INGRESS", + "disabled": false, + "selfLink": "https://www.googleapis.com/compute/v1/projects/aqua-dev-akhtar/global/firewalls/openall", + "kind": "compute#firewall" + }, + { + "id": "3482752052453535354", + "creationTimestamp": "2021-02-25T00:34:07.519-08:00", + "name": "opensome", + "description": "", + "network": "https://www.googleapis.com/compute/v1/projects/aqua-dev-akhtar/global/networks/app-vpc", + "priority": 1000, + "sourceRanges": [ "192.168.0.0/16" ], + "allowed": [{ "IPProtocol": "tcp", "ports": [ "22" ]}], + "direction": "INGRESS", + "disabled": false, + "selfLink": "https://www.googleapis.com/compute/v1/projects/aqua-dev-akhtar/global/firewalls/opensome", + "kind": "compute#firewall" + } +]; + +const createCache = (groups, err) => { + return { + firewalls:{ + list: { + 'global': { + data: groups, + err: err + }, + }, + }, + }; +}; + +const createNullCache = () => { + return { + firewalls:{ + list: { + 'global': null, + }, + }, + }; +}; + +describe('openRedis', function () { + describe('run', function () { + it('should PASS if no open ports found', function (done) { + const cache = createCache([firewalls[1]]); + openRedis.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should FAIL if firewall rule has TCP port 6379 for Redis is open to public', function (done) { + const cache = createCache([firewalls[0]]); + openRedis.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should PASS if no firewall rules found', function (done) { + const cache = createCache([]); + openRedis.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should UNKNWON if unable to describe firewall rules', function (done) { + const cache = createCache([], { message: 'Unable to query firewall rules'}); + openRedis.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(3); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should not return anything if describe firewall rules response not found', function (done) { + const cache = createNullCache(); + openRedis.run(cache, {}, (err, results) => { + expect(results.length).to.equal(0); + done(); + }); + }); + + }); +});