Skip to content

Commit e114025

Browse files
authored
Merge branch 'master' into Azure/Public-access-plugins
2 parents 135bcda + 94ab539 commit e114025

File tree

62 files changed

+3287
-1233
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+3287
-1233
lines changed

Dockerfile

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,27 @@ FROM node:lts-alpine3.12
99
# You could also use this to specify a particular version number.
1010
ARG PACKAGENAME=cloudsploit
1111

12+
# Create a non-root user and group
13+
RUN addgroup -S cloudsploit && adduser -S cloudsploit -G cloudsploit
14+
1215
COPY . /var/scan/cloudsploit/
1316

17+
# Set the working directory to /var/scan
18+
WORKDIR /var/scan
19+
1420
# Install cloudsploit/scan into the container using npm from NPM
15-
RUN cd /var/scan \
16-
&& npm init --yes \
21+
RUN npm init --yes \
1722
&& npm install ${PACKAGENAME} \
18-
&& npm link /var/scan/cloudsploit
23+
&& npm link /var/scan/cloudsploit \
24+
&& chown -R cloudsploit:cloudsploit /var/scan
1925

2026
# Setup the container's path so that you can run cloudsploit directly
2127
# in case someone wants to customize it when running the container.
2228
ENV PATH "$PATH:/var/scan/node_modules/.bin"
2329

30+
# Switch to non-root user
31+
USER cloudsploit
32+
2433
# By default, run the scan. CMD allows consumers of the container to supply
2534
# command line arguments to the run command to control how this executes.
2635
# Thus, you can use the parameters that you would normally give to index.js

collectors/aws/accessanalyzer/listFindingsV2.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module.exports = function(AWSConfig, collection, retries, callback) {
1919
if (paginating && data.findings && data.findings.length &&
2020
collection.accessanalyzer.listFindingsV2[AWSConfig.region][analyzer.arn].data.findings &&
2121
collection.accessanalyzer.listFindingsV2[AWSConfig.region][analyzer.arn].data.findings.length) {
22-
collection.accessanalyzer.listFindingsV2[AWSConfig.region][analyzer.arn].data.findings = collection.accessanalyzer.listFindings[AWSConfig.region][analyzer.arn].data.findings.concat(data.findings);
22+
collection.accessanalyzer.listFindingsV2[AWSConfig.region][analyzer.arn].data.findings = collection.accessanalyzer.listFindingsV2[AWSConfig.region][analyzer.arn].data.findings.concat(data.findings);
2323
} else {
2424
collection.accessanalyzer.listFindingsV2[AWSConfig.region][analyzer.arn].data = data;
2525
}
@@ -46,4 +46,4 @@ module.exports = function(AWSConfig, collection, retries, callback) {
4646
}, function(){
4747
callback();
4848
});
49-
};
49+
};

collectors/aws/guardduty/getDetector.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ module.exports = function(AWSConfig, collection, retries, callback) {
1414
if (err) {
1515
collection.guardduty.getDetector[AWSConfig.region][detectorId].err = err;
1616
}
17-
if (data) collection.guardduty.getDetector[AWSConfig.region][detectorId].data = data;
17+
if (data) {
18+
data.id = detectorId;
19+
collection.guardduty.getDetector[AWSConfig.region][detectorId].data = data;
20+
}
1821
cb();
1922
});
2023
}, function(){

collectors/aws/ses/getIdentityDkimAttributes.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ module.exports = function(AWSConfig, collection, retries, callback) {
2727
if (err) {
2828
collection.ses.getIdentityDkimAttributes[AWSConfig.region].err = err;
2929
} else if (data && data.DkimAttributes) {
30-
allDkimAttributes = {
31-
...allDkimAttributes,
32-
...data.DkimAttributes
33-
};
30+
var processedIdentities = Object.keys(data.DkimAttributes).map((key) => ({
31+
identityName: key,
32+
...data.DkimAttributes[key],
33+
}));
34+
allDkimAttributes = allDkimAttributes.concat(processedIdentities);
3435
}
3536
processIdentityChunk(chunkIndex + 1);
3637
});
Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,59 @@
1+
const { BlobServiceClient, StorageSharedKeyCredential } = require('@azure/storage-blob');
12
var async = require('async');
23

34
module.exports = function(collection, reliesOn, callback) {
45
if (!reliesOn['storageAccounts.listKeys']) return callback();
56

6-
var azureStorage = require('azure-storage');
7-
87
if (!collection['blobService']['listContainersSegmented']) collection['blobService']['listContainersSegmented'] = {};
98
if (!collection['blobService']['getContainerAcl']) collection['blobService']['getContainerAcl'] = {};
109

11-
// Loop through regions and properties in reliesOn
12-
async.eachOfLimit(reliesOn['storageAccounts.listKeys'], 10,function(regionObj, region, cb) {
10+
async.eachOfLimit(reliesOn['storageAccounts.listKeys'], 10, function(regionObj, region, cb) {
1311
collection['blobService']['listContainersSegmented'][region] = {};
1412
collection['blobService']['getContainerAcl'][region] = {};
1513

1614
async.eachOfLimit(regionObj, 10, function(subObj, resourceId, sCb) {
1715
collection['blobService']['listContainersSegmented'][region][resourceId] = {};
1816

19-
if (subObj && subObj.data && subObj.data.keys && subObj.data.keys[0] && subObj.data.keys[0].value) {
20-
// Extract storage account name from resourceId
21-
var storageAccountName = resourceId.substring(resourceId.lastIndexOf('/') + 1);
22-
var storageService = new azureStorage['BlobService'](storageAccountName, subObj.data.keys[0].value);
23-
24-
storageService.listContainersSegmented(null, function(serviceErr, serviceResults) {
25-
if (serviceErr || !serviceResults) {
26-
collection['blobService']['listContainersSegmented'][region][resourceId].err = (serviceErr || 'No data returned');
27-
sCb();
28-
} else {
29-
collection['blobService']['listContainersSegmented'][region][resourceId].data = serviceResults.entries;
30-
31-
// Add ACLs
32-
async.eachLimit(serviceResults.entries, 10, function(entryObj, entryCb) {
33-
var entryId = `${resourceId}/blobService/${entryObj.name}`;
34-
collection['blobService']['getContainerAcl'][region][entryId] = {};
35-
36-
storageService.getContainerAcl(entryObj.name, function(getErr, getData) {
37-
if (getErr || !getData) {
38-
collection['blobService']['getContainerAcl'][region][entryId].err = (getErr || 'No data returned');
39-
} else {
40-
collection['blobService']['getContainerAcl'][region][entryId].data = getData;
41-
}
42-
entryCb();
43-
});
44-
}, function() {
45-
sCb();
46-
});
17+
const key = subObj && subObj.data && subObj.data.keys && subObj.data.keys[0] && subObj.data.keys[0].value? subObj.data.keys[0].value : null;
18+
if (!key) return sCb();
19+
20+
const storageAccountName = resourceId.substring(resourceId.lastIndexOf('/') + 1);
21+
const credential = new StorageSharedKeyCredential(storageAccountName, key);
22+
const blobServiceClient = new BlobServiceClient(
23+
`https://${storageAccountName}.blob.core.windows.net`,
24+
credential
25+
);
26+
27+
const containers = [];
28+
29+
(async() => {
30+
try {
31+
for await (const container of blobServiceClient.listContainers()) {
32+
containers.push(container);
4733
}
48-
});
49-
} else {
50-
sCb();
51-
}
52-
}, function() {
53-
cb();
54-
});
55-
}, function() {
56-
callback();
57-
});
34+
35+
collection['blobService']['listContainersSegmented'][region][resourceId].data = containers;
36+
37+
// Get ACLs for each container
38+
async.eachLimit(containers, 10, async(entryObj, entryCb) => {
39+
const entryId = `${resourceId}/blobService/${entryObj.name}`;
40+
collection['blobService']['getContainerAcl'][region][entryId] = {};
41+
42+
try {
43+
const containerClient = blobServiceClient.getContainerClient(entryObj.name);
44+
const aclResponse = await containerClient.getAccessPolicy();
45+
collection['blobService']['getContainerAcl'][region][entryId].data = aclResponse;
46+
} catch (getErr) {
47+
collection['blobService']['getContainerAcl'][region][entryId].err = getErr.message || getErr;
48+
}
49+
50+
entryCb();
51+
}, sCb);
52+
} catch (serviceErr) {
53+
collection['blobService']['listContainersSegmented'][region][resourceId].err = serviceErr.message || serviceErr;
54+
sCb();
55+
}
56+
})();
57+
}, cb);
58+
}, callback);
5859
};
Lines changed: 47 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,57 @@
1+
const { TableServiceClient, AzureNamedKeyCredential } = require('@azure/data-tables');
12
var async = require('async');
23

34
module.exports = function(collection, reliesOn, callback) {
45
if (!reliesOn['storageAccounts.listKeys']) return callback();
56

6-
var azureStorage = require('azure-storage');
7+
if (!collection['tableService']['listTablesSegmented']) collection['tableService']['listTablesSegmented'] = {};
8+
if (!collection['tableService']['getTableAcl']) collection['tableService']['getTableAcl'] = {};
79

8-
if (!collection['queueService']['listQueuesSegmented']) collection['queueService']['listQueuesSegmented'] = {};
9-
if (!collection['queueService']['getQueueAcl']) collection['queueService']['getQueueAcl'] = {};
10-
11-
// Loop through regions and properties in reliesOn
12-
async.eachOfLimit(reliesOn['storageAccounts.listKeys'], 10,function(regionObj, region, cb) {
13-
collection['queueService']['listQueuesSegmented'][region] = {};
14-
collection['queueService']['getQueueAcl'][region] = {};
10+
async.eachOfLimit(reliesOn['storageAccounts.listKeys'], 10, function(regionObj, region, cb) {
11+
collection['tableService']['listTablesSegmented'][region] = {};
12+
collection['tableService']['getTableAcl'][region] = {};
1513

1614
async.eachOfLimit(regionObj, 10, function(subObj, resourceId, sCb) {
17-
collection['queueService']['listQueuesSegmented'][region][resourceId] = {};
18-
19-
if (subObj && subObj.data && subObj.data.keys && subObj.data.keys[0] && subObj.data.keys[0].value) {
20-
// Extract storage account name from resourceId
21-
var storageAccountName = resourceId.substring(resourceId.lastIndexOf('/') + 1);
22-
var storageService = new azureStorage['QueueService'](storageAccountName, subObj.data.keys[0].value);
23-
24-
storageService.listQueuesSegmented(null, function(serviceErr, serviceResults) {
25-
if (serviceErr || !serviceResults) {
26-
collection['queueService']['listQueuesSegmented'][region][resourceId].err = (serviceErr || 'No data returned');
27-
sCb();
28-
} else {
29-
collection['queueService']['listQueuesSegmented'][region][resourceId].data = serviceResults.entries;
30-
31-
// Add ACLs
32-
async.eachLimit(serviceResults.entries, 10, function(entryObj, entryCb) {
33-
var entryId = `${resourceId}/queueService/${entryObj.name}`;
34-
collection['queueService']['getQueueAcl'][region][entryId] = {};
35-
36-
storageService.getQueueAcl(entryObj.name, function(getErr, getData) {
37-
if (getErr || !getData) {
38-
collection['queueService']['getQueueAcl'][region][entryId].err = (getErr || 'No data returned');
39-
} else {
40-
collection['queueService']['getQueueAcl'][region][entryId].data = getData;
41-
}
42-
entryCb();
43-
});
44-
}, function() {
45-
sCb();
46-
});
15+
collection['tableService']['listTablesSegmented'][region][resourceId] = {};
16+
17+
const key = subObj && subObj.data && subObj.data.keys && subObj.data.keys[0] && subObj.data.keys[0].value? subObj.data.keys[0].value:null;
18+
if (!key) return sCb();
19+
20+
const storageAccountName = resourceId.substring(resourceId.lastIndexOf('/') + 1);
21+
const credential = new AzureNamedKeyCredential(storageAccountName, key);
22+
const serviceClient = new TableServiceClient(
23+
`https://${storageAccountName}.table.core.windows.net`,
24+
credential
25+
);
26+
27+
const tables = [];
28+
29+
(async() => {
30+
try {
31+
for await (const table of serviceClient.listTables()) {
32+
tables.push(table.name);
4733
}
48-
});
49-
} else {
50-
sCb();
51-
}
52-
}, function() {
53-
cb();
54-
});
55-
}, function() {
56-
callback();
57-
});
34+
35+
collection['tableService']['listTablesSegmented'][region][resourceId].data = tables;
36+
37+
async.eachLimit(tables, 10, async(tableName, tableCb) => {
38+
const tableId = `${resourceId}/tableService/${tableName}`;
39+
collection['tableService']['getTableAcl'][region][tableId] = {};
40+
41+
try {
42+
const aclResponse = await serviceClient.getAccessPolicy(tableName);
43+
collection['tableService']['getTableAcl'][region][tableId].data = aclResponse;
44+
} catch (getErr) {
45+
collection['tableService']['getTableAcl'][region][tableId].err = getErr.message || getErr;
46+
}
47+
48+
tableCb();
49+
}, sCb);
50+
} catch (tableErr) {
51+
collection['tableService']['listTablesSegmented'][region][resourceId].err = tableErr.message || tableErr;
52+
sCb();
53+
}
54+
})();
55+
}, cb);
56+
}, callback);
5857
};
Lines changed: 41 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,57 @@
1+
const { TableServiceClient, AzureNamedKeyCredential } = require('@azure/data-tables');
12
var async = require('async');
23

34
module.exports = function(collection, reliesOn, callback) {
45
if (!reliesOn['storageAccounts.listKeys']) return callback();
56

6-
var azureStorage = require('azure-storage');
7-
87
if (!collection['tableService']['listTablesSegmented']) collection['tableService']['listTablesSegmented'] = {};
98
if (!collection['tableService']['getTableAcl']) collection['tableService']['getTableAcl'] = {};
109

11-
// Loop through regions and properties in reliesOn
12-
async.eachOfLimit(reliesOn['storageAccounts.listKeys'], 10,function(regionObj, region, cb) {
10+
async.eachOfLimit(reliesOn['storageAccounts.listKeys'], 10, function(regionObj, region, cb) {
1311
collection['tableService']['listTablesSegmented'][region] = {};
1412
collection['tableService']['getTableAcl'][region] = {};
1513

1614
async.eachOfLimit(regionObj, 10, function(subObj, resourceId, sCb) {
1715
collection['tableService']['listTablesSegmented'][region][resourceId] = {};
1816

19-
if (subObj && subObj.data && subObj.data.keys && subObj.data.keys[0] && subObj.data.keys[0].value) {
20-
// Extract storage account name from resourceId
21-
var storageAccountName = resourceId.substring(resourceId.lastIndexOf('/') + 1);
22-
var storageService = new azureStorage['TableService'](storageAccountName, subObj.data.keys[0].value);
23-
24-
storageService.listTablesSegmented(null, function(tableErr, tableResults) {
25-
if (tableErr || !tableResults) {
26-
collection['tableService']['listTablesSegmented'][region][resourceId].err = (tableErr || 'No data returned');
27-
sCb();
28-
} else {
29-
collection['tableService']['listTablesSegmented'][region][resourceId].data = tableResults.entries;
30-
31-
// Add table ACLs
32-
async.eachLimit(tableResults.entries, 10, function(tableName, tableCb){
33-
var tableId = `${resourceId}/tableService/${tableName}`;
34-
collection['tableService']['getTableAcl'][region][tableId] = {};
35-
36-
storageService.getTableAcl(tableName, function(getErr, getData){
37-
if (getErr || !getData) {
38-
collection['tableService']['getTableAcl'][region][tableId].err = (getErr || 'No data returned');
39-
} else {
40-
collection['tableService']['getTableAcl'][region][tableId].data = getData;
41-
}
42-
tableCb();
43-
});
44-
}, function(){
45-
sCb();
46-
});
17+
const key = subObj && subObj.data && subObj.data.keys && subObj.data.keys[0] && subObj.data.keys[0].value? subObj.data.keys[0].value:null;
18+
if (!key) return sCb();
19+
20+
const storageAccountName = resourceId.substring(resourceId.lastIndexOf('/') + 1);
21+
const credential = new AzureNamedKeyCredential(storageAccountName, key);
22+
const serviceClient = new TableServiceClient(
23+
`https://${storageAccountName}.table.core.windows.net`,
24+
credential
25+
);
26+
27+
const tables = [];
28+
29+
(async() => {
30+
try {
31+
for await (const table of serviceClient.listTables()) {
32+
tables.push(table.name);
4733
}
48-
});
49-
} else {
50-
sCb();
51-
}
52-
}, function() {
53-
cb();
54-
});
55-
}, function() {
56-
callback();
57-
});
34+
35+
collection['tableService']['listTablesSegmented'][region][resourceId].data = tables;
36+
37+
async.eachLimit(tables, 10, async(tableName, tableCb) => {
38+
const tableId = `${resourceId}/tableService/${tableName}`;
39+
collection['tableService']['getTableAcl'][region][tableId] = {};
40+
41+
try {
42+
const aclResponse = await serviceClient.getAccessPolicy(tableName);
43+
collection['tableService']['getTableAcl'][region][tableId].data = aclResponse;
44+
} catch (getErr) {
45+
collection['tableService']['getTableAcl'][region][tableId].err = getErr.message || getErr;
46+
}
47+
48+
tableCb();
49+
}, sCb);
50+
} catch (tableErr) {
51+
collection['tableService']['listTablesSegmented'][region][resourceId].err = tableErr.message || tableErr;
52+
sCb();
53+
}
54+
})();
55+
}, cb);
56+
}, callback);
5857
};

0 commit comments

Comments
 (0)