Skip to content

Commit

Permalink
Merge pull request aquasecurity#1430 from abdullahaslam306/feature/SA…
Browse files Browse the repository at this point in the history
…AS-9853-aws-cognito-user-pool-have-waf

Feature/saas 9853 aws cognito user pool have waf
  • Loading branch information
AkhtarAmir committed Nov 1, 2022
2 parents 05bed12 + 61933e2 commit 3e336e5
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 2 deletions.
28 changes: 28 additions & 0 deletions collectors/aws/wafv2/getWebACLForCognitoUserPool.js
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();
});
};
2 changes: 2 additions & 0 deletions exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,8 @@ module.exports = {

'ecsContainerInsightsEnabled' : require(__dirname + '/plugins/aws/ecs/ecsContainerInsightsEnabled.js'),
'ecsClustersHaveTags' : require(__dirname + '/plugins/aws/ecs/ecsClustersHaveTags.js'),

'cognitoHasWafEnabled' : require(__dirname + '/plugins/aws/cognito/cognitoHasWafEnabled.js'),
'cognitoMFAEnabled' : require(__dirname + '/plugins/aws/cognito/cognitoMFAEnabled.js')
},
azure : {
Expand Down
7 changes: 6 additions & 1 deletion helpers/aws/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ var calls = {
params: {
MaxResults: 60
}
},
}
},
CodePipeline: {
listPipelines: {
Expand Down Expand Up @@ -2061,6 +2061,11 @@ var postcalls = [
reliesOnService: 'wafv2',
reliesOnCall: 'listWebACLs',
override: true
},
getWebACLForCognitoUserPool: {
reliesOnService: 'cognitoidentityserviceprovider',
reliesOnCall: 'listUserPools',
override: true
}
},
GuardDuty: {
Expand Down
7 changes: 6 additions & 1 deletion helpers/aws/api_multipart.js
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,7 @@ var calls = [
property: 'UserPools',
paginate: 'NextToken',
params: {
MaxResults: 100
MaxResults: 60
}
},
},
Expand Down Expand Up @@ -1713,6 +1713,11 @@ var postcalls = [
reliesOnCall: 'listWebACLs',
override: true,
rateLimit: 600
},
getWebACLForCognitoUserPool: {
reliesOnService: 'cognitoidentityserviceprovider',
reliesOnCall: 'listUserPools',
override: true
}
},
ECS: {
Expand Down
64 changes: 64 additions & 0 deletions plugins/aws/cognito/cognitoHasWafEnabled.js
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);
});
}
};
110 changes: 110 additions & 0 deletions plugins/aws/cognito/cognitoHasWafEnabled.spec.js
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);
});

});
});

0 comments on commit 3e336e5

Please sign in to comment.