Skip to content

Commit

Permalink
listFindingV2 added
Browse files Browse the repository at this point in the history
  • Loading branch information
Khizer-aqua committed Jan 26, 2025
1 parent 5370f01 commit a2139e2
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 7 deletions.
49 changes: 49 additions & 0 deletions collectors/aws/accessanalyzer/listFindingsV2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
var AWS = require('aws-sdk');
var async = require('async');
var helpers = require(__dirname + '/../../../helpers/aws');

module.exports = function(AWSConfig, collection, retries, callback) {
var accessanalyzer = new AWS.AccessAnalyzer(AWSConfig);
async.eachLimit(collection.accessanalyzer.listAnalyzers[AWSConfig.region].data, 15, function(analyzer, cb) {
collection.accessanalyzer.listFindingsV2[AWSConfig.region][analyzer.arn] = {};
var params = {
analyzerArn: analyzer.arn
};

var paginating = false;
var paginateCb = function(err, data) {
if (err) collection.accessanalyzer.listFindingsV2[AWSConfig.region][analyzer.arn].err = err;

if (!data) return cb();

if (paginating && data.findings && data.findings.length &&
collection.accessanalyzer.listFindingsV2[AWSConfig.region][analyzer.arn].data.findings &&
collection.accessanalyzer.listFindingsV2[AWSConfig.region][analyzer.arn].data.findings.length) {
collection.accessanalyzer.listFindingsV2[AWSConfig.region][analyzer.arn].data.findings = collection.accessanalyzer.listFindings[AWSConfig.region][analyzer.arn].data.findings.concat(data.findings);
} else {
collection.accessanalyzer.listFindingsV2[AWSConfig.region][analyzer.arn].data = data;
}

if (data.nextToken && data.nextToken.length) {
paginating = true;
return execute(data.nextToken);
}

cb();
};

function execute(nextToken) { // eslint-disable-line no-inner-declarations
var localParams = JSON.parse(JSON.stringify(params || {}));
if (nextToken) localParams['nextToken'] = nextToken;
if (nextToken) {
helpers.makeCustomCollectorCall(accessanalyzer, 'listFindingsV2', localParams, retries, null, null, null, paginateCb);
} else {
helpers.makeCustomCollectorCall(accessanalyzer, 'listFindingsV2', params, retries, null, null, null, paginateCb);
}
}

execute();
}, function(){
callback();
});
};
6 changes: 6 additions & 0 deletions helpers/aws/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -1833,8 +1833,14 @@ var postcalls = [
reliesOnCall: 'listAnalyzers',
override: true
},
listFindingsV2: {
reliesOnService: 'accessanalyzer',
reliesOnCall: 'listAnalyzers',
override: true
},
sendIntegration: serviceMap['IAM'][0]
},

APIGateway: {
getStages: {
reliesOnService: 'apigateway',
Expand Down
23 changes: 18 additions & 5 deletions plugins/aws/accessanalyzer/accessAnalyzerActiveFindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module.exports = {
'You can view IAM Access Analyzer findings at any time. Work through all of the findings in your account until you have zero active findings.',
link: 'https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-work-with-findings.html',
recommended_action: 'Investigate into active findings in your account and do the needful until you have zero active findings.',
apis: ['AccessAnalyzer:listAnalyzers', 'AccessAnalyzer:listFindings'],
apis: ['AccessAnalyzer:listAnalyzers', 'AccessAnalyzer:listFindings', 'AccessAnalyzer:listFindingsV2'],
realtime_triggers: ['accessanalyzer:CreateAnalyzer','accessanalyzer:DeleteAnalyzer','accessanalyzer:CreateArchiveRule','accessanalyzer:StartResourceScan'],

run: function(cache, settings, callback) {
Expand Down Expand Up @@ -40,19 +40,32 @@ module.exports = {
if (!analyzer.arn) continue;

let resource = analyzer.arn;
let totalFiltered = []

var listFindings = helpers.addSource(cache, source,
['accessanalyzer', 'listFindings', region, analyzer.arn]);

if (!listFindings || listFindings.err || !listFindings.data) {
if (listFindings && !listFindings.err && listFindings.data) {
let filtered = listFindings.data.findings.filter(finding => finding.status === 'ACTIVE');
totalFiltered = totalFiltered.concat(filtered)
}

var listFindingsV2 = helpers.addSource(cache, source,
['accessanalyzer', 'listFindingsV2', region, analyzer.arn]);

if (listFindingsV2 && !listFindingsV2.err && listFindingsV2.data) {
let filteredv2 = listFindingsV2.data.findings.filter(finding => finding.status === 'ACTIVE');
totalFiltered = totalFiltered.concat(filteredv2)
}

if ((!listFindings || listFindings.err || !listFindings.data) && (!listFindingsV2 || listFindingsV2.err || !listFindingsV2.data)) {
helpers.addResult(results, 3,
`Unable to IAM Access Analyzer findings: ${helpers.addError(listFindings)}`,
`Unable to IAM Access Analyzer findings: ${helpers.addError(listFindings)} ${helpers.addError(listFindingsV2)}`,
region, resource);
continue;
}

let filtered = listFindings.data.findings.filter(finding => finding.status === 'ACTIVE');
if (!filtered.length) {
if (!totalFiltered.length) {
helpers.addResult(results, 0,
'Amazon IAM Access Analyzer has no active findings',
region, resource);
Expand Down
105 changes: 103 additions & 2 deletions plugins/aws/accessanalyzer/accessAnalyzerActiveFindings.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,83 @@ const listFindings = [

];

const listFindingsV2 = [
{
"findings": [
{
"analyzedAt": "2025-01-23T13:06:24+00:00",
"createdAt": "2025-01-23T13:06:56+00:00",
"id": "1a234567-bc6d-7yui-h5j7-4f5f9j8987y0",
"resource": "arn:aws:iam::123456789123:role/abcd-abcd-adfitoui-abcdefg-p1-AsdfghTfjdudnjkDkjg-Z9JgMyMzcxOZ",
"resourceType": "AWS::IAM::Role",
"resourceOwnerAccount": "123456789123",
"status": "ACTIVE",
"updatedAt": "2025-01-23T13:06:56+00:00",
"findingType": "UnusedIAMRole"
},
{
"analyzedAt": "2025-01-23T13:06:24+00:00",
"createdAt": "2025-01-23T13:06:56+00:00",
"id": "938r4848-4h4j-8449-76d8-8768dh5dhh4u",
"resource": "arn:aws:iam::123456789123:role/abcd-abcd-adfitoui-abcdefg-AsdfghTfjdudnjkDkjg-6vzrTVSqTaNe",
"resourceType": "AWS::IAM::Role",
"resourceOwnerAccount": "123456789123",
"status": "ACTIVE",
"updatedAt": "2025-01-23T13:06:56+00:00",
"findingType": "UnusedIAMRole"
},
{
"analyzedAt": "2025-01-23T13:06:55+00:00",
"createdAt": "2025-01-23T13:06:56+00:00",
"id": "7484f848-984j-498l-784s-yryh74748f45",
"resource": "arn:aws:iam::123456789123:role/service-role/sdfghyFj-FGH-njkkjg-plgd-6uhjn9ok",
"resourceType": "AWS::IAM::Role",
"resourceOwnerAccount": "123456789123",
"status": "ACTIVE",
"updatedAt": "2025-01-23T13:06:56+00:00",
"findingType": "UnusedPermission"
},
]
},
{
"findings": [
{
"analyzedAt": "2025-01-23T13:06:24+00:00",
"createdAt": "2025-01-23T13:06:56+00:00",
"id": "1a234567-bc6d-7yui-h5j7-4f5f9j8987y0",
"resource": "arn:aws:iam::123456789123:role/abcd-abcd-adfitoui-abcdefg-p1-AsdfghTfjdudnjkDkjg-Z9JgMyMzcxOZ",
"resourceType": "AWS::IAM::Role",
"resourceOwnerAccount": "123456789123",
"status": "ARCHIVED",
"updatedAt": "2025-01-23T13:06:56+00:00",
"findingType": "UnusedIAMRole"
},
{
"analyzedAt": "2025-01-23T13:06:24+00:00",
"createdAt": "2025-01-23T13:06:56+00:00",
"id": "938r4848-4h4j-8449-76d8-8768dh5dhh4u",
"resource": "arn:aws:iam::123456789123:role/abcd-abcd-adfitoui-abcdefg-AsdfghTfjdudnjkDkjg-6vzrTVSqTaNe",
"resourceType": "AWS::IAM::Role",
"resourceOwnerAccount": "123456789123",
"status": "ARCHIVED",
"updatedAt": "2025-01-23T13:06:56+00:00",
"findingType": "UnusedIAMRole"
},
{
"analyzedAt": "2025-01-23T13:06:55+00:00",
"createdAt": "2025-01-23T13:06:56+00:00",
"id": "7484f848-984j-498l-784s-yryh74748f45",
"resource": "arn:aws:iam::123456789123:role/service-role/sdfghyFj-FGH-njkkjg-plgd-6uhjn9ok",
"resourceType": "AWS::IAM::Role",
"resourceOwnerAccount": "123456789123",
"status": "RESOLVED",
"updatedAt": "2025-01-23T13:06:56+00:00",
"findingType": "UnusedPermission"
},
]
}

]

const createCache = (analyzer, listFindings, analyzerErr, listFindingsErr) => {
var analyzerArn = (analyzer && analyzer.length) ? analyzer[0].arn: null;
Expand All @@ -163,7 +240,7 @@ const createCache = (analyzer, listFindings, analyzerErr, listFindingsErr) => {

describe('accessAnalyzerActiveFindings', function () {
describe('run', function () {
it('should FAIL if Amazon IAM access analyzer has active findings.', function (done) {
it('should FAIL if Amazon IAM access analyzer V1 has active findings.', function (done) {
const cache = createCache(listAnalyzers, listFindings[0]);
accessAnalyzerActiveFindings.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
Expand All @@ -174,7 +251,18 @@ describe('accessAnalyzerActiveFindings', function () {
});
});

it('should PASS if Amazon IAM access analyzer have no active findings.', function (done) {
it('should FAIL if Amazon IAM access analyzer v2 has active findings.', function (done) {
const cache = createCache(listAnalyzers, listFindingsV2[0]);
accessAnalyzerActiveFindings.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(2);
expect(results[0].region).to.equal('us-east-1');
expect(results[0].message).to.include('Amazon IAM Access Analyzer has active findings');
done();
});
});

it('should PASS if Amazon IAM access analyzer V1 have no active findings.', function (done) {
const cache = createCache(listAnalyzers, listFindings[1]);
accessAnalyzerActiveFindings.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
Expand All @@ -186,6 +274,19 @@ describe('accessAnalyzerActiveFindings', function () {
});
});


it('should PASS if Amazon IAM access analyzer V2 have no active findings.', function (done) {
const cache = createCache(listAnalyzers, listFindingsV2[1]);
accessAnalyzerActiveFindings.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
expect(results[0].region).to.equal('us-east-1');
expect(results[0].message).to.include('Amazon IAM Access Analyzer has no active findings');

done();
});
});

it('should PASS if no analyzers found', function (done) {
const cache = createCache([]);
accessAnalyzerActiveFindings.run(cache, {}, (err, results) => {
Expand Down

0 comments on commit a2139e2

Please sign in to comment.