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#1430 from abdullahaslam306/feature/SA…
…AS-9853-aws-cognito-user-pool-have-waf Feature/saas 9853 aws cognito user pool have waf
- Loading branch information
Showing
6 changed files
with
216 additions
and
2 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
var AWS = require('aws-sdk'); | ||
var async = require('async'); | ||
var helpers = require(__dirname + '/../../../helpers/aws'); | ||
|
||
module.exports = function(AWSConfig, collection, retries, callback) { | ||
|
||
var wafv2 = new AWS.WAFV2(AWSConfig); | ||
|
||
if (!collection.sts.getCallerIdentity || !collection.sts.getCallerIdentity['us-east-1'].data) return callback(); | ||
|
||
async.eachLimit(collection.cognitoidentityserviceprovider.listUserPools[AWSConfig.region].data, 15, function(up, cb){ | ||
collection.wafv2.getWebACLForCognitoUserPool[AWSConfig.region][up.Id] = {}; | ||
var params = { | ||
'ResourceArn':`arn:aws:cognito-idp:${AWSConfig.region}:${collection.sts.getCallerIdentity['us-east-1'].data}:userpool/${up.Id}` | ||
}; | ||
|
||
helpers.makeCustomCollectorCall(wafv2, 'getWebACLForResource', params, retries, null, null, null, function(err, data) { | ||
if (err) { | ||
collection.wafv2.getWebACLForCognitoUserPool[AWSConfig.region][up.Id].err = err; | ||
} | ||
collection.wafv2.getWebACLForCognitoUserPool[AWSConfig.region][up.Id].data = data; | ||
cb(); | ||
}); | ||
|
||
}, function(){ | ||
callback(); | ||
}); | ||
}; |
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
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,64 @@ | ||
var async = require('async'); | ||
var helpers = require('../../../helpers/aws'); | ||
|
||
module.exports = { | ||
title: 'Cognito User Pool WAF Enabled', | ||
category: 'Cognito', | ||
domain: 'Identity and Access Management', | ||
description: 'Ensure that Cognito User Pool has WAF enabled.', | ||
more_info: 'Enabling WAF allows control over unwanted requests to your hosted UI and Amazon Cognito API service endpoints, allowing or denying traffic based off rules in the Web ACL.', | ||
link: 'https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-waf.html', | ||
recommended_action: '1. Enter the Cognito service. 2. Enter user pools and enable WAF from properties.', | ||
apis: ['CognitoIdentityServiceProvider:listUserPools', 'WAFV2:getWebACLForCognitoUserPool', 'STS:getCallerIdentity'], | ||
|
||
run: function(cache, settings, callback) { | ||
var results = []; | ||
var source = {}; | ||
var regions = helpers.regions(settings); | ||
|
||
var acctRegion = helpers.defaultRegion(settings); | ||
var awsOrGov = helpers.defaultPartition(settings); | ||
var accountId = helpers.addSource(cache, source, ['sts', 'getCallerIdentity', acctRegion, 'data']); | ||
|
||
async.each(regions.cognitoidentityserviceprovider, function(region, rcb) { | ||
var userPools = helpers.addSource(cache, source, | ||
['cognitoidentityserviceprovider', 'listUserPools', region]); | ||
|
||
if (!userPools) return rcb(); | ||
|
||
if (userPools.err || !userPools.data){ | ||
helpers.addResult(results, 3, 'Unable to query Cognito user pools: ' + helpers.addError(userPools), region); | ||
return rcb(); | ||
} | ||
|
||
if (!userPools.data.length){ | ||
helpers.addResult(results, 0, 'No Cognito user pools found', region); | ||
return rcb(); | ||
} | ||
|
||
for (let userPool of userPools.data) { | ||
if (!userPool.Id) continue; | ||
|
||
var arn = 'arn:' + awsOrGov + ':cognito-idp:' + region + ':' + accountId + ':userpool/' + userPool.Id; | ||
|
||
var webACLResource = helpers.addSource(cache, source, | ||
['wafv2', 'getWebACLForCognitoUserPool', region, userPool.Id]); | ||
|
||
if (!webACLResource || webACLResource.err || !webACLResource.data){ | ||
helpers.addResult(results, 3, | ||
'Unable to get WebACL resource for cognito user pool: ' + helpers.addError(webACLResource), region, arn); | ||
continue; | ||
} | ||
if (webACLResource.data.WebACL){ | ||
helpers.addResult(results, 0, 'User pool has WAFV2 enabled', region, arn); | ||
} else { | ||
helpers.addResult(results, 2, 'User pool does not have WAFV2 enabled', region, arn); | ||
} | ||
} | ||
|
||
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,110 @@ | ||
var expect = require('chai').expect; | ||
var cognitoHasWafEnabled = require('./cognitoHasWafEnabled'); | ||
|
||
const listUserPools = [ | ||
{ | ||
Id: 'us-east-1_cbDh8sCFGH', | ||
Name: 'test', | ||
LambdaConfig: {} | ||
} | ||
]; | ||
|
||
const createCache = (poolList, waf) => { | ||
return { | ||
cognitoidentityserviceprovider: { | ||
listUserPools: { | ||
'us-east-1': { | ||
err: null, | ||
data: poolList | ||
} | ||
}, | ||
}, | ||
sts: { | ||
getCallerIdentity: { | ||
'us-east-1': { | ||
data: '11111222222' | ||
} | ||
} | ||
}, | ||
wafv2: { | ||
getWebACLForCognitoUserPool: { | ||
'us-east-1':{ | ||
'us-east-1_cbDh8sCFGH': { | ||
err: null, | ||
data: waf | ||
} | ||
} | ||
} | ||
} | ||
|
||
} | ||
}; | ||
|
||
describe('cognitoHasWafEnabled', function () { | ||
describe('run', function () { | ||
it('should give unknown result if unable to list user pools', function (done) { | ||
const callback = (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(3); | ||
expect(results[0].region).to.equal('us-east-1'); | ||
expect(results[0].message).to.include('Unable to query Cognito user pools:'); | ||
done() | ||
}; | ||
|
||
const cache = createCache(null, null); | ||
cognitoHasWafEnabled.run(cache, {}, callback); | ||
}); | ||
|
||
it('should give passing result if User pool not found.', function (done) { | ||
const callback = (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('No Cognito user pools found'); | ||
done(); | ||
}; | ||
const cache = createCache([], null); | ||
cognitoHasWafEnabled.run(cache, {}, callback); | ||
}); | ||
|
||
it('should give unknown result if unable to query WAFV2 getWebACLForResource api', function (done) { | ||
const callback = (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(3); | ||
expect(results[0].region).to.equal('us-east-1'); | ||
expect(results[0].message).to.include('Unable to get WebACL resource for cognito user pool'); | ||
done(); | ||
}; | ||
|
||
const cache = createCache([listUserPools[0]], null); | ||
cognitoHasWafEnabled.run(cache, {}, callback); | ||
}); | ||
|
||
it('should give passing result if User pool has WAF enabled', function (done) { | ||
const callback = (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('User pool has WAFV2 enabled'); | ||
done(); | ||
}; | ||
|
||
const cache = createCache([listUserPools[0]], { WebACL: {'Name': 'abc'}}); | ||
cognitoHasWafEnabled.run(cache, {}, callback); | ||
}); | ||
|
||
it('should give failing result if User pool does not have WAF enabled', function (done) { | ||
const callback = (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('User pool does not have WAFV2 enabled'); | ||
done(); | ||
}; | ||
|
||
const cache = createCache([listUserPools[0]], { WebACL: null}); | ||
cognitoHasWafEnabled.run(cache, {}, callback); | ||
}); | ||
|
||
}); | ||
}); |