diff --git a/exports.js b/exports.js index 261e4485ff..b057118818 100644 --- a/exports.js +++ b/exports.js @@ -534,6 +534,8 @@ module.exports = { 'neptuneDBMultiAz' : require(__dirname + '/plugins/aws/neptune/neptuneDBMultiAz.js'), 'neptuneDbDeletionProtection' : require(__dirname + '/plugins/aws/neptune/neptuneDbDeletionProtection.js'), 'neptuneDBIamAuth' : require(__dirname + '/plugins/aws/neptune/neptuneDBIamAuth.js'), + 'neptuneAuditLoggingEnabled' : require(__dirname + '/plugins/aws/neptune/neptuneAuditLoggingEnabled.js'), + 'monitoringMetrics' : require(__dirname + '/plugins/aws/cloudwatchlogs/monitoringMetrics.js'), diff --git a/plugins/aws/neptune/neptuneAuditLoggingEnabled.js b/plugins/aws/neptune/neptuneAuditLoggingEnabled.js new file mode 100644 index 0000000000..395ea0c225 --- /dev/null +++ b/plugins/aws/neptune/neptuneAuditLoggingEnabled.js @@ -0,0 +1,53 @@ +var async = require('async'); +var helpers = require('../../../helpers/aws'); + +module.exports = { + title: 'Neptune Audit Logging Enabled', + category: 'Neptune', + domain: 'Databases', + severity: 'Medium', + description: 'Ensure that Amazon Neptune database clusters have audit logging enabled.', + more_info: 'Neptune audit logging records database access and management activities and delivers the logs to AWS CloudTrail. This helps in security monitoring, compliance auditing, and forensic analysis.', + recommended_action: 'Modify the Neptune DB cluster and enable audit logging.', + link: 'https://docs.aws.amazon.com/neptune/latest/userguide/security-logging.html', + apis: ['Neptune:describeDBClusters'], + realtime_triggers: ['neptune:CreateDBCluster','neptune:ModifyDBCluster'], + + run: function(cache, settings, callback) { + var results = []; + var source = {}; + var regions = helpers.regions(settings); + + async.each(regions.neptune, function(region, rcb) { + var describeDBClusters = helpers.addSource(cache,source, + ['neptune', 'describeDBClusters', region]); + + if (!describeDBClusters) return rcb(); + + if (describeDBClusters.err || !describeDBClusters.data) { + helpers.addResult(results,3, + `Unable to list Neptune database clusters: ${helpers.addError(describeDBClusters)}`,region); + return rcb(); + } + + if (!describeDBClusters.data.length) { + helpers.addResult(results,0, + 'No Neptune database clusters found',region); + return rcb(); + } + + for (let cluster of describeDBClusters.data) { + if (!cluster.DBClusterArn || cluster.Engine !== 'neptune') continue; + if (cluster.EnableAuditLog) { + helpers.addResult(results,0,'Neptune audit logging is enabled',region,cluster.DBClusterArn); + } else { + helpers.addResult(results,2,'Neptune audit logging is disabled',region,cluster.DBClusterArn); + } + } + + rcb(); + }, function() { + callback(null, results, source); + }); + } +}; diff --git a/plugins/aws/neptune/neptuneAuditLoggingEnabled.spec.js b/plugins/aws/neptune/neptuneAuditLoggingEnabled.spec.js new file mode 100644 index 0000000000..4c71e7a5d0 --- /dev/null +++ b/plugins/aws/neptune/neptuneAuditLoggingEnabled.spec.js @@ -0,0 +1,86 @@ +var expect = require('chai').expect; +var neptuneAuditLogging = require('./neptuneAuditLoggingEnabled'); + + +const describeDBClusters = [ + { + "AllocatedStorage": 1, + "BackupRetentionPeriod": 1, + "DbClusterResourceId": "cluster-AUDIT1", + "DBClusterArn": "arn:aws:rds:us-east-1:000111222333:cluster:database-2", + "AssociatedRoles": [], + "Engine": "neptune", + "EnableAuditLog": true + }, + { + "AllocatedStorage": 1, + "BackupRetentionPeriod": 1, + "DbClusterResourceId": "cluster-AUDIT2", + "DBClusterArn": "arn:aws:rds:us-east-1:000111222334:cluster:database-3", + "AssociatedRoles": [], + "Engine": "neptune", + "EnableAuditLog": false + } +]; + +const createCache = (clusters, clustersErr) => { + return { + neptune: { + describeDBClusters: { + 'us-east-1': { + err: clustersErr, + data: clusters + }, + }, + }, + }; +}; + +describe('neptuneAuditLogging', function () { + describe('run', function () { + + it('should PASS if Neptune DB cluster has audit logging enabled', function (done) { + const cache = createCache([describeDBClusters[0]]); + neptuneAuditLogging.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].message).to.include('Neptune audit logging is enabled'); + expect(results[0].region).to.include('us-east-1'); + done(); + }); + }); + + it('should FAIL if Neptune DB cluster does not have audit logging enabled', function (done) { + const cache = createCache([describeDBClusters[1]]); + neptuneAuditLogging.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].message).to.include('Neptune audit logging is disabled'); + expect(results[0].region).to.include('us-east-1'); + done(); + }); + }); + + it('should PASS if no Neptune DB clusters found', function (done) { + const cache = createCache([]); + neptuneAuditLogging.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].message).to.include('No Neptune database clusters found'); + expect(results[0].region).to.include('us-east-1'); + done(); + }); + }); + + it('should UNKNOWN if unable to list Neptune DB clusters', function (done) { + const cache = createCache(null, { message: "Unable to list Neptune database clusters" }); + neptuneAuditLogging.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(3); + expect(results[0].region).to.include('us-east-1'); + done(); + }); + }); + + }); +});