-
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.
Added Google BigQuery Dataset All Users Policy plugin and test cases
- Loading branch information
1 parent
c652d8d
commit ccff1c9
Showing
6 changed files
with
217 additions
and
5 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
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,68 @@ | ||
var async = require('async'); | ||
var helpers = require('../../../helpers/google'); | ||
|
||
module.exports = { | ||
title: 'Dataset All Users Policy', | ||
category: 'BigQuery', | ||
description: 'Ensure that BigQuery datasets do not allow public read, write or delete access.', | ||
more_info: 'Granting permissions to allUsers or allAuthenticatedUsers allows anyone to access the dataset. Such access might not be desirable if sensitive data is being stored in the dataset.', | ||
link: 'https://cloud.google.com/bigquery/docs/dataset-access-controls', | ||
recommended_action: 'Ensure that each dataset is configured so that no member is set to allUsers or allAuthenticatedUsers.', | ||
apis: ['datasets:list', 'datasets:get'], | ||
|
||
run: function(cache, settings, callback) { | ||
var results = []; | ||
var source = {}; | ||
var regions = helpers.regions(); | ||
|
||
async.each(regions.datasets, function(region, rcb){ | ||
let datasetsGet = helpers.addSource(cache, source, | ||
['datasets', 'get', region]); | ||
|
||
if (!datasetsGet) return rcb(); | ||
|
||
if (datasetsGet.err || !datasetsGet.data) { | ||
helpers.addResult(results, 3, 'Unable to query BigQuery datasets: ' + helpers.addError(datasetsGet), region); | ||
return rcb(); | ||
} | ||
|
||
if (!datasetsGet.data.length) { | ||
helpers.addResult(results, 0, 'No BigQuery datasets found', region); | ||
return rcb(); | ||
} | ||
|
||
async.each(datasetsGet.data, (dataset, dcb) => { | ||
if (!dataset.id) return dcb(); | ||
|
||
var permissionStr = []; | ||
if (dataset.access) { | ||
for (let rolePermission of dataset.access) { | ||
for (let property in rolePermission) { | ||
if (!rolePermission['role']) continue; | ||
|
||
if (rolePermission[property].toLowerCase() == 'allusers' || rolePermission[property].toLowerCase() == 'allauthenticatedusers') { | ||
permissionStr.push(`${rolePermission['role']} access to ${rolePermission[property]}`); | ||
} | ||
} | ||
} | ||
|
||
if (permissionStr.length) { | ||
helpers.addResult(results, 2, | ||
`BigQuery dataset provides ${permissionStr.join(',')}`, region, dataset.id); | ||
} else { | ||
helpers.addResult(results, 0, | ||
'BigQuery dataset does not provide public access', region, dataset.id); | ||
} | ||
} else { | ||
helpers.addResult(results, 0, | ||
'BigQuery dataset does not provide public access', region, dataset.id); | ||
} | ||
}); | ||
|
||
rcb(); | ||
}, function(){ | ||
// Global checking goes here | ||
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,120 @@ | ||
var assert = require('assert'); | ||
var expect = require('chai').expect; | ||
var plugin = require('./datasetAllUsersPolicy'); | ||
|
||
const datasetGet = [ | ||
{ | ||
"kind": "bigquery#dataset", | ||
"id": "aqua-dev-cloudsploit:aqua_ds", | ||
"selfLink": "https://www.googleapis.com/bigquery/v2/projects/aqua-dev-cloudsploit/datasets/aqua_ds", | ||
"datasetReference": { "datasetId": "aqua_ds", "projectId": "aqua-dev-cloudploit" }, | ||
"access": [ | ||
{ "role": "WRITER", "specialGroup": "projectWriters" }, | ||
{ "role": "OWNER", "specialGroup": "projectOwners" }, | ||
{ "role": "READER", "specialGroup": "projectReaders" } | ||
], | ||
"creationTime": "1619622395743", | ||
"lastModifiedTime": "1619699668544", | ||
"location": "US", | ||
"type": "DEFAULT" | ||
}, | ||
{ | ||
"kind": "bigquery#dataset", | ||
"id": "aqua-dev-cloudsploit:aqua_ds", | ||
"selfLink": "https://www.googleapis.com/bigquery/v2/projects/aqua-dev-cloudsploit/datasets/aqua_ds", | ||
"datasetReference": { "datasetId": "aqua_ds", "projectId": "aqua-dev-cloudploit" }, | ||
"access": [ | ||
{ "role": "WRITER", "iamMember": "allUsers" }, | ||
{ "role": "WRITER", "specialGroup": "projectWriters" }, | ||
{ "role": "OWNER", "specialGroup": "projectOwners" }, | ||
{ "role": "READER", "specialGroup": "allAuthenticatedUsers" }, | ||
{ "role": "READER", "specialGroup": "projectReaders" } | ||
], | ||
"creationTime": "1619622395743", | ||
"lastModifiedTime": "1619699668544", | ||
"location": "US", | ||
"type": "DEFAULT" | ||
} | ||
]; | ||
|
||
const createCache = (err, data) => { | ||
return { | ||
datasets: { | ||
get: { | ||
'global': { | ||
err: err, | ||
data: data | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
|
||
describe('datasetAllUsersPolicy', function () { | ||
describe('run', function () { | ||
it('should give unknown result if unable to query BigQuery datasets', function (done) { | ||
const callback = (err, results) => { | ||
expect(results.length).to.be.above(0); | ||
expect(results[0].status).to.equal(3); | ||
expect(results[0].message).to.include('Unable to query BigQuery datasets'); | ||
expect(results[0].region).to.equal('global'); | ||
done() | ||
}; | ||
|
||
const cache = createCache( | ||
['error'], | ||
null, | ||
); | ||
|
||
plugin.run(cache, {}, callback); | ||
}); | ||
it('should give passing result if no datasets found', function (done) { | ||
const callback = (err, results) => { | ||
expect(results.length).to.be.above(0); | ||
expect(results[0].status).to.equal(0); | ||
expect(results[0].message).to.include('No BigQuery datasets found'); | ||
expect(results[0].region).to.equal('global'); | ||
done() | ||
}; | ||
|
||
const cache = createCache( | ||
null, | ||
[], | ||
); | ||
|
||
plugin.run(cache, {}, callback); | ||
}); | ||
it('should give passing result if BigQuery dataset does not provide public access', function (done) { | ||
const callback = (err, results) => { | ||
expect(results.length).to.be.above(0); | ||
expect(results[0].status).to.equal(0); | ||
expect(results[0].message).to.include('BigQuery dataset does not provide public access'); | ||
expect(results[0].region).to.equal('global'); | ||
done() | ||
}; | ||
|
||
const cache = createCache( | ||
null, | ||
[datasetGet[0]] | ||
); | ||
|
||
plugin.run(cache, {}, callback); | ||
}); | ||
it('should give failing result if BigQuery dataset provides public access', function (done) { | ||
const callback = (err, results) => { | ||
expect(results.length).to.be.above(0); | ||
expect(results[0].status).to.equal(2); | ||
expect(results[0].message).to.include('BigQuery dataset provides'); | ||
expect(results[0].region).to.equal('global'); | ||
done() | ||
}; | ||
|
||
const cache = createCache( | ||
null, | ||
[datasetGet[1]] | ||
); | ||
|
||
plugin.run(cache, {}, callback); | ||
}) | ||
}) | ||
}); |