Skip to content

Commit

Permalink
feature-request: Added 'Workspaces IP Access Control' plugin and test…
Browse files Browse the repository at this point in the history
… cases (aquasecurity#451)

* Added 'Workspaces IP Access Control' plugin and test cases

* Accommodated PR changes to add extar checks
  • Loading branch information
AkhtarAmir authored Jan 21, 2021
1 parent ee246b2 commit 955a4e3
Show file tree
Hide file tree
Showing 4 changed files with 307 additions and 0 deletions.
8 changes: 8 additions & 0 deletions collectors/aws/collector.js
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,14 @@ var calls = {
describeWorkspaces: {
property: 'Workspaces',
paginate: 'NextToken'
},
describeWorkspaceDirectories:{
property: 'Directories',
paginate: 'NextToken'
},
describeIpGroups:{
property: 'Result',
paginate: 'NextToken'
}
},
XRay: {
Expand Down
2 changes: 2 additions & 0 deletions exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ module.exports = {
'guardDutyEnabled' : require(__dirname + '/plugins/aws/guardduty/guarddutyEnabled.js'),
'guardDutyMaster' : require(__dirname + '/plugins/aws/guardduty/guarddutyMaster.js'),

'workspacesIpAccessControl' : require(__dirname + '/plugins/aws/workspaces/workspacesIpAccessControl.js'),

'xrayEncryptionEnabled' : require(__dirname + '/plugins/aws/xray/xrayEncryptionEnabled.js'),
},
azure : {
Expand Down
87 changes: 87 additions & 0 deletions plugins/aws/workspaces/workspacesIpAccessControl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
var async = require('async');
var helpers = require('../../../helpers/aws');

module.exports = {
title: 'Workspaces IP Access Control',
category: 'Workspaces',
description: 'Ensures enforced IP Access Control on Workspaces',
more_info: 'Checking the existence of IP Access control on Workspaces and ensuring that no Workspaces are open',
link: 'https://docs.aws.amazon.com/workspaces/latest/adminguide/amazon-workspaces-ip-access-control-groups.html',
recommended_action: 'Enable proper IP Access Controls for all workspaces',
apis: ['WorkSpaces:describeWorkspaces', 'WorkSpaces:describeWorkspaceDirectories', 'WorkSpaces:describeIpGroups', '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']);

const enabledString = 'IP Access Control is enabled';
const enabledButAllowsWorldString = 'IP Access Control is enabled but 0.0.0.0/0 is allowed';
const disabledString = 'IP Access Control is disabled';

async.each(regions.workspaces, function(region, rcb){
var listWorkspaces = helpers.addSource(cache, source, ['workspaces', 'describeWorkspaces', region, 'data']);
var listDirectories = helpers.addSource(cache, source, ['workspaces', 'describeWorkspaceDirectories', region, 'data']);
var listIPGroups = helpers.addSource(cache, source, ['workspaces', 'describeIpGroups', region, 'data']);

if (!listWorkspaces) {
return rcb();
}

if (listWorkspaces.err) {
helpers.addResult(
results, 3, 'Unable to query for WorkSpaces information: ' + helpers.addError(listWorkspaces), region);
return rcb();
}

if (!listWorkspaces.length) {
helpers.addResult(
results, 0, 'No Workspaces found.', region);
return rcb();
}

for (var workspace of listWorkspaces) {
var arn = 'arn:' + awsOrGov + ':workspaces:' + region + ':' + accountId + ':workspace/' + workspace.WorkspaceId;

if (!workspace.DirectoryId){
helpers.addResult(results, 2, disabledString, region, arn);
continue;
}

var workspaceDirectory = listDirectories.find(directory => directory.DirectoryId === workspace.DirectoryId);

if (workspaceDirectory && workspaceDirectory.ipGroupIds) {
let openToEverything = false;
for (var workspaceIPGroup of workspaceDirectory.ipGroupIds){
var ipGroup = listIPGroups.find(o => o.groupId === workspaceIPGroup);

if (ipGroup && ipGroup.userRules) {
if (ipGroup.userRules.find(o => o.ipRule === '0.0.0.0/0')) {
openToEverything = true;
break;
}
}
}

if (openToEverything){
helpers.addResult(results, 2, enabledButAllowsWorldString, region, arn);
} else {
helpers.addResult(results, 0, enabledString, region, arn);
}
} else {
helpers.addResult(results, 2, disabledString, region, arn);
}
}

return rcb();

}, function(){
callback(null, results, source);
});
}
};
210 changes: 210 additions & 0 deletions plugins/aws/workspaces/workspacesIpAccessControl.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
var expect = require("chai").expect;
var workspacesIpAccessControl = require("./workspacesIpAccessControl.js")


const errorWorkspaces = (statement) => {
return {workspaces:{
describeWorkspaces: {
"us-east-1":{
},
},
},
}
};

const noWorkspaces = (statement) => {
return {workspaces:{
describeWorkspaces: {
"us-east-1":{
data: []
},
},
},
}
};

const testWorkspaces = (statement) => {
return {workspaces:{
describeWorkspaces: {
"us-east-1":{
data: [
{
WorkspaceId: "test01",
DirectoryId: "d-01",
},
{
WorkspaceId: "test02",
DirectoryId: "d-02",
},
]
},
},
describeWorkspaceDirectories: {
"us-east-1":{
data:[
{
DirectoryId: "d-01",
DirectoryName: "corp.amazonworkspaces.com",
CustomerUserName: "Administrator",
ipGroupIds: [
"ipgroup01"
]
},
{
DirectoryId: "d-02",
DirectoryName: "corp.amazonworkspaces.com",
CustomerUserName: "Administrator",
ipGroupIds: [
"ipgroup02",
"ipgroup03"
]
}
]
}
},
describeIpGroups:{
"us-east-1":{
data: [
{
"groupId": "ipgroup01",
"groupName": "testIPControlAccess"
},
{
"groupId": "ipgroup02",
"groupName": "testIPControlAccess"
},
{
"groupId": "ipgroup03",
"groupName": "testIPControlAccess",
"userRules": [
{
"ipRule": "192.45.32.10",
"ruleDesc": "Open for one."
}
]
}
]
}
}
},
}
};

const testWorkspaces2 = (statement) => {
return {workspaces:{
describeWorkspaces: {
"us-east-1":{
data: [
{
WorkspaceId: "test01",
DirectoryId: "d-01",
},
{
WorkspaceId: "test02",
DirectoryId: "d-02",
},
]
},
},
describeWorkspaceDirectories: {
"us-east-1":{
data:[
{
DirectoryId: "d-01",
DirectoryName: "corp.amazonworkspaces.com",
CustomerUserName: "Administrator",
ipGroupIds: [
"ipgroup01"
]
},
{
DirectoryId: "d-02",
DirectoryName: "corp.amazonworkspaces.com",
CustomerUserName: "Administrator",
ipGroupIds: [
"ipgroup02"
]
}
]
}
},
describeIpGroups:{
"us-east-1":{
data: [
{
"groupId": "ipgroup01",
"groupName": "testIPControlAccess"
},
{
"groupId": "ipgroup02",
"groupName": "testIPControlAccess",
"userRules": [
{
"ipRule": "0.0.0.0/0",
"ruleDesc": "Open for all"
}
]
}
]
}
}
},
}
};


describe("workspacesIPAccessControl", function () {
describe("run", function () {
it("should give a general error if it can not get workspaces", function (done) {
const settings = {};
const cache = errorWorkspaces();
const callback = (err, results) => {
expect(results.length).to.equal(0)
};
workspacesIpAccessControl.run(cache, settings, callback);
done();
});

it("should give an output of no available workspaces", function (done) {
const settings = {};
const cache = noWorkspaces();

const callback = (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
};

workspacesIpAccessControl.run(cache, settings, callback);
done();
});

it("should give IP access controls on both the workspaces", function (done) {
const settings = {};
const cache = testWorkspaces();

const callback = (err, results) => {
expect(results.length).to.equal(2)
expect(results[0].status).to.equal(0);
expect(results[1].status).to.equal(0);
};

workspacesIpAccessControl.run(cache, settings, callback);
done();
})

it("should give IP access control enabled on one and no IP access control on the other", function (done) {
const settings = {};
const cache = testWorkspaces2();

const callback = (err, results) => {
expect(results.length).to.equal(2);
expect(results[0].status).to.equal(0);
expect(results[1].status).to.equal(2);
};


workspacesIpAccessControl.run(cache, settings, callback);
done();
})
})
})

0 comments on commit 955a4e3

Please sign in to comment.