forked from aquasecurity/cloudsploit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request aquasecurity#1204 from sadeed12345/SAAS-4768
SAAS-4768: Added MSK Cluster Client Broker Encryption Plugin
- Loading branch information
Showing
3 changed files
with
181 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
var async = require('async'); | ||
var helpers = require('../../../helpers/aws'); | ||
|
||
module.exports = { | ||
title: 'MSK Cluster Client Broker Encryption', | ||
category: 'MSK', | ||
domain: 'Compute', | ||
severity: 'LOW', | ||
description: 'Ensure that only TLS encryption between the client and broker feature is enabled for your Amazon MSK clusters.', | ||
more_info: 'Amazon MSK in-transit encryption is an optional feature which encrypts data in transit between the client and brokers. Select the Transport Layer Security (TLS) protocol to encrypt data as it travels between brokers and clients within the cluster.', | ||
link: 'https://docs.aws.amazon.com/msk/latest/developerguide/msk-encryption.html', | ||
recommended_action: 'Enable only TLS encryption between the client and broker for all MSK clusters', | ||
apis: ['Kafka:listClusters'], | ||
|
||
run: function(cache, settings, callback) { | ||
var results = []; | ||
var source = {}; | ||
var regions = helpers.regions(settings); | ||
|
||
async.each(regions.kafka, function(region, rcb){ | ||
var listClusters = helpers.addSource(cache, source, | ||
['kafka', 'listClusters', region]); | ||
|
||
if (!listClusters) return rcb(); | ||
|
||
if (listClusters.err || !listClusters.data) { | ||
helpers.addResult(results, 3, | ||
'Unable to query for MSK clusters: ' + helpers.addError(listClusters), region); | ||
return rcb(); | ||
} | ||
|
||
if (!listClusters.data.length) { | ||
helpers.addResult(results, 0, 'No MSK clusters found', region); | ||
return rcb(); | ||
} | ||
|
||
for (var cluster of listClusters.data) { | ||
if (!cluster.ClusterArn) continue; | ||
|
||
var resource = cluster.ClusterArn; | ||
|
||
if (cluster.EncryptionInfo && | ||
cluster.EncryptionInfo.EncryptionInTransit && | ||
cluster.EncryptionInfo.EncryptionInTransit.ClientBroker && | ||
cluster.EncryptionInfo.EncryptionInTransit.ClientBroker.toUpperCase() === 'TLS') { | ||
helpers.addResult(results, 0, | ||
'Encryption between the client and broker is only TLS encrypted', region, resource); | ||
} else { | ||
helpers.addResult(results, 2, | ||
'Encryption between the client and broker is not only TLS encrypted', region, resource); | ||
} | ||
} | ||
|
||
rcb(); | ||
}, function(){ | ||
callback(null, results, source); | ||
}); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
var expect = require('chai').expect; | ||
const mskClusterCBEncryption = require('./mskClusterCBEncryption'); | ||
|
||
const listClusters = [ | ||
{ | ||
"ClusterArn": "arn:aws:kafka:us-east-1:000011112222:cluster/sadeedcluster/b08122a8-7104-476a-b6ee-c59444fb04d5-25", | ||
"ClusterName": "sadeedcluster", | ||
"CreationTime": "2022-04-06T14:19:41.573000+00:00", | ||
"CurrentBrokerSoftwareInfo": { | ||
"KafkaVersion": "2.6.2" | ||
}, | ||
"CurrentVersion": "K3R76HOPU0Z2CB", | ||
"EncryptionInfo": { | ||
"EncryptionAtRest": { | ||
"DataVolumeKMSKeyId": "arn:aws:kms:us-east-1:000011112222:key/39009d78-b364-4a0b-937f-c89a2c2b473f" | ||
}, | ||
"EncryptionInTransit": { | ||
"ClientBroker": "TLS", | ||
"InCluster": true | ||
} | ||
}, | ||
}, | ||
{ | ||
"ClusterArn": "arn:aws:kafka:us-east-1:000011112222:cluster/sadeedcluster/b08122a8-7104-476a-b6ee-c59444fb04d5-25", | ||
"ClusterName": "sadeedcluster", | ||
"CreationTime": "2022-04-06T14:19:41.573000+00:00", | ||
"CurrentBrokerSoftwareInfo": { | ||
"KafkaVersion": "2.6.2" | ||
}, | ||
"CurrentVersion": "K3R76HOPU0Z2CB", | ||
"EncryptionInfo": { | ||
"EncryptionAtRest": { | ||
"DataVolumeKMSKeyId": "arn:aws:kms:us-east-1:000011112222:key/39009d78-b364-4a0b-937f-c89a2c2b473f" | ||
}, | ||
"EncryptionInTransit": { | ||
"ClientBroker": "TLS_PLAINTEXT", | ||
"InCluster": true | ||
} | ||
}, | ||
} | ||
]; | ||
|
||
const createCache = (clusters) => { | ||
return { | ||
kafka: { | ||
listClusters: { | ||
'us-east-1': { | ||
data: clusters, | ||
}, | ||
}, | ||
}, | ||
}; | ||
}; | ||
|
||
const createErrorCache = () => { | ||
return { | ||
kafka: { | ||
listClusters: { | ||
'us-east-1': { | ||
err: { | ||
message: 'error listing clusters' | ||
}, | ||
}, | ||
}, | ||
}, | ||
}; | ||
}; | ||
|
||
|
||
describe('mskClusterCBEncryption', function () { | ||
describe('run', function () { | ||
it('should FAIL if Encryption between the client and broker is not only TLS encrypted', function (done) { | ||
const cache = createCache([listClusters[1]]); | ||
mskClusterCBEncryption.run(cache, {}, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(2); | ||
expect(results[0].message).to.include('Encryption between the client and broker is not only TLS encrypted'); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should PASS if Encryption between the client and broker is only TLS encrypted', function (done) { | ||
const cache = createCache([listClusters[0]]); | ||
mskClusterCBEncryption.run(cache, {}, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(0); | ||
expect(results[0].message).to.include('Encryption between the client and broker is only TLS encrypted'); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should PASS if no MSK clusters found', function (done) { | ||
const cache = createCache([]); | ||
mskClusterCBEncryption.run(cache, {}, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(0); | ||
expect(results[0].message).to.include('No MSK clusters found'); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should UNKNOWN if Unable to query for MSK clusters', function (done) { | ||
const cache = createCache(null); | ||
mskClusterCBEncryption.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 MSK clusters'); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should not return any results if there was an error querying for MSK clusters', function (done) { | ||
const cache = createErrorCache(); | ||
mskClusterCBEncryption.run(cache, {}, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |