Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,7 @@ module.exports = {
'docdbClusterBackupRetention' : require(__dirname + '/plugins/aws/documentDB/docdbClusterBackupRetention.js'),
'docdbCertificateRotated' : require(__dirname + '/plugins/aws/documentDB/docdbCertificateRotated.js'),
'docdbClusterProfilerEnabled' : require(__dirname + '/plugins/aws/documentDB/docdbClusterProfilerEnabled.js'),
'docdbEncryptionInTransit' : require(__dirname + '/plugins/aws/documentDB/docdbEncryptionInTransit.js'),
'docdbAuditLoggingEnabled' : require(__dirname + '/plugins/aws/documentDB/docdbAuditLoggingEnabled.js'),

'instanceMediaStreamsEncrypted' : require(__dirname + '/plugins/aws/connect/instanceMediaStreamsEncrypted.js'),
Expand Down
6 changes: 6 additions & 0 deletions helpers/aws/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -2293,6 +2293,12 @@ var postcalls = [
filterKey: 'ResourceName',
filterValue: 'DBClusterArn'
},
describeDBClusterParameters: {
reliesOnService: 'docdb',
reliesOnCall: 'describeDBClusters',
filterKey: 'DBClusterParameterGroupName',
filterValue: 'DBClusterParameterGroup'
},
sendIntegration: serviceMap['DocumentDB']
},
DynamoDB: {
Expand Down
6 changes: 6 additions & 0 deletions helpers/aws/api_multipart.js
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,12 @@ var postcalls = [
filterKey: 'ResourceName',
filterValue: 'DBClusterArn'
},
describeDBClusterParameters: {
reliesOnService: 'docdb',
reliesOnCall: 'describeDBClusters',
filterKey: 'DBClusterParameterGroupName',
filterValue: 'DBClusterParameterGroup'
},
},
DynamoDB: {
describeTable: {
Expand Down
99 changes: 99 additions & 0 deletions plugins/aws/documentDB/docdbEncryptionInTransit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
var async = require('async');
var helpers = require('../../../helpers/aws');

module.exports = {
title: 'DocumentDB Encryption In Transit',
category: 'DocumentDB',
domain: 'Databases',
severity: 'High',
description: 'Ensure that DocumentDB clusters have TLS/SSL encryption in transit enabled.',
more_info: 'DocumentDB uses TLS/SSL to encrypt data during transit. The TLS parameter in the cluster parameter group should be set to enabled to require encrypted connections. This ensures that all data transmitted between clients and the DocumentDB cluster is encrypted.',
recommended_action: 'Modify the cluster parameter group to set the tls parameter to enabled, or create a custom parameter group with TLS enabled and associate it with the cluster.',
link: 'https://docs.aws.amazon.com/documentdb/latest/developerguide/security.encryption.ssl.html',
apis: ['DocDB:describeDBClusters', 'DocDB:describeDBClusterParameters'],
realtime_triggers: [ 'docdb:CreateDBCluster', 'docdb:ModifyDBCluster', 'docdb:ModifyDBClusterParameterGroup', 'docdb:CreateDBClusterParameterGroup','docdb:DeleteDBCluster' ],

run: function(cache, settings, callback) {
var results = [];
var source = {};
var regions = helpers.regions(settings);

async.each(regions.docdb, function(region, rcb){
var describeDBClusters = helpers.addSource(cache, source,
['docdb', 'describeDBClusters', region]);

if (!describeDBClusters) return rcb();

if (describeDBClusters.err || !describeDBClusters.data) {
helpers.addResult(results, 3,
`Unable to list DocumentDB clusters: ${helpers.addError(describeDBClusters)}`, region);
return rcb();
}

if (!describeDBClusters.data.length) {
helpers.addResult(results, 0,
'No DocumentDB clusters found', region);
return rcb();
}

async.each(describeDBClusters.data, function(cluster, ccb){
if (!cluster.DBClusterArn || !cluster.DBClusterIdentifier) return ccb();

var resource = cluster.DBClusterArn;
var tlsEnabled = false;

if (!cluster.DBClusterParameterGroup) {
helpers.addResult(results, 2,
'DocumentDB cluster does not have a parameter group associated',
region, resource);
return ccb();
}

var parameterGroupName = cluster.DBClusterParameterGroup;


var parameters = helpers.addSource(cache, source,
['docdb', 'describeDBClusterParameters', region, parameterGroupName]);

if (!parameters || parameters.err || !parameters.data) {
helpers.addResult(results, 3,
`Unable to query cluster parameters: ${helpers.addError(parameters)}`,
region, resource);
return ccb();
}

if (!parameters.data.Parameters) {
helpers.addResult(results, 2,
'DocumentDB cluster does not have TLS encryption in transit enabled',
region, resource);
return ccb();
}

for (var param of parameters.data.Parameters) {
if (param.ParameterName && param.ParameterName === 'tls' &&
param.ParameterValue &&
(param.ParameterValue.toLowerCase() === 'enabled' || param.ParameterValue === '1')) {
tlsEnabled = true;
break;
}
}

if (tlsEnabled) {
helpers.addResult(results, 0,
'DocumentDB cluster has TLS encryption in transit enabled',
region, resource);
} else {
helpers.addResult(results, 2,
'DocumentDB cluster does not have TLS encryption in transit enabled',
region, resource);
}

ccb();
}, function(){
rcb();
});
}, function(){
callback(null, results, source);
});
}
};
233 changes: 233 additions & 0 deletions plugins/aws/documentDB/docdbEncryptionInTransit.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
var expect = require('chai').expect;
var docdbEncryptionInTransit = require('./docdbEncryptionInTransit');

const describeDBClusters = [
{
AvailabilityZones: [],
BackupRetentionPeriod: 7,
DBClusterArn: 'arn:aws:rds:us-east-1:000011112222:cluster:docdb-2021-11-10-10-16-10',
DBClusterIdentifier: 'docdb-2021-11-10-10-16-10',
DBClusterParameterGroup: 'custom-docdb-param-group',
DBSubnetGroup: 'default-vpc-99de2fe4',
Status: 'available',
Engine: 'docdb',
EngineVersion: '4.0.0'
},
{
AvailabilityZones: [],
BackupRetentionPeriod: 7,
DBClusterArn: 'arn:aws:rds:us-east-1:000011112223:cluster:docdb-2021-11-10-10-16-11',
DBClusterIdentifier: 'docdb-2021-11-10-10-16-11',
DBClusterParameterGroup: 'custom-docdb-param-group-disabled',
DBSubnetGroup: 'default-vpc-99de2fe4',
Status: 'available',
Engine: 'docdb',
EngineVersion: '4.0.0'
},
{
AvailabilityZones: [],
BackupRetentionPeriod: 7,
DBClusterArn: 'arn:aws:rds:us-east-1:000011112224:cluster:docdb-2021-11-10-10-16-12',
DBClusterIdentifier: 'docdb-2021-11-10-10-16-12',
DBClusterParameterGroup: 'default.docdb4.0',
DBSubnetGroup: 'default-vpc-99de2fe4',
Status: 'available',
Engine: 'docdb',
EngineVersion: '4.0.0'
},
{
AvailabilityZones: [],
BackupRetentionPeriod: 7,
DBClusterArn: 'arn:aws:rds:us-east-1:000011112225:cluster:docdb-2021-11-10-10-16-13',
DBClusterIdentifier: 'docdb-2021-11-10-10-16-13',
DBSubnetGroup: 'default-vpc-99de2fe4',
Status: 'available',
Engine: 'docdb',
EngineVersion: '4.0.0'
}
];

const clusterParameters = {
'custom-docdb-param-group': {
Parameters: [
{
ParameterName: 'tls',
ParameterValue: 'enabled',
Description: 'Enable TLS encryption',
Source: 'user',
ApplyType: 'static',
DataType: 'string',
AllowedValues: 'enabled,disabled',
IsModifiable: true
}
]
},
'custom-docdb-param-group-disabled': {
Parameters: [
{
ParameterName: 'tls',
ParameterValue: 'disabled',
Description: 'Enable TLS encryption',
Source: 'user',
ApplyType: 'static',
DataType: 'string',
AllowedValues: 'enabled,disabled',
IsModifiable: true
}
]
}
};

const createCache = (clusters, clustersErr, parameters, parametersErr) => {
var cache = {
docdb: {
describeDBClusters: {
'us-east-1': {
err: clustersErr,
data: clusters
},
},
}
};

if (parameters) {
cache.docdb = cache.docdb || {};
cache.docdb.describeDBClusterParameters = {
'us-east-1': {}
};
for (var groupName in parameters) {
cache.docdb.describeDBClusterParameters['us-east-1'][groupName] = {
err: parametersErr,
data: parameters[groupName]
};
}
}

return cache;
};

describe('docdbEncryptionInTransit', function () {
describe('run', function () {
it('should PASS if DocumentDB cluster has TLS enabled in custom parameter group', function (done) {
const cache = createCache([describeDBClusters[0]], null, clusterParameters);
docdbEncryptionInTransit.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('has TLS encryption in transit enabled');
expect(results[0].region).to.equal('us-east-1');
done();
});
});

it('should FAIL if DocumentDB cluster has TLS disabled in parameter group', function (done) {
const cache = createCache([describeDBClusters[1]], null, clusterParameters);
docdbEncryptionInTransit.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(2);
expect(results[0].message).to.include('does not have TLS encryption in transit enabled');
expect(results[0].region).to.equal('us-east-1');
done();
});
});

it('should FAIL if DocumentDB cluster uses default parameter group', function (done) {
const cache = createCache([describeDBClusters[2]], null, {
'default.docdb4.0': {
Parameters: [
{
ParameterName: 'tls',
ParameterValue: 'disabled',
Description: 'Enable TLS encryption',
Source: 'system',
ApplyType: 'static',
DataType: 'string',
AllowedValues: 'enabled,disabled',
IsModifiable: false
}
]
}
});
docdbEncryptionInTransit.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(2);
expect(results[0].message).to.include('does not have TLS encryption in transit enabled');
expect(results[0].region).to.equal('us-east-1');
done();
});
});

it('should FAIL if DocumentDB cluster has no parameter group', function (done) {
const cache = createCache([describeDBClusters[3]], null);
docdbEncryptionInTransit.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(2);
expect(results[0].message).to.include('does not have a parameter group associated');
expect(results[0].region).to.equal('us-east-1');
done();
});
});

it('should PASS if no DocumentDB clusters found', function (done) {
const cache = createCache([]);
docdbEncryptionInTransit.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('No DocumentDB clusters found');
expect(results[0].region).to.equal('us-east-1');
done();
});
});

it('should UNKNOWN if unable to list DocumentDB clusters', function (done) {
const cache = createCache(null, { message: "Unable to list DocumentDB Clusters" });
docdbEncryptionInTransit.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 list DocumentDB clusters:');
expect(results[0].region).to.equal('us-east-1');
done();
});
});

it('should UNKNOWN if unable to query cluster parameters', function (done) {
const cache = createCache([describeDBClusters[0]], null, null, { message: "Unable to query parameters" });
docdbEncryptionInTransit.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 cluster parameters');
expect(results[0].region).to.equal('us-east-1');
done();
});
});

it('should FAIL if cluster parameters data is null', function (done) {
const cache = createCache([describeDBClusters[0]], null, {
'custom-docdb-param-group': {
Parameters: null
}
});
docdbEncryptionInTransit.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(2);
expect(results[0].message).to.include('does not have TLS encryption in transit enabled');
expect(results[0].region).to.equal('us-east-1');
done();
});
});

it('should FAIL if cluster parameters array is empty', function (done) {
const cache = createCache([describeDBClusters[0]], null, {
'custom-docdb-param-group': {
Parameters: []
}
});
docdbEncryptionInTransit.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(2);
expect(results[0].message).to.include('does not have TLS encryption in transit enabled');
expect(results[0].region).to.equal('us-east-1');
done();
});
});
});
});