Skip to content

Commit

Permalink
Added AWS CodeBuild Valid Source Providers plugin and test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
AkhtarAmir committed Apr 8, 2021
1 parent 9d5683d commit ceb2c8d
Show file tree
Hide file tree
Showing 8 changed files with 604 additions and 342 deletions.
24 changes: 24 additions & 0 deletions collectors/aws/codebuild/batchGetProjects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
var AWS = require('aws-sdk');
var async = require('async');

module.exports = function(AWSConfig, collection, callback) {
var codebuild = new AWS.CodeBuild(AWSConfig);

async.eachLimit(collection.codebuild.listProjects[AWSConfig.region].data, 15, function(project, cb){
collection.codebuild.batchGetProjects[AWSConfig.region][project] = {};

var params = {
names: [project],
};

codebuild.batchGetProjects(params, function(err, data) {
if (err) {
collection.codebuild.batchGetProjects[AWSConfig.region][project].err = err;
}
collection.codebuild.batchGetProjects[AWSConfig.region][project].data = data;
cb();
});
}, function(){
callback();
});
};
13 changes: 13 additions & 0 deletions collectors/aws/collector.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ var calls = {
}
}
},
CodeBuild: {
listProjects: {
property: 'projects',
paginate: 'nextToken'
}
},
Comprehend: {
listEntitiesDetectionJobs: {
property: 'EntitiesDetectionJobPropertiesList',
Expand Down Expand Up @@ -838,6 +844,13 @@ var postcalls = [
filterValue: 'TrailARN'
}
},
CodeBuild: {
batchGetProjects: {
reliesOnService: 'codebuild',
reliesOnCall: 'listProjects',
override: true
}
},
DynamoDB: {
describeTable: {
reliesOnService: 'dynamodb',
Expand Down
680 changes: 341 additions & 339 deletions exports.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion helpers/aws/regions.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,5 +125,6 @@ module.exports = {
xray: ['us-east-1', 'us-east-2', 'us-west-2', 'us-west-1',
'ca-central-1', 'eu-central-1', 'eu-west-1', 'eu-west-2', 'eu-west-3', 'eu-north-1',
'ap-northeast-1', 'ap-northeast-2',
'ap-southeast-1', 'ap-southeast-2', 'ap-south-1', 'sa-east-1', 'ap-east-1']
'ap-southeast-1', 'ap-southeast-2', 'ap-south-1', 'sa-east-1', 'ap-east-1'],
codebuild: regions
};
3 changes: 2 additions & 1 deletion helpers/aws/regions_china.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,6 @@ module.exports = {
wafv2: [],
workspaces: ['cn-northwest-1'],
xray: regions,
resourcegroupstaggingapi: regions
resourcegroupstaggingapi: regions,
codebuild: regions
};
3 changes: 2 additions & 1 deletion helpers/aws/regions_gov.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,6 @@ module.exports = {
wafv2: regions,
workspaces: ['us-gov-west-1'],
xray: [],
resourcegroupstaggingapi: regions
resourcegroupstaggingapi: regions,
codebuild: regions
};
94 changes: 94 additions & 0 deletions plugins/aws/codebuild/codebuildValidSourceProviders.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
var async = require('async');
var helpers = require('../../../helpers/aws');

module.exports = {
title: 'CodeBuild Valid Source Providers',
category: 'CodeBuild',
description: 'Ensure that CodeBuild projects are using only valid source providers.',
more_info: 'CodeBuild should use only desired source providers in order to follow your organizations\'s security and compliance requirements.',
link: 'https://docs.aws.amazon.com/codebuild/latest/APIReference/API_ProjectSource.html',
recommended_action: 'Edit CodeBuild project source provider information and remove disallowed source providers',
apis: ['CodeBuild:listProjects', 'CodeBuild:batchGetProjects', 'STS:getCallerIdentity'],
settings: {
codebuild_disallowed_source_providers: {
name: 'CodeBuild Disallowed Source Providers',
description: 'A comma-separated list of source providers which should not be used',
regex: '^((bitbucket|codecommit|codepipeline|github|github_enterprise|s3|),? ?){1,5}$',
default: ''
}
},

run: function(cache, settings, callback) {
var results = [];
var source = {};
var regions = helpers.regions(settings);

var config = {
codebuild_disallowed_source_providers: settings.codebuild_disallowed_source_providers || this.settings.codebuild_disallowed_source_providers.default
};

if (!config.codebuild_disallowed_source_providers.length) return callback(null, results, source);

var acctRegion = helpers.defaultRegion(settings);
var awsOrGov = helpers.defaultPartition(settings);
var accountId = helpers.addSource(cache, source,
['sts', 'getCallerIdentity', acctRegion, 'data']);

async.each(regions.codebuild, function(region, rcb){
var listProjects = helpers.addSource(cache, source, ['codebuild', 'listProjects', region]);

if (!listProjects) return rcb();

if (listProjects.err || !listProjects.data) {
helpers.addResult(results, 3, `Unable to query CodeBuild projects: ${helpers.addError(listProjects)}`, region);
return rcb();
}

if (!listProjects.data.length) {
helpers.addResult(results, 0, 'No CodeBuild projects found', region);
return rcb();
}

async.each(listProjects.data, function(project, cb) {
var resource = `arn:${awsOrGov}:codebuild:${region}:${accountId}:project/${project}`;

var batchGetProjects = helpers.addSource(cache, source, ['codebuild', 'batchGetProjects', region, project]);

if (!batchGetProjects || batchGetProjects.err ||
!batchGetProjects.data || !batchGetProjects.data.projects || !batchGetProjects.data.projects.length) {
helpers.addResult(results, 3,
`Unable to query CodeBuild project: ${helpers.addError(batchGetProjects)}`, region, resource);
return cb();
}

var invalidSources = [];
if (batchGetProjects.data.projects[0].source &&
batchGetProjects.data.projects[0].source.type &&
config.codebuild_disallowed_source_providers.includes(batchGetProjects.data.projects[0].source.type.toLowerCase()))
invalidSources.push(batchGetProjects.data.projects[0].source.type.toLowerCase());

if (batchGetProjects.data.projects[0].secondarySources &&
batchGetProjects.data.projects[0].secondarySources.length) {
for (let source of batchGetProjects.data.projects[0].secondarySources) {
var sourceLower = source.type.toLowerCase()
if (config.codebuild_disallowed_source_providers.includes(sourceLower) && !invalidSources.includes(sourceLower)) invalidSources.push(sourceLower);
}
}

if (invalidSources.length) {
helpers.addResult(results, 2,
`CodeBuild project is using these disallowed source providers: ${invalidSources.join(', ')}`, region, resource);
} else {
helpers.addResult(results, 0,
'CodeBuild project is using allowed source providers', region, resource);
}

cb();
}, function(){
rcb();
});
}, function(){
callback(null, results, source);
});
}
};
126 changes: 126 additions & 0 deletions plugins/aws/codebuild/codebuildValidSourceProviders.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
var expect = require('chai').expect;
const codebuildValidSourceProviders = require('./codebuildValidSourceProviders');

const listProjects = [
'test-project'
];


const batchGetProjects ={
"projects": [
{
"name": "test-project",
"arn": "arn:aws:codebuild:us-east-1:111122223333:project/test-project",
"source": {
"type": "GITHUB",
"location": "https://github.com/cloudsplit/scans",
"gitCloneDepth": 1,
"gitSubmodulesConfig": {
"fetchSubmodules": false
},
"reportBuildStatus": false,
"insecureSsl": false
},
"secondarySources": [
{
"type": "S3",
"location": "my-aqua-bucket/data",
"insecureSsl": false,
"sourceIdentifier": "s3_source"
}
]
}
],
};

const createCache = (listProjects, batchGetProjects, listProjectsErr, batchGetProjectsErr) => {
let project = (listProjects && listProjects.length) ? listProjects[0] : null;
return {
codebuild: {
listProjects: {
'us-east-1': {
data: listProjects,
err: listProjectsErr
}
},
batchGetProjects: {
'us-east-1': {
[project]: {
data: batchGetProjects,
err: batchGetProjectsErr
}
}
}
}
}
};

const createNullCache = () => {
return {
codebuild: {
listProjects: {
'us-east-1': null,
},
},
};
};

describe('codebuildValidSourceProviders', function () {
describe('run', function () {
it('should PASS if CodeBuild project is using allowed source providers', function (done) {
const cache = createCache(listProjects, batchGetProjects);
codebuildValidSourceProviders.run(cache, { codebuild_disallowed_source_providers: 'bitbucket'}, (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 CodeBuild project is using disallowed source providers', function (done) {
const cache = createCache(listProjects, batchGetProjects);
codebuildValidSourceProviders.run(cache, { codebuild_disallowed_source_providers: 's3' }, (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 no CodeBuild projects found', function (done) {
const cache = createCache([]);
codebuildValidSourceProviders.run(cache, { codebuild_disallowed_source_providers: 's3' }, (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 UNKNOWN if unable to query CodeBuild projects', function (done) {
const cache = createCache(listProjects, { message: 'Unable to query CodeBuild projects' });
codebuildValidSourceProviders.run(cache, { codebuild_disallowed_source_providers: 's3' }, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(3);
done();
});
});

it('should UNKNOWN if unable to query CodeBuild project', function (done) {
const cache = createCache(listProjects, null, null, { message: 'Unable to query CodeBuild project' });
codebuildValidSourceProviders.run(cache, { codebuild_disallowed_source_providers: 's3' }, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(3);
done();
});
});

it('should not return any results if unable to query for comprehend jobs', function (done) {
const cache = createNullCache();
codebuildValidSourceProviders.run(cache, {}, (err, results) => {
expect(results.length).to.equal(0);
done();
});
});
});
});

0 comments on commit ceb2c8d

Please sign in to comment.