-
Notifications
You must be signed in to change notification settings - Fork 673
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature-iam-policies-present: Added AWS IAM Policies Present plugin a…
…nd test cases (#648) * SPLOIT-113: Added Plain Text Parameters plugin for CloudFormation * Added vpcEndpointAcceptance plugin and spec file * SPLOIT-113: Added Plain Text Parameters plugin for CloudFormation * Added plugin and spec file for launch wizard security groups * Refactored code in plaintextParameters plugin and spec file * SPLOIT-113: Updated custom settings * Made PR requested changes * SPLOIT-113: Added regex to check if NoEcho is enabled * Accommodated PR changes * Fixed eslint issues * Update exports.js * Fixed eslint issues * Update index.js * Update index.js * Added cloudformation in china and gov regions * Accomodated PR changes * Updated status in result of failure * SPLOIT-113: Added Plain Text Parameters plugin for CloudFormation * Added plugin and spec file for launch wizard security groups * Added vpcEndpointAcceptance plugin and spec file * Refactored code in plaintextParameters plugin and spec file * SPLOIT-113: Updated custom settings * Made PR requested changes * SPLOIT-113: Added regex to check if NoEcho is enabled * Accommodated PR changes * Fixed eslint issues * Update index.js * Update index.js * Accomodated PR changes * Updated status in result of failure * SPLOIT-113: Added Plain Text Parameters plugin for CloudFormation * Added plugin and spec file for launch wizard security groups * Added vpcEndpointAcceptance plugin and spec file * Refactored code in plaintextParameters plugin and spec file * SPLOIT-113: Updated custom settings * Made PR requested changes * SPLOIT-113: Added regex to check if NoEcho is enabled * Accommodated PR changes * Fixed eslint issues * Update index.js * Update index.js * Accomodated PR changes * Updated status in result of failure * SPLOIT-113: Added Plain Text Parameters plugin for CloudFormation * SPLOIT-113: Added Plain Text Parameters plugin for CloudFormation * Added plugin and spec file for launch wizard security groups * Added vpcEndpointAcceptance plugin and spec file * Refactored code in plaintextParameters plugin and spec file * SPLOIT-113: Updated custom settings * Made PR requested changes * SPLOIT-113: Added regex to check if NoEcho is enabled * Accommodated PR changes * Fixed eslint issues * Update exports.js * Update index.js * Update index.js * Accomodated PR changes * Updated status in result of failure * Removed unnecesary rebase changes * Added superlinter * Added scans ci * Updated Ci file * Updated Node version in CI file * removed spech check command * Delete scan_ci.yml * Added spellcheck * Added AWS IAM Policies Present plugin and test cases * Update plugins/aws/iam/iamPoliciesPresent.js * Update plugins/aws/iam/iamPoliciesPresent.js Co-authored-by: Gio Rodriguez <gioroddev@gmail.com>
- Loading branch information
1 parent
6cd2f5c
commit 9ed8095
Showing
3 changed files
with
265 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,105 @@ | ||
var async = require('async'); | ||
var helpers = require('../../../helpers/aws'); | ||
|
||
module.exports = { | ||
title: 'IAM Policies Present', | ||
category: 'IAM', | ||
description: 'Ensure that required policies are present in all IAM roles.', | ||
more_info: 'Validate the presence of required policies in IAM roles in order to follow your organizations\'s security and compliance requirements.', | ||
link: 'https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html', | ||
recommended_action: 'Modify IAM roles to attach required policies', | ||
apis: ['IAM:listRoles', 'IAM:listRolePolicies', 'IAM:listAttachedRolePolicies'], | ||
settings: { | ||
iam_required_policy_names: { | ||
name: 'IAM Required Policy Names', | ||
description: 'A comma separated list of IAM policy names that all IAM roles should have', | ||
regex: '^.*$', | ||
default: '' | ||
} | ||
}, | ||
|
||
run: function(cache, settings, callback) { | ||
var config = { | ||
iam_required_policy_names: settings.iam_required_policy_names || this.settings.iam_required_policy_names.default | ||
}; | ||
|
||
if (!config.iam_required_policy_names.length) return callback(null, results, source); | ||
|
||
config.iam_required_policy_names = config.iam_required_policy_names.split(','); | ||
|
||
var results = []; | ||
var source = {}; | ||
|
||
var region = helpers.defaultRegion(settings); | ||
|
||
var listRoles = helpers.addSource(cache, source, | ||
['iam', 'listRoles', region]); | ||
|
||
if (!listRoles) return callback(null, results, source); | ||
|
||
if (listRoles.err || !listRoles.data) { | ||
helpers.addResult(results, 3, | ||
'Unable to query for IAM roles: ' + helpers.addError(listRoles)); | ||
return callback(null, results, source); | ||
} | ||
|
||
if (!listRoles.data.length) { | ||
helpers.addResult(results, 0, 'No IAM roles found'); | ||
return callback(null, results, source); | ||
} | ||
|
||
async.each(listRoles.data, function(role, cb){ | ||
if (!role.RoleName) return cb(); | ||
|
||
// Get managed policies attached to role | ||
var listAttachedRolePolicies = helpers.addSource(cache, source, | ||
['iam', 'listAttachedRolePolicies', region, role.RoleName]); | ||
|
||
// Get inline policies attached to role | ||
var listRolePolicies = helpers.addSource(cache, source, | ||
['iam', 'listRolePolicies', region, role.RoleName]); | ||
|
||
if (!listAttachedRolePolicies || listAttachedRolePolicies.err) { | ||
helpers.addResult(results, 3, | ||
'Unable to query for IAM attached policy for role: ' + role.RoleName + ': ' + helpers.addError(listAttachedRolePolicies), region, role.Arn); | ||
return cb(); | ||
} | ||
|
||
if (!listRolePolicies || listRolePolicies.err) { | ||
helpers.addResult(results, 3, | ||
'Unable to query for IAM role policy for role: ' + role.RoleName + ': ' + helpers.addError(listRolePolicies), region, role.Arn); | ||
return cb(); | ||
} | ||
|
||
var attachedPolicies = []; | ||
var difference = []; | ||
|
||
// See if role has admin managed policy | ||
if (listAttachedRolePolicies.data && | ||
listAttachedRolePolicies.data.AttachedPolicies) { | ||
|
||
for (let policy of listAttachedRolePolicies.data.AttachedPolicies) { | ||
attachedPolicies.push(policy.PolicyName); | ||
} | ||
} | ||
|
||
if (listRolePolicies.data && listRolePolicies.data.PolicyNames) attachedPolicies = attachedPolicies.concat(listRolePolicies.data.PolicyNames); | ||
|
||
for (let policy of config.iam_required_policy_names) { | ||
if (!attachedPolicies.includes(policy)) difference.push(policy); | ||
} | ||
|
||
if (difference.length) { | ||
helpers.addResult(results, 2, | ||
`IAM role does not have these required policies attached: ${difference.join(', ')}`, region, role.Arn); | ||
} else { | ||
helpers.addResult(results, 0, | ||
'IAM role has all required policies attached', region, role.Arn); | ||
} | ||
|
||
cb(); | ||
}, 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,159 @@ | ||
const expect = require('chai').expect; | ||
var iamPoliciesPresent = require('./iamPoliciesPresent'); | ||
|
||
|
||
const listRoles = [ | ||
{ | ||
"Path": "/", | ||
"RoleName": "test-role-1", | ||
"RoleId": "AROAYE32SRU5VIMXXL3BH", | ||
"Arn": "arn:aws:iam::000011112222:role/test-role-1", | ||
"CreateDate": "2020-11-21T23:56:33Z", | ||
"AssumeRolePolicyDocument": { | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Effect": "Allow", | ||
"Principal": { | ||
"AWS": "arn:aws:iam::000011112222:root" | ||
}, | ||
"Action": "sts:AssumeRoleWithSAML", | ||
"Condition": {} | ||
} | ||
] | ||
}, | ||
"MaxSessionDuration": 3600 | ||
} | ||
]; | ||
|
||
const listRolePolicies = [ | ||
{ | ||
"PolicyNames": [ | ||
"S3-Full" | ||
] | ||
} | ||
]; | ||
|
||
const listAttachedRolePolicies = [ | ||
{ | ||
"ResponseMetadata": { | ||
"RequestId": 'f7d427cc-970b-47af-9b7d-3e06121f83da' | ||
}, | ||
"AttachedPolicies": [ | ||
{ | ||
"PolicyName": 'AdministratorAccess', | ||
"PolicyArn": 'arn:aws:iam::aws:policy/AdministratorAccess' | ||
} | ||
], | ||
"IsTruncated": false | ||
} | ||
]; | ||
|
||
const createCache = (listRoles, listAttachedRolePolicies, listRolePolicies, listRolesErr, listAttachedRolePoliciesErr, listRolePoliciesErr) => { | ||
var roleName = (listRoles && listRoles.length) ? listRoles[0].RoleName : null; | ||
return { | ||
iam: { | ||
listRoles: { | ||
'us-east-1': { | ||
err: listRolesErr, | ||
data: listRoles | ||
} | ||
}, | ||
listAttachedRolePolicies: { | ||
'us-east-1': { | ||
[roleName]: { | ||
err: listAttachedRolePoliciesErr, | ||
data: listAttachedRolePolicies | ||
} | ||
} | ||
}, | ||
listRolePolicies: { | ||
'us-east-1': { | ||
[roleName]: { | ||
err: listRolePoliciesErr, | ||
data: listRolePolicies | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
}; | ||
|
||
const createNullCache = () => { | ||
return { | ||
lambda: { | ||
listRoles: { | ||
'us-east-1': null | ||
} | ||
} | ||
}; | ||
}; | ||
|
||
describe('iamPoliciesPresent', function () { | ||
describe('run', function () { | ||
|
||
it('should PASS if IAM role has all required policies attached', function (done) { | ||
const cache = createCache([listRoles[0]], listAttachedRolePolicies[0], listRolePolicies[0]); | ||
iamPoliciesPresent.run(cache, { iam_required_policy_names: 'S3-Full,AdministratorAccess' }, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(0); | ||
expect(results[0].region).to.equal('us-east-1'); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should FAIL if IAM role does not have required policies attached', function (done) { | ||
const cache = createCache([listRoles[0]], {}, listRolePolicies[0]); | ||
iamPoliciesPresent.run(cache, { iam_required_policy_names: 'AdministratorAccess' }, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(2); | ||
expect(results[0].region).to.equal('us-east-1'); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should PASS if on IAM roles found', function (done) { | ||
const cache = createCache([]); | ||
iamPoliciesPresent.run(cache, { iam_required_policy_names: 'S3-Full' }, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(0); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should UNKNOWN if unable to list IAM roles', function (done) { | ||
const cache = createCache(null, null, null, { message: 'Unable to list IAM roles'}); | ||
iamPoliciesPresent.run(cache, { iam_required_policy_names: 'S3-Full' }, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(3); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should UNKNOWN if unable to list attached role policies', function (done) { | ||
const cache = createCache([listRoles[0]], {}, null, { message: 'Unable to list attached role policies'}); | ||
iamPoliciesPresent.run(cache, { iam_required_policy_names: 'S3-Full' }, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(3); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should UNKNOWN if unable to list role policies', function (done) { | ||
const cache = createCache([listRoles[0]], listAttachedRolePolicies[0], {}, null, null, { message: 'Unable to query role policies'}); | ||
iamPoliciesPresent.run(cache, { iam_required_policy_names: 'S3-Full' }, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(3); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should not return anything if list roles response not found', function (done) { | ||
const cache = createNullCache(); | ||
iamPoliciesPresent.run(cache, { iam_required_policy_names: 'S3-Full' }, (err, results) => { | ||
expect(results.length).to.equal(0); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |