diff --git a/collectors/aws/accessanalyzer/listFindings.js b/collectors/aws/accessanalyzer/listFindings.js index 10c9cb933b..965bb7cb98 100644 --- a/collectors/aws/accessanalyzer/listFindings.js +++ b/collectors/aws/accessanalyzer/listFindings.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var accessanalyzer = new AWS.AccessAnalyzer(AWSConfig); async.eachLimit(collection.accessanalyzer.listAnalyzers[AWSConfig.region].data, 15, function(analyzer, cb) { collection.accessanalyzer.listFindings[AWSConfig.region][analyzer.arn] = {}; @@ -36,9 +36,9 @@ module.exports = function(AWSConfig, collection, retries, callback) { var localParams = JSON.parse(JSON.stringify(params || {})); if (nextToken) localParams['nextToken'] = nextToken; if (nextToken) { - helpers.makeCustomCollectorCall(accessanalyzer, 'listFindings', localParams, retries, null, null, null, paginateCb); + helpers.makeCustomCollectorCall(accessanalyzer, 'listFindings', localParams, retries, null, null, null, settings, scanAWSConfig, AWSConfig, paginateCb); } else { - helpers.makeCustomCollectorCall(accessanalyzer, 'listFindings', params, retries, null, null, null, paginateCb); + helpers.makeCustomCollectorCall(accessanalyzer, 'listFindings', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, paginateCb); } } diff --git a/collectors/aws/accessanalyzer/listFindingsV2.js b/collectors/aws/accessanalyzer/listFindingsV2.js index 3f9240b56e..aa409117a8 100644 --- a/collectors/aws/accessanalyzer/listFindingsV2.js +++ b/collectors/aws/accessanalyzer/listFindingsV2.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var accessanalyzer = new AWS.AccessAnalyzer(AWSConfig); async.eachLimit(collection.accessanalyzer.listAnalyzers[AWSConfig.region].data, 15, function(analyzer, cb) { collection.accessanalyzer.listFindingsV2[AWSConfig.region][analyzer.arn] = {}; @@ -36,9 +36,9 @@ module.exports = function(AWSConfig, collection, retries, callback) { var localParams = JSON.parse(JSON.stringify(params || {})); if (nextToken) localParams['nextToken'] = nextToken; if (nextToken) { - helpers.makeCustomCollectorCall(accessanalyzer, 'listFindingsV2', localParams, retries, null, null, null, paginateCb); + helpers.makeCustomCollectorCall(accessanalyzer, 'listFindingsV2', localParams, retries, null, null, null, settings, scanAWSConfig, AWSConfig, paginateCb); } else { - helpers.makeCustomCollectorCall(accessanalyzer, 'listFindingsV2', params, retries, null, null, null, paginateCb); + helpers.makeCustomCollectorCall(accessanalyzer, 'listFindingsV2', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, paginateCb); } } diff --git a/collectors/aws/apigateway/getClientCertificate.js b/collectors/aws/apigateway/getClientCertificate.js index 7c68bcfb22..c5065213de 100644 --- a/collectors/aws/apigateway/getClientCertificate.js +++ b/collectors/aws/apigateway/getClientCertificate.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var apigateway = new AWS.APIGateway(AWSConfig); async.eachLimit(collection.apigateway.getRestApis[AWSConfig.region].data, 5, function(api, cb){ @@ -21,7 +21,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { clientCertificateId: stage.clientCertificateId }; - helpers.makeCustomCollectorCall(apigateway, 'getClientCertificate', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(apigateway, 'getClientCertificate', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.apigateway.getClientCertificate[AWSConfig.region][stage.clientCertificateId].err = err; return pCb(); diff --git a/collectors/aws/apigateway/getIntegration.js b/collectors/aws/apigateway/getIntegration.js index 9a4ce5ca39..efe48f8c4a 100644 --- a/collectors/aws/apigateway/getIntegration.js +++ b/collectors/aws/apigateway/getIntegration.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var apigateway = new AWS.APIGateway(AWSConfig); async.eachLimit(collection.apigateway.getRestApis[AWSConfig.region].data, 5, function(api, cb){ @@ -29,7 +29,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { restApiId : api.id, }; - helpers.makeCustomCollectorCall(apigateway, 'getIntegration', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(apigateway, 'getIntegration', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.apigateway.getIntegration[AWSConfig.region][api.id][resource.id][methodKey].err = err; return mCb(); diff --git a/collectors/aws/appmesh/describeVirtualGateway.js b/collectors/aws/appmesh/describeVirtualGateway.js index e6a55fd82c..77c64c3b53 100644 --- a/collectors/aws/appmesh/describeVirtualGateway.js +++ b/collectors/aws/appmesh/describeVirtualGateway.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var appmesh = new AWS.AppMesh(AWSConfig); if (!collection.appmesh || @@ -24,7 +24,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { async.eachLimit(collection.appmesh.listVirtualGateways[AWSConfig.region][mesh.meshName].data.virtualGateways, 3, function(gateway, pCb){ collection.appmesh.describeVirtualGateway[AWSConfig.region][gateway.virtualGatewayName] = {}; - helpers.makeCustomCollectorCall(appmesh, 'describeVirtualGateway', {virtualGatewayName: gateway.virtualGatewayName,meshName: mesh.meshName}, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(appmesh, 'describeVirtualGateway', {virtualGatewayName: gateway.virtualGatewayName,meshName: mesh.meshName}, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.appmesh.describeVirtualGateway[AWSConfig.region][gateway.virtualGatewayName].err = err; } diff --git a/collectors/aws/autoscaling/describeLaunchConfigurations.js b/collectors/aws/autoscaling/describeLaunchConfigurations.js index eb47515c0b..3beaab906c 100644 --- a/collectors/aws/autoscaling/describeLaunchConfigurations.js +++ b/collectors/aws/autoscaling/describeLaunchConfigurations.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var autoscaling = new AWS.AutoScaling(AWSConfig); async.eachLimit(collection.autoscaling.describeAutoScalingGroups[AWSConfig.region].data, 15, function(asg, cb){ @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'LaunchConfigurationNames': [asg.LaunchConfigurationName] }; - helpers.makeCustomCollectorCall(autoscaling, 'describeLaunchConfigurations', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(autoscaling, 'describeLaunchConfigurations', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.autoscaling.describeLaunchConfigurations[AWSConfig.region][asg.AutoScalingGroupARN].err = err; } diff --git a/collectors/aws/autoscaling/describeNotificationConfigurations.js b/collectors/aws/autoscaling/describeNotificationConfigurations.js index 34e4adcb6d..534b4ad6cc 100644 --- a/collectors/aws/autoscaling/describeNotificationConfigurations.js +++ b/collectors/aws/autoscaling/describeNotificationConfigurations.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var autoscaling = new AWS.AutoScaling(AWSConfig); async.eachLimit(collection.autoscaling.describeAutoScalingGroups[AWSConfig.region].data, 15, function(asg, cb){ @@ -10,7 +10,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'AutoScalingGroupNames':[asg.AutoScalingGroupName] }; - helpers.makeCustomCollectorCall(autoscaling, 'describeNotificationConfigurations', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(autoscaling, 'describeNotificationConfigurations', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { collection.autoscaling.describeNotificationConfigurations[AWSConfig.region][asg.AutoScalingGroupARN] = {}; if (err || !data) { collection.autoscaling.describeNotificationConfigurations[AWSConfig.region][asg.AutoScalingGroupARN].err = err; diff --git a/collectors/aws/cloudfront/getDistribution.js b/collectors/aws/cloudfront/getDistribution.js index f0f979c067..4ab1a2e921 100644 --- a/collectors/aws/cloudfront/getDistribution.js +++ b/collectors/aws/cloudfront/getDistribution.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var cloudfront = new AWS.CloudFront(AWSConfig); async.eachLimit(collection.cloudfront.listDistributions[AWSConfig.region].data, 15, function(distribution, cb){ @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'Id':distribution.Id }; - helpers.makeCustomCollectorCall(cloudfront, 'getDistribution', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(cloudfront, 'getDistribution', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.cloudfront.getDistribution[AWSConfig.region][distribution.Id].err = err; } diff --git a/collectors/aws/cloudtrail/listTags.js b/collectors/aws/cloudtrail/listTags.js index dc3c2cbc9e..2fdcf9239f 100644 --- a/collectors/aws/cloudtrail/listTags.js +++ b/collectors/aws/cloudtrail/listTags.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var cloudtrail = new AWS.CloudTrail(AWSConfig); async.eachLimit(collection.cloudtrail.describeTrails[AWSConfig.region].data, 15, function(trail, cb) { @@ -10,7 +10,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { ResourceIdList: [trail.TrailARN] }; - helpers.makeCustomCollectorCall(cloudtrail, 'listTags', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(cloudtrail, 'listTags', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { collection.cloudtrail.listTags[AWSConfig.region][trail.TrailARN] = {}; if (err || !data) { collection.cloudtrail.listTags[AWSConfig.region][trail.TrailARN].err = err; diff --git a/collectors/aws/cloudwatch/getEc2MetricStatistics.js b/collectors/aws/cloudwatch/getEc2MetricStatistics.js index 3742ea8762..1c896491e8 100644 --- a/collectors/aws/cloudwatch/getEc2MetricStatistics.js +++ b/collectors/aws/cloudwatch/getEc2MetricStatistics.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require('../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var cloudwatch = new AWS.CloudWatch(AWSConfig); async.eachLimit(collection.ec2.describeInstances[AWSConfig.region].data, 10, function(reservation, cb) { @@ -26,7 +26,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { ] }; - helpers.makeCustomCollectorCall(cloudwatch, 'getMetricStatistics', params,retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(cloudwatch, 'getMetricStatistics', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) collection.cloudwatch.getEc2MetricStatistics[AWSConfig.region][instance.InstanceId].err = err; if (data) collection.cloudwatch.getEc2MetricStatistics[AWSConfig.region][instance.InstanceId].data = data; }); diff --git a/collectors/aws/cloudwatch/getEcMetricStatistics.js b/collectors/aws/cloudwatch/getEcMetricStatistics.js index 5ecb621e26..2bfb12bdd7 100644 --- a/collectors/aws/cloudwatch/getEcMetricStatistics.js +++ b/collectors/aws/cloudwatch/getEcMetricStatistics.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var cloudwatch = new AWS.CloudWatch(AWSConfig); async.eachLimit(collection.elasticache.describeCacheClusters[AWSConfig.region].data, 10, function(cluster, cb){ @@ -25,7 +25,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { ] }; - helpers.makeCustomCollectorCall(cloudwatch, 'getMetricStatistics', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(cloudwatch, 'getMetricStatistics', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.cloudwatch.getEcMetricStatistics[AWSConfig.region][cluster.CacheClusterId].err = err; } diff --git a/collectors/aws/cloudwatch/getEsMetricStatistics.js b/collectors/aws/cloudwatch/getEsMetricStatistics.js index 559a3ee40a..08609c6ef7 100644 --- a/collectors/aws/cloudwatch/getEsMetricStatistics.js +++ b/collectors/aws/cloudwatch/getEsMetricStatistics.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var cloudwatch = new AWS.CloudWatch(AWSConfig); async.eachLimit(collection.opensearch.listDomainNames[AWSConfig.region].data, 10, function(domain, cb){ @@ -25,7 +25,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { ] }; - helpers.makeCustomCollectorCall(cloudwatch, 'getMetricStatistics', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(cloudwatch, 'getMetricStatistics', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.cloudwatch.getEsMetricStatistics[AWSConfig.region][domain.DomainName].err = err; } diff --git a/collectors/aws/cloudwatch/getRdsMetricStatistics.js b/collectors/aws/cloudwatch/getRdsMetricStatistics.js index afc81333a7..d724604061 100644 --- a/collectors/aws/cloudwatch/getRdsMetricStatistics.js +++ b/collectors/aws/cloudwatch/getRdsMetricStatistics.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var cloudwatch = new AWS.CloudWatch(AWSConfig); async.eachLimit(collection.rds.describeDBInstances[AWSConfig.region].data, 10, function(instance, cb){ @@ -25,7 +25,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { ] }; - helpers.makeCustomCollectorCall(cloudwatch, 'getMetricStatistics', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(cloudwatch, 'getMetricStatistics', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.cloudwatch.getRdsMetricStatistics[AWSConfig.region][instance.DBInstanceIdentifier].err = err; } diff --git a/collectors/aws/cloudwatch/getRdsReadIOPSMetricStatistics.js b/collectors/aws/cloudwatch/getRdsReadIOPSMetricStatistics.js index a080770755..82ec555d51 100644 --- a/collectors/aws/cloudwatch/getRdsReadIOPSMetricStatistics.js +++ b/collectors/aws/cloudwatch/getRdsReadIOPSMetricStatistics.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var cloudwatch = new AWS.CloudWatch(AWSConfig); async.eachLimit(collection.rds.describeDBInstances[AWSConfig.region].data, 10, function(instance, cb){ @@ -25,7 +25,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { ] }; - helpers.makeCustomCollectorCall(cloudwatch, 'getMetricStatistics', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(cloudwatch, 'getMetricStatistics', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.cloudwatch.getRdsReadIOPSMetricStatistics[AWSConfig.region][instance.DBInstanceIdentifier].err = err; } diff --git a/collectors/aws/cloudwatch/getRdsWriteIOPSMetricStatistics.js b/collectors/aws/cloudwatch/getRdsWriteIOPSMetricStatistics.js index 5f68bfecd0..4c5233acb8 100644 --- a/collectors/aws/cloudwatch/getRdsWriteIOPSMetricStatistics.js +++ b/collectors/aws/cloudwatch/getRdsWriteIOPSMetricStatistics.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var cloudwatch = new AWS.CloudWatch(AWSConfig); async.eachLimit(collection.rds.describeDBInstances[AWSConfig.region].data, 10, function(instance, cb){ @@ -25,7 +25,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { ] }; - helpers.makeCustomCollectorCall(cloudwatch, 'getMetricStatistics', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(cloudwatch, 'getMetricStatistics', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.cloudwatch.getRdsWriteIOPSMetricStatistics[AWSConfig.region][instance.DBInstanceIdentifier].err = err; } diff --git a/collectors/aws/cloudwatch/getredshiftMetricStatistics.js b/collectors/aws/cloudwatch/getredshiftMetricStatistics.js index 979f8543e6..6ae848cada 100644 --- a/collectors/aws/cloudwatch/getredshiftMetricStatistics.js +++ b/collectors/aws/cloudwatch/getredshiftMetricStatistics.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var cloudwatch = new AWS.CloudWatch(AWSConfig); async.eachLimit(collection.redshift.describeClusters[AWSConfig.region].data, 10, function(cluster, cb){ @@ -25,7 +25,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { ] }; - helpers.makeCustomCollectorCall(cloudwatch, 'getMetricStatistics', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(cloudwatch, 'getMetricStatistics', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.cloudwatch.getredshiftMetricStatistics[AWSConfig.region][cluster.ClusterIdentifier].err = err; } diff --git a/collectors/aws/codebuild/batchGetProjects.js b/collectors/aws/codebuild/batchGetProjects.js index e176ce5d76..b8d865c9ef 100644 --- a/collectors/aws/codebuild/batchGetProjects.js +++ b/collectors/aws/codebuild/batchGetProjects.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var codebuild = new AWS.CodeBuild(AWSConfig); async.eachLimit(collection.codebuild.listProjects[AWSConfig.region].data, 15, function(project, cb){ @@ -12,7 +12,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { names: [project], }; - helpers.makeCustomCollectorCall(codebuild, 'batchGetProjects', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(codebuild, 'batchGetProjects', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.codebuild.batchGetProjects[AWSConfig.region][project].err = err; } diff --git a/collectors/aws/collector.js b/collectors/aws/collector.js index 6f7fa7b99a..b6663bc136 100644 --- a/collectors/aws/collector.js +++ b/collectors/aws/collector.js @@ -126,7 +126,7 @@ var collect = function(AWSConfig, settings, callback) { LocalAWSConfig.region = region; if (callObj.override) { - collectors[serviceLower][callKey](LocalAWSConfig, collection, retries, function() { + collectors[serviceLower][callKey](LocalAWSConfig, collection, retries, settings, AWSConfig, function() { if (callObj.rateLimit) { setTimeout(function() { regionCb(); @@ -191,7 +191,14 @@ var collect = function(AWSConfig, settings, callback) { } }, function(cb) { executor[callKey](localParams, function(err, data) { - return cb(err, data); + helpers.refreshCredentialsIfTokenExpired(err, settings, AWSConfig, LocalAWSConfig, function(refreshErr, newCreds) { + if (!newCreds) { + if (refreshErr) console.log('[WARN] Token refresh failed'); + return cb(err, data); + } + var newExecutor = debugMode ? (AWSXRay.captureAWSClient(new AWS[serviceName](LocalAWSConfig))) : new AWS[serviceName](LocalAWSConfig); + newExecutor[callKey](localParams, cb); + }); }); }, function(err, data){ executorCb(err, data); @@ -215,7 +222,14 @@ var collect = function(AWSConfig, settings, callback) { } }, function(cb) { executor[callKey](function(err, data) { - return cb(err, data); + helpers.refreshCredentialsIfTokenExpired(err, settings, AWSConfig, LocalAWSConfig, function(refreshErr, newCreds) { + if (!newCreds) { + if (refreshErr) console.log('[WARN] Token refresh failed'); + return cb(err, data); + } + var newExecutor = debugMode ? (AWSXRay.captureAWSClient(new AWS[serviceName](LocalAWSConfig))) : new AWS[serviceName](LocalAWSConfig); + newExecutor[callKey](cb); + }); }); }, function(err, data){ executorCb(err, data); @@ -294,7 +308,7 @@ var collect = function(AWSConfig, settings, callback) { if (callObj.signatureVersion) LocalAWSConfig.signatureVersion = callObj.signatureVersion; if (callObj.override) { - collectors[serviceLower][callKey](LocalAWSConfig, collection, retries, function() { + collectors[serviceLower][callKey](LocalAWSConfig, collection, retries, settings, AWSConfig, function() { if (callObj.rateLimit) { setTimeout(function() { @@ -336,16 +350,32 @@ var collect = function(AWSConfig, settings, callback) { } }, function(cb) { executor[callKey](filter, function(err, data) { - if (helpers.collectRateError(err, rateError)) { - return cb(err); - } else if (err) { - collection[serviceLower][callKey][LocalAWSConfig.region][dep[callObj.filterValue]].err = err; - helpers.logError(serviceLower, callKey, region, err, errors, apiCallErrors, apiCallTypeErrors, totalApiCallErrors, errorSummary, errorTypeSummary, debugMode); - return cb(); - } else { - collection[serviceLower][callKey][LocalAWSConfig.region][dep[callObj.filterValue]].data = data; - return cb(); - } + helpers.refreshCredentialsIfTokenExpired(err, settings, AWSConfig, LocalAWSConfig, function(refreshErr, newCreds) { + // No new creds = either not token-expired, or refresh failed: handle original err/data (rate error, store err, or store data) + if (!newCreds) { + if (refreshErr) console.log('[WARN] Token refresh failed'); + if (helpers.collectRateError(err, rateError)) return cb(err); + if (err) { + collection[serviceLower][callKey][LocalAWSConfig.region][dep[callObj.filterValue]].err = err; + helpers.logError(serviceLower, callKey, region, err, errors, apiCallErrors, apiCallTypeErrors, totalApiCallErrors, errorSummary, errorTypeSummary, debugMode); + return cb(); + } + collection[serviceLower][callKey][LocalAWSConfig.region][dep[callObj.filterValue]].data = data; + return cb(); + } + + var newExecutor = debugMode ? (AWSXRay.captureAWSClient(new AWS[serviceName](LocalAWSConfig))) : new AWS[serviceName](LocalAWSConfig); + newExecutor[callKey](filter, function(retryErr, retryData) { + if (helpers.collectRateError(retryErr, rateError)) return cb(retryErr); + if (retryErr) { + collection[serviceLower][callKey][LocalAWSConfig.region][dep[callObj.filterValue]].err = retryErr; + helpers.logError(serviceLower, callKey, region, retryErr, errors, apiCallErrors, apiCallTypeErrors, totalApiCallErrors, errorSummary, errorTypeSummary, debugMode); + return cb(); + } + collection[serviceLower][callKey][LocalAWSConfig.region][dep[callObj.filterValue]].data = retryData; + return cb(); + }); + }); }); }, function(){ diff --git a/collectors/aws/collector_multipart.js b/collectors/aws/collector_multipart.js index e9960d4aee..4cf57026fa 100644 --- a/collectors/aws/collector_multipart.js +++ b/collectors/aws/collector_multipart.js @@ -155,7 +155,7 @@ var collect = function(AWSConfig, settings, callback) { LocalAWSConfig.region = region; if (callObj.override) { - collectors[serviceLower][callKey](LocalAWSConfig, collection, retries, function() { + collectors[serviceLower][callKey](LocalAWSConfig, collection, retries, settings, AWSConfig, function() { if (callObj.rateLimit) { setTimeout(function() { regionCb(); @@ -334,7 +334,7 @@ var collect = function(AWSConfig, settings, callback) { if (callObj.signatureVersion) LocalAWSConfig.signatureVersion = callObj.signatureVersion; if (callObj.override) { - collectors[serviceLower][callKey](LocalAWSConfig, collection, retries, function() { + collectors[serviceLower][callKey](LocalAWSConfig, collection, retries, settings, AWSConfig, function() { if (callObj.rateLimit) { setTimeout(function() { diff --git a/collectors/aws/connect/instanceAttachmentStorageConfigs.js b/collectors/aws/connect/instanceAttachmentStorageConfigs.js index 3d147ab582..1e8c9915a8 100644 --- a/collectors/aws/connect/instanceAttachmentStorageConfigs.js +++ b/collectors/aws/connect/instanceAttachmentStorageConfigs.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var connect = new AWS.Connect(AWSConfig); async.eachLimit(collection.connect.listInstances[AWSConfig.region].data, 15, function(instance, cb){ @@ -12,7 +12,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'ResourceType': 'ATTACHMENTS' }; - helpers.makeCustomCollectorCall(connect, 'listInstanceStorageConfigs', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(connect, 'listInstanceStorageConfigs', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.connect.instanceAttachmentStorageConfigs[AWSConfig.region][instance.Id].err = err; } diff --git a/collectors/aws/connect/listInstanceCallRecordingStorageConfigs.js b/collectors/aws/connect/listInstanceCallRecordingStorageConfigs.js index 11bd731010..4a3d112581 100644 --- a/collectors/aws/connect/listInstanceCallRecordingStorageConfigs.js +++ b/collectors/aws/connect/listInstanceCallRecordingStorageConfigs.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var connect = new AWS.Connect(AWSConfig); async.eachLimit(collection.connect.listInstances[AWSConfig.region].data, 15, function(instance, cb){ @@ -12,7 +12,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'ResourceType': 'CALL_RECORDINGS' }; - helpers.makeCustomCollectorCall(connect, 'listInstanceStorageConfigs', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(connect, 'listInstanceStorageConfigs', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.connect.listInstanceCallRecordingStorageConfigs[AWSConfig.region][instance.Id].err = err; } diff --git a/collectors/aws/connect/listInstanceChatTranscriptStorageConfigs.js b/collectors/aws/connect/listInstanceChatTranscriptStorageConfigs.js index b65aafe668..3d8cfef146 100644 --- a/collectors/aws/connect/listInstanceChatTranscriptStorageConfigs.js +++ b/collectors/aws/connect/listInstanceChatTranscriptStorageConfigs.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var connect = new AWS.Connect(AWSConfig); async.eachLimit(collection.connect.listInstances[AWSConfig.region].data, 15, function(instance, cb){ @@ -12,7 +12,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'ResourceType': 'CHAT_TRANSCRIPTS' }; - helpers.makeCustomCollectorCall(connect, 'listInstanceStorageConfigs', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(connect, 'listInstanceStorageConfigs', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.connect.listInstanceChatTranscriptStorageConfigs[AWSConfig.region][instance.Id].err = err; } diff --git a/collectors/aws/connect/listInstanceExportedReportStorageConfigs.js b/collectors/aws/connect/listInstanceExportedReportStorageConfigs.js index 851b7ddf9a..170b301d2d 100644 --- a/collectors/aws/connect/listInstanceExportedReportStorageConfigs.js +++ b/collectors/aws/connect/listInstanceExportedReportStorageConfigs.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var connect = new AWS.Connect(AWSConfig); async.eachLimit(collection.connect.listInstances[AWSConfig.region].data, 15, function(instance, cb){ @@ -12,7 +12,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'ResourceType': 'SCHEDULED_REPORTS' }; - helpers.makeCustomCollectorCall(connect, 'listInstanceStorageConfigs', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(connect, 'listInstanceStorageConfigs', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.connect.listInstanceExportedReportStorageConfigs[AWSConfig.region][instance.Id].err = err; } diff --git a/collectors/aws/connect/listInstanceMediaStreamStorageConfigs.js b/collectors/aws/connect/listInstanceMediaStreamStorageConfigs.js index 4873a4ebe2..210b749924 100644 --- a/collectors/aws/connect/listInstanceMediaStreamStorageConfigs.js +++ b/collectors/aws/connect/listInstanceMediaStreamStorageConfigs.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var connect = new AWS.Connect(AWSConfig); async.eachLimit(collection.connect.listInstances[AWSConfig.region].data, 15, function(instance, cb){ @@ -12,7 +12,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'ResourceType': 'MEDIA_STREAMS' }; - helpers.makeCustomCollectorCall(connect, 'listInstanceStorageConfigs', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(connect, 'listInstanceStorageConfigs', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.connect.listInstanceMediaStreamStorageConfigs[AWSConfig.region][instance.Id].err = err; } diff --git a/collectors/aws/dynamodb/describeContinuousBackups.js b/collectors/aws/dynamodb/describeContinuousBackups.js index d7884b6b22..0482a76fda 100644 --- a/collectors/aws/dynamodb/describeContinuousBackups.js +++ b/collectors/aws/dynamodb/describeContinuousBackups.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var dynamodb = new AWS.DynamoDB(AWSConfig); async.eachLimit(collection.dynamodb.listTables[AWSConfig.region].data, 15, function(table, cb){ @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'TableName': table }; - helpers.makeCustomCollectorCall(dynamodb, 'describeContinuousBackups', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(dynamodb, 'describeContinuousBackups', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.dynamodb.describeContinuousBackups[AWSConfig.region][table].err = err; } diff --git a/collectors/aws/dynamodb/describeTable.js b/collectors/aws/dynamodb/describeTable.js index c6ab50676c..d44430017e 100644 --- a/collectors/aws/dynamodb/describeTable.js +++ b/collectors/aws/dynamodb/describeTable.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var dynamodb = new AWS.DynamoDB(AWSConfig); async.eachLimit(collection.dynamodb.listTables[AWSConfig.region].data, 15, function(table, cb){ @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'TableName': table }; - helpers.makeCustomCollectorCall(dynamodb, 'describeTable', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(dynamodb, 'describeTable', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.dynamodb.describeTable[AWSConfig.region][table].err = err; } diff --git a/collectors/aws/dynamodb/listBackups.js b/collectors/aws/dynamodb/listBackups.js index dd4138ed69..09e8762e0a 100644 --- a/collectors/aws/dynamodb/listBackups.js +++ b/collectors/aws/dynamodb/listBackups.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var dynamodb = new AWS.DynamoDB(AWSConfig); async.eachLimit(collection.dynamodb.listTables[AWSConfig.region].data, 15, function(table, cb){ @@ -14,7 +14,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { }; - helpers.makeCustomCollectorCall(dynamodb, 'listBackups', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(dynamodb, 'listBackups', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.dynamodb.listBackups[AWSConfig.region][table].err = err; } diff --git a/collectors/aws/ec2/describeAddresses.js b/collectors/aws/ec2/describeAddresses.js new file mode 100644 index 0000000000..5e98037b71 --- /dev/null +++ b/collectors/aws/ec2/describeAddresses.js @@ -0,0 +1,69 @@ +var async = require('async'); +var { EC2Client, DescribeAddressesCommand } = require('@aws-sdk/client-ec2'); +var helpers = require(__dirname + '/../../../helpers/aws'); + +var rateError = { message: 'rate', statusCode: 429 }; +var apiRetryAttempts = 2; +var apiRetryCap = 1000; +var apiRetryBackoff = 500; + +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { + + var ec2Client = new EC2Client(helpers.buildV3ClientConfig(AWSConfig)); + var params = {}; + + function runOnce(cb) { + var command = new DescribeAddressesCommand(params); + ec2Client.send(command).then(function(data) { + return cb(null, data); + }).catch(function(err) { + helpers.refreshCredentialsIfTokenExpired(err, settings, scanAWSConfig, AWSConfig, function(refreshErr, newCreds) { + if (!newCreds) { + if (refreshErr) console.log('[WARN] Token refresh failed'); + return cb(err, null); + } + try { + ec2Client = new EC2Client(helpers.buildV3ClientConfig(AWSConfig)); + } catch (e) { + return cb(err, null); + } + var retryCommand = new DescribeAddressesCommand(params); + ec2Client.send(retryCommand).then(function(data) { + return cb(null, data); + }).catch(function(retryErr) { + return cb(retryErr, null); + }); + }); + }); + } + + async.retry({ + times: apiRetryAttempts, + interval: function(retryCount) { + let retryExponential = 3; + let retryLeveler = 3; + let timestamp = parseInt(((new Date()).getTime()).toString().slice(-1)); + let retry_temp = Math.min(apiRetryCap, (apiRetryBackoff * (retryExponential + timestamp) ** retryCount)); + let retry_seconds = Math.round(retry_temp / retryLeveler + Math.random(0, retry_temp) * 5000); + + console.log(`Trying DescribeAddressesCommand again in: ${retry_seconds / 1000} seconds`); + retries.push({ seconds: Math.round(retry_seconds / 1000) }); + return retry_seconds; + }, + errorFilter: function(err) { + return helpers.collectRateError(err, rateError); + } + }, function(cb) { + runOnce(cb); + }, function(err, data) { + if (err) { + collection.ec2.describeAddresses[AWSConfig.region].err = err; + } else if (data) { + collection.ec2.describeAddresses[AWSConfig.region].data = data.Addresses || []; + } else if (!collection.ec2.describeAddresses[AWSConfig.region].data) { + collection.ec2.describeAddresses[AWSConfig.region].data = []; + } + + callback(); + }); +}; diff --git a/collectors/aws/ec2/describeSnapshotAttribute.js b/collectors/aws/ec2/describeSnapshotAttribute.js index 8439c61db1..a2fae7f641 100644 --- a/collectors/aws/ec2/describeSnapshotAttribute.js +++ b/collectors/aws/ec2/describeSnapshotAttribute.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var ec2 = new AWS.EC2(AWSConfig); async.eachLimit(collection.ec2.describeSnapshots[AWSConfig.region].data, 20, function(snapshot, cb){ @@ -12,7 +12,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { SnapshotId: snapshot.SnapshotId }; - helpers.makeCustomCollectorCall(ec2, 'describeSnapshotAttribute', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(ec2, 'describeSnapshotAttribute', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.ec2.describeSnapshotAttribute[AWSConfig.region][snapshot.SnapshotId].err = err; } diff --git a/collectors/aws/ec2/describeSnapshots.js b/collectors/aws/ec2/describeSnapshots.js index 11a65e4862..47b7ecae79 100644 --- a/collectors/aws/ec2/describeSnapshots.js +++ b/collectors/aws/ec2/describeSnapshots.js @@ -5,7 +5,7 @@ var helpers = require(__dirname + '/../../../helpers/aws'); // default call retrieves every snapshot // available, including public ones -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var ec2 = new AWS.EC2(AWSConfig); var sts = new AWS.STS(AWSConfig); var paginating = false; @@ -13,7 +13,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { var createdTime = new Date(); createdTime.setDate(createdTime.getDate() - 30); - helpers.makeCustomCollectorCall(sts, 'getCallerIdentity', {}, retries, null, null, null, function(stsErr, stsData) { + helpers.makeCustomCollectorCall(sts, 'getCallerIdentity', {}, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(stsErr, stsData) { if (stsErr || !stsData.Account) { collection.ec2.describeSnapshots[AWSConfig.region].err = 'Unable to filter by owner ID'; return callback(); @@ -68,9 +68,9 @@ module.exports = function(AWSConfig, collection, retries, callback) { var localParams = JSON.parse(JSON.stringify(params || {})); if (nextToken) localParams['NextToken'] = nextToken; if (nextToken) { - helpers.makeCustomCollectorCall(ec2, 'describeSnapshots', localParams, retries, null, null, null, paginateCb); + helpers.makeCustomCollectorCall(ec2, 'describeSnapshots', localParams, retries, null, null, null, settings, scanAWSConfig, AWSConfig, paginateCb); } else { - helpers.makeCustomCollectorCall(ec2, 'describeSnapshots', params, retries, null, null, null, paginateCb); + helpers.makeCustomCollectorCall(ec2, 'describeSnapshots', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, paginateCb); } } execute(); diff --git a/collectors/aws/ec2/describeSubnets.js b/collectors/aws/ec2/describeSubnets.js index 0ecc6857c3..b28f897003 100644 --- a/collectors/aws/ec2/describeSubnets.js +++ b/collectors/aws/ec2/describeSubnets.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var ec2 = new AWS.EC2(AWSConfig); async.eachLimit(collection.ec2.describeVpcs[AWSConfig.region].data, 15, function(vpc, cb){ @@ -20,7 +20,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { ] }; - helpers.makeCustomCollectorCall(ec2, 'describeSubnets', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(ec2, 'describeSubnets', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.ec2.describeSubnets[AWSConfig.region][vpc.VpcId].err = err; } diff --git a/collectors/aws/ecs/describeCluster.js b/collectors/aws/ecs/describeCluster.js index a539683097..8010250c0f 100644 --- a/collectors/aws/ecs/describeCluster.js +++ b/collectors/aws/ecs/describeCluster.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var ecs = new AWS.ECS(AWSConfig); async.eachLimit(collection.ecs.listClusters[AWSConfig.region].data, 10, function(cluster, cb){ @@ -14,7 +14,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'include': ['SETTINGS'] }; - helpers.makeCustomCollectorCall(ecs, 'describeClusters', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(ecs, 'describeClusters', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.ecs.describeCluster[AWSConfig.region][cluster].err = err; } diff --git a/collectors/aws/ecs/describeContainerInstances.js b/collectors/aws/ecs/describeContainerInstances.js index a03285a20a..54549ff8a2 100644 --- a/collectors/aws/ecs/describeContainerInstances.js +++ b/collectors/aws/ecs/describeContainerInstances.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var ecs = new AWS.ECS(AWSConfig); async.eachOfLimit(collection.ecs.listContainerInstances[AWSConfig.region], 10, function(containerInstanceData,instance, cb){ @@ -17,7 +17,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { cluster : clusterName, };collection.ecs.describeContainerInstances[AWSConfig.region][containerInstance] = {}; - helpers.makeCustomCollectorCall(ecs, 'describeContainerInstances', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(ecs, 'describeContainerInstances', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.ecs.describeContainerInstances[AWSConfig.region][containerInstance].err = err; } diff --git a/collectors/aws/ecs/describeServices.js b/collectors/aws/ecs/describeServices.js index 87fa1d7034..57998d393a 100644 --- a/collectors/aws/ecs/describeServices.js +++ b/collectors/aws/ecs/describeServices.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var ecs = new AWS.ECS(AWSConfig); async.eachOfLimit(collection.ecs.listServices[AWSConfig.region], 10, function(servicesData,instance, cb){ @@ -17,7 +17,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { cluster : clusterName, }; - helpers.makeCustomCollectorCall(ecs, 'describeServices', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(ecs, 'describeServices', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.ecs.describeServices[AWSConfig.region][service].err = err; } diff --git a/collectors/aws/ecs/describeTasks.js b/collectors/aws/ecs/describeTasks.js index fad0738b3a..c372340753 100644 --- a/collectors/aws/ecs/describeTasks.js +++ b/collectors/aws/ecs/describeTasks.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var ecs = new AWS.ECS(AWSConfig); async.eachOfLimit(collection.ecs.listTasks[AWSConfig.region], 10, function(tasksData,instance, cb){ @@ -17,7 +17,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { cluster : clusterName, }; - helpers.makeCustomCollectorCall(ecs, 'describeTasks', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(ecs, 'describeTasks', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.ecs.describeTasks[AWSConfig.region][task].err = err; } diff --git a/collectors/aws/ecs/listContainerInstances.js b/collectors/aws/ecs/listContainerInstances.js index c7b9eb175e..5316d95aa7 100644 --- a/collectors/aws/ecs/listContainerInstances.js +++ b/collectors/aws/ecs/listContainerInstances.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var ecs = new AWS.ECS(AWSConfig); async.eachLimit(collection.ecs.listClusters[AWSConfig.region].data, 10, function(cluster, cb){ @@ -13,7 +13,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { cluster: cluster }; - helpers.makeCustomCollectorCall(ecs, 'listContainerInstances', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(ecs, 'listContainerInstances', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.ecs.listContainerInstances[AWSConfig.region][cluster].err = err; } else if (data && data.containerInstanceArns) { diff --git a/collectors/aws/ecs/listServices.js b/collectors/aws/ecs/listServices.js index 4898290ad1..74be653672 100644 --- a/collectors/aws/ecs/listServices.js +++ b/collectors/aws/ecs/listServices.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var ecs = new AWS.ECS(AWSConfig); async.eachLimit(collection.ecs.listClusters[AWSConfig.region].data, 10, function(cluster, cb){ @@ -15,7 +15,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { cluster: clusterName }; - helpers.makeCustomCollectorCall(ecs, 'listServices', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(ecs, 'listServices', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.ecs.listServices[AWSConfig.region][cluster].err = err; } diff --git a/collectors/aws/ecs/listTasks.js b/collectors/aws/ecs/listTasks.js index 082cad3ec9..4623902dc1 100644 --- a/collectors/aws/ecs/listTasks.js +++ b/collectors/aws/ecs/listTasks.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var ecs = new AWS.ECS(AWSConfig); async.eachLimit(collection.ecs.listClusters[AWSConfig.region].data, 10, function(cluster, cb){ @@ -15,7 +15,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { cluster: clusterName }; - helpers.makeCustomCollectorCall(ecs, 'listTasks', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(ecs, 'listTasks', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.ecs.listTasks[AWSConfig.region][cluster].err = err; } else if (data && data.taskArns) { diff --git a/collectors/aws/eks/describeCluster.js b/collectors/aws/eks/describeCluster.js index e5e485badc..6441747c73 100644 --- a/collectors/aws/eks/describeCluster.js +++ b/collectors/aws/eks/describeCluster.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var eks = new AWS.EKS(AWSConfig); async.eachLimit(collection.eks.listClusters[AWSConfig.region].data, 10, function(cluster, cb){ @@ -13,7 +13,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { name: cluster }; - helpers.makeCustomCollectorCall(eks, 'describeCluster', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(eks, 'describeCluster', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) collection.eks.describeCluster[AWSConfig.region][cluster].err = err; if (data) collection.eks.describeCluster[AWSConfig.region][cluster].data = data; diff --git a/collectors/aws/eks/describeNodegroups.js b/collectors/aws/eks/describeNodegroups.js index bba92226ef..8267a29bf7 100644 --- a/collectors/aws/eks/describeNodegroups.js +++ b/collectors/aws/eks/describeNodegroups.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var eks = new AWS.EKS(AWSConfig); //var autoscaling = new AWS.AutoScaling(AWSConfig); @@ -16,7 +16,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { nodegroupName: nodeGroup }; - helpers.makeCustomCollectorCall(eks, 'describeNodegroup', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(eks, 'describeNodegroup', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) collection.eks.describeNodegroups[AWSConfig.region][cluster][nodeGroup].err = err; //var autoScalingGroupNames = []; if (data) collection.eks.describeNodegroups[AWSConfig.region][cluster][nodeGroup].data = data.nodegroup; diff --git a/collectors/aws/eks/listNodegroups.js b/collectors/aws/eks/listNodegroups.js index 3679225bfb..c1901a228b 100644 --- a/collectors/aws/eks/listNodegroups.js +++ b/collectors/aws/eks/listNodegroups.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var eks = new AWS.EKS(AWSConfig); async.eachLimit(collection.eks.listClusters[AWSConfig.region].data, 10, function(cluster, cb){ @@ -13,7 +13,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { clusterName: cluster }; - helpers.makeCustomCollectorCall(eks, 'listNodegroups', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(eks, 'listNodegroups', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) collection.eks.listNodegroups[AWSConfig.region][cluster].err = err; if (data) collection.eks.listNodegroups[AWSConfig.region][cluster].data = data.nodegroups; diff --git a/collectors/aws/elasticache/describeCacheSubnetGroups.js b/collectors/aws/elasticache/describeCacheSubnetGroups.js index 41736b4956..c27a51c348 100644 --- a/collectors/aws/elasticache/describeCacheSubnetGroups.js +++ b/collectors/aws/elasticache/describeCacheSubnetGroups.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var elasticache = new AWS.ElastiCache(AWSConfig); async.eachLimit(collection.elasticache.describeCacheClusters[AWSConfig.region].data, 15, function(cluster, cb){ @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { CacheSubnetGroupName: cluster.CacheSubnetGroupName }; - helpers.makeCustomCollectorCall(elasticache, 'describeCacheSubnetGroups', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(elasticache, 'describeCacheSubnetGroups', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.elasticache.describeCacheSubnetGroups[AWSConfig.region][cluster.CacheSubnetGroupName].err = err; } diff --git a/collectors/aws/elasticbeanstalk/describeConfigurationSettings.js b/collectors/aws/elasticbeanstalk/describeConfigurationSettings.js index 287476cd50..4b01885e07 100644 --- a/collectors/aws/elasticbeanstalk/describeConfigurationSettings.js +++ b/collectors/aws/elasticbeanstalk/describeConfigurationSettings.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var elasticbeanstalk = new AWS.ElasticBeanstalk(AWSConfig); async.eachLimit(collection.elasticbeanstalk.describeEnvironments[AWSConfig.region].data, 15, function(environment, cb) { @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { EnvironmentName: environment.EnvironmentName }; - helpers.makeCustomCollectorCall(elasticbeanstalk, 'describeConfigurationSettings', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(elasticbeanstalk, 'describeConfigurationSettings', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { collection.elasticbeanstalk.describeConfigurationSettings[AWSConfig.region][environment.EnvironmentArn] = {}; if (err || !data) { collection.elasticbeanstalk.describeConfigurationSettings[AWSConfig.region][environment.EnvironmentArn].err = err; diff --git a/collectors/aws/elb/describeInstanceHealth.js b/collectors/aws/elb/describeInstanceHealth.js index d7bfa57ebd..63c2144447 100644 --- a/collectors/aws/elb/describeInstanceHealth.js +++ b/collectors/aws/elb/describeInstanceHealth.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var elb = new AWS.ELB(AWSConfig); async.eachLimit(collection.elb.describeLoadBalancers[AWSConfig.region].data, 15, function(lb, cb){ @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'LoadBalancerName':lb.LoadBalancerName }; - helpers.makeCustomCollectorCall(elb, 'describeInstanceHealth', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(elb, 'describeInstanceHealth', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.elb.describeInstanceHealth[AWSConfig.region][lb.DNSName].err = err; } diff --git a/collectors/aws/elb/describeLoadBalancerAttributes.js b/collectors/aws/elb/describeLoadBalancerAttributes.js index 282ee9ef2b..c5256def6b 100644 --- a/collectors/aws/elb/describeLoadBalancerAttributes.js +++ b/collectors/aws/elb/describeLoadBalancerAttributes.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var elb = new AWS.ELB(AWSConfig); async.eachLimit(collection.elb.describeLoadBalancers[AWSConfig.region].data, 15, function(lb, cb){ @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'LoadBalancerName':lb.LoadBalancerName }; - helpers.makeCustomCollectorCall(elb, 'describeLoadBalancerAttributes', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(elb, 'describeLoadBalancerAttributes', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.elb.describeLoadBalancerAttributes[AWSConfig.region][lb.DNSName].err = err; } diff --git a/collectors/aws/elb/describeLoadBalancerPolicies.js b/collectors/aws/elb/describeLoadBalancerPolicies.js index e0c70dc934..caea948a56 100644 --- a/collectors/aws/elb/describeLoadBalancerPolicies.js +++ b/collectors/aws/elb/describeLoadBalancerPolicies.js @@ -4,7 +4,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var elb = new AWS.ELB(AWSConfig); // Gather list of policies from load balancers @@ -47,7 +47,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { PolicyNames: policy.PolicyNames }; - helpers.makeCustomCollectorCall(elb, 'describeLoadBalancerPolicies', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(elb, 'describeLoadBalancerPolicies', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.elb.describeLoadBalancerPolicies[AWSConfig.region][policy.DNSName].err = err; } else if (data) { diff --git a/collectors/aws/elb/describeTags.js b/collectors/aws/elb/describeTags.js index d673d44d4e..25d09a6ffb 100644 --- a/collectors/aws/elb/describeTags.js +++ b/collectors/aws/elb/describeTags.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var elb = new AWS.ELB(AWSConfig); async.eachLimit(collection.elb.describeLoadBalancers[AWSConfig.region].data, 15, function(lb, cb){ @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'LoadBalancerNames': [lb.LoadBalancerName] }; - helpers.makeCustomCollectorCall(elb, 'describeTags', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(elb, 'describeTags', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.elb.describeTags[AWSConfig.region][lb.LoadBalancerName].err = err; } diff --git a/collectors/aws/elbv2/describeListeners.js b/collectors/aws/elbv2/describeListeners.js index 794a1fd53c..b4dfadcd14 100644 --- a/collectors/aws/elbv2/describeListeners.js +++ b/collectors/aws/elbv2/describeListeners.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var elb = new AWS.ELBv2(AWSConfig); async.eachLimit(collection.elbv2.describeLoadBalancers[AWSConfig.region].data, 15, function(lb, cb){ @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'LoadBalancerArn':lb.LoadBalancerArn }; - helpers.makeCustomCollectorCall(elb, 'describeListeners', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(elb, 'describeListeners', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.elbv2.describeListeners[AWSConfig.region][lb.DNSName].err = err; } diff --git a/collectors/aws/elbv2/describeLoadBalancerAttributes.js b/collectors/aws/elbv2/describeLoadBalancerAttributes.js index 0e36f521a1..a29562f74d 100644 --- a/collectors/aws/elbv2/describeLoadBalancerAttributes.js +++ b/collectors/aws/elbv2/describeLoadBalancerAttributes.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var elb = new AWS.ELBv2(AWSConfig); async.eachLimit(collection.elbv2.describeLoadBalancers[AWSConfig.region].data, 15, function(lb, cb){ @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'LoadBalancerArn':lb.LoadBalancerArn }; - helpers.makeCustomCollectorCall(elb, 'describeLoadBalancerAttributes', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(elb, 'describeLoadBalancerAttributes', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.elbv2.describeLoadBalancerAttributes[AWSConfig.region][lb.DNSName].err = err; } diff --git a/collectors/aws/elbv2/describeTags.js b/collectors/aws/elbv2/describeTags.js index cb41af06d0..b01f3842ee 100644 --- a/collectors/aws/elbv2/describeTags.js +++ b/collectors/aws/elbv2/describeTags.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var elb = new AWS.ELBv2(AWSConfig); async.eachLimit(collection.elbv2.describeLoadBalancers[AWSConfig.region].data, 15, function(lb, cb){ @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'ResourceArns': [lb.LoadBalancerArn] }; - helpers.makeCustomCollectorCall(elb, 'describeTags', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(elb, 'describeTags', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.elbv2.describeTags[AWSConfig.region][lb.DNSName].err = err; } diff --git a/collectors/aws/elbv2/describeTargetGroups.js b/collectors/aws/elbv2/describeTargetGroups.js index 410b9a9ff7..775e143bdd 100644 --- a/collectors/aws/elbv2/describeTargetGroups.js +++ b/collectors/aws/elbv2/describeTargetGroups.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var elb = new AWS.ELBv2(AWSConfig); async.eachLimit(collection.elbv2.describeLoadBalancers[AWSConfig.region].data, 15, function(lb, cb){ @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'LoadBalancerArn':lb.LoadBalancerArn }; - helpers.makeCustomCollectorCall(elb, 'describeTargetGroups', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(elb, 'describeTargetGroups', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.elbv2.describeTargetGroups[AWSConfig.region][lb.DNSName].err = err; } diff --git a/collectors/aws/emr/describeSecurityConfiguration.js b/collectors/aws/emr/describeSecurityConfiguration.js index f919eb8da8..e31dd1b2b7 100644 --- a/collectors/aws/emr/describeSecurityConfiguration.js +++ b/collectors/aws/emr/describeSecurityConfiguration.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var emr = new AWS.EMR(AWSConfig); async.eachLimit(collection.emr.listClusters[AWSConfig.region].data, 15, function(cluster, cb){ @@ -22,7 +22,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'Name': securityConfigurationName }; - helpers.makeCustomCollectorCall(emr, 'describeSecurityConfiguration', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(emr, 'describeSecurityConfiguration', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.emr.describeSecurityConfiguration[AWSConfig.region][securityConfigurationName].err = err; } diff --git a/collectors/aws/firehose/describeDeliveryStream.js b/collectors/aws/firehose/describeDeliveryStream.js index abebc7e57f..16d16a911a 100644 --- a/collectors/aws/firehose/describeDeliveryStream.js +++ b/collectors/aws/firehose/describeDeliveryStream.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var firehose = new AWS.Firehose(AWSConfig); async.eachLimit(collection.firehose.listDeliveryStreams[AWSConfig.region].data, 15, function(deliverystream, cb){ @@ -12,7 +12,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { DeliveryStreamName: deliverystream }; - helpers.makeCustomCollectorCall(firehose, 'describeDeliveryStream', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(firehose, 'describeDeliveryStream', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.firehose.describeDeliveryStream[AWSConfig.region][deliverystream].err = err; } diff --git a/collectors/aws/guardduty/describePublishingDestination.js b/collectors/aws/guardduty/describePublishingDestination.js index 897608ef16..dcecebc862 100644 --- a/collectors/aws/guardduty/describePublishingDestination.js +++ b/collectors/aws/guardduty/describePublishingDestination.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var guardduty = new AWS.GuardDuty(AWSConfig); if (!collection.guardduty || @@ -26,7 +26,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { collection.guardduty.describePublishingDestination[AWSConfig.region][destination.DestinationId] = {}; // Make the describe destinations call - helpers.makeCustomCollectorCall(guardduty, 'describePublishingDestination', {DestinationId: destination.DestinationId, DetectorId: detectorId}, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(guardduty, 'describePublishingDestination', {DestinationId: destination.DestinationId, DetectorId: detectorId}, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.guardduty.describePublishingDestination[AWSConfig.region][destination.DestinationId].err = err; } diff --git a/collectors/aws/guardduty/getDetector.js b/collectors/aws/guardduty/getDetector.js index b04b7c3d71..e2f69fe448 100644 --- a/collectors/aws/guardduty/getDetector.js +++ b/collectors/aws/guardduty/getDetector.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var guardduty = new AWS.GuardDuty(AWSConfig); async.eachLimit(collection.guardduty.listDetectors[AWSConfig.region].data, 15, function(detectorId, cb) { collection.guardduty.getDetector[AWSConfig.region][detectorId] = {}; @@ -10,7 +10,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'DetectorId': detectorId }; - helpers.makeCustomCollectorCall(guardduty, 'getDetector', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(guardduty, 'getDetector', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.guardduty.getDetector[AWSConfig.region][detectorId].err = err; } diff --git a/collectors/aws/guardduty/getFindings.js b/collectors/aws/guardduty/getFindings.js index 26132a0fa7..5576b18d7a 100644 --- a/collectors/aws/guardduty/getFindings.js +++ b/collectors/aws/guardduty/getFindings.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var guardduty = new AWS.GuardDuty(AWSConfig); async.eachLimit(collection.guardduty.listDetectors[AWSConfig.region].data, 15, function(detectorId, dcb) { if (!collection.guardduty || @@ -22,7 +22,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { FindingIds: findingIds }; - helpers.makeCustomCollectorCall(guardduty, 'getFindings', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(guardduty, 'getFindings', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.guardduty.getFindings[AWSConfig.region][detectorId].err = err; } diff --git a/collectors/aws/guardduty/getMasterAccount.js b/collectors/aws/guardduty/getMasterAccount.js index 2e399f38f0..c1dcca0e8a 100644 --- a/collectors/aws/guardduty/getMasterAccount.js +++ b/collectors/aws/guardduty/getMasterAccount.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var guardduty = new AWS.GuardDuty(AWSConfig); async.eachLimit(collection.guardduty.listDetectors[AWSConfig.region].data, 15, function(detectorId, cb) { collection.guardduty.getMasterAccount[AWSConfig.region][detectorId] = {}; @@ -10,7 +10,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'DetectorId': detectorId }; - helpers.makeCustomCollectorCall(guardduty, 'getMasterAccount', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(guardduty, 'getMasterAccount', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.guardduty.getMasterAccount[AWSConfig.region][detectorId].err = err; } diff --git a/collectors/aws/guardduty/listFindings.js b/collectors/aws/guardduty/listFindings.js index 7e2826f89f..7ea391f138 100644 --- a/collectors/aws/guardduty/listFindings.js +++ b/collectors/aws/guardduty/listFindings.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var guardduty = new AWS.GuardDuty(AWSConfig); async.eachLimit(collection.guardduty.listDetectors[AWSConfig.region].data, 15, function(detectorId, cb) { collection.guardduty.listFindings[AWSConfig.region][detectorId] = {}; @@ -17,7 +17,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { } }; - helpers.makeCustomCollectorCall(guardduty, 'listFindings', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(guardduty, 'listFindings', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.guardduty.listFindings[AWSConfig.region][detectorId].err = err; } diff --git a/collectors/aws/guardduty/listPublishingDestinations.js b/collectors/aws/guardduty/listPublishingDestinations.js index e6d7f7a3b7..fd4a117566 100644 --- a/collectors/aws/guardduty/listPublishingDestinations.js +++ b/collectors/aws/guardduty/listPublishingDestinations.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var guardduty = new AWS.GuardDuty(AWSConfig); async.eachLimit(collection.guardduty.listDetectors[AWSConfig.region].data, 15, function(detectorId, cb) { collection.guardduty.listPublishingDestinations[AWSConfig.region][detectorId] = {}; @@ -10,7 +10,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'DetectorId': detectorId }; - helpers.makeCustomCollectorCall(guardduty, 'listPublishingDestinations', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(guardduty, 'listPublishingDestinations', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.guardduty.listPublishingDestinations[AWSConfig.region][detectorId].err = err; } diff --git a/collectors/aws/iam/generateCredentialReport.js b/collectors/aws/iam/generateCredentialReport.js index 4ee1fdb2f3..8838475b80 100644 --- a/collectors/aws/iam/generateCredentialReport.js +++ b/collectors/aws/iam/generateCredentialReport.js @@ -1,7 +1,7 @@ var AWS = require('aws-sdk'); var async = require('async'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var iam = new AWS.IAM(AWSConfig); var generateCredentialReport = function(genCb) { diff --git a/collectors/aws/iam/getGroupPolicy.js b/collectors/aws/iam/getGroupPolicy.js index 95b2512819..40f4a4b7af 100644 --- a/collectors/aws/iam/getGroupPolicy.js +++ b/collectors/aws/iam/getGroupPolicy.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var iam = new AWS.IAM(AWSConfig); if (!collection.iam || @@ -39,7 +39,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { async.eachLimit(collection.iam.listGroupPolicies[AWSConfig.region][group.GroupName].data.PolicyNames, 5, function(policyName, pCb){ collection.iam.getGroupPolicy[AWSConfig.region][group.GroupName][policyName] = {}; - helpers.makeCustomCollectorCall(iam, 'getGroupPolicy', {PolicyName: policyName, GroupName: group.GroupName}, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(iam, 'getGroupPolicy', {PolicyName: policyName, GroupName: group.GroupName}, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.iam.getGroupPolicy[AWSConfig.region][group.GroupName][policyName].err = err; return pCb(); diff --git a/collectors/aws/iam/getInstanceProfile.js b/collectors/aws/iam/getInstanceProfile.js index 453e2a78fa..8358155761 100644 --- a/collectors/aws/iam/getInstanceProfile.js +++ b/collectors/aws/iam/getInstanceProfile.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var iam = new AWS.IAM(AWSConfig); if (!collection.ec2 || @@ -28,7 +28,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { collection.iam.getInstanceProfile[AWSConfig.region][instance.IamInstanceProfile.Arn] = {}; - helpers.makeCustomCollectorCall(iam, 'getInstanceProfile', {InstanceProfileName: iamInstanceProfileName}, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(iam, 'getInstanceProfile', {InstanceProfileName: iamInstanceProfileName}, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.iam.getInstanceProfile[AWSConfig.region][instance.IamInstanceProfile.Arn].err = err; } diff --git a/collectors/aws/iam/getPolicyVersion.js b/collectors/aws/iam/getPolicyVersion.js index 70bb12a38f..3c46c052d0 100644 --- a/collectors/aws/iam/getPolicyVersion.js +++ b/collectors/aws/iam/getPolicyVersion.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var iam = new AWS.IAM(AWSConfig); if (!collection.iam || @@ -25,7 +25,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { var versionId = collection.iam.getPolicy[AWSConfig.region][policy.Arn].data.Policy.DefaultVersionId; collection.iam.getPolicyVersion[AWSConfig.region][policy.Arn] = {}; - helpers.makeCustomCollectorCall(iam, 'getPolicyVersion', {PolicyArn: policy.Arn, VersionId: versionId}, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(iam, 'getPolicyVersion', {PolicyArn: policy.Arn, VersionId: versionId}, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.iam.getPolicyVersion[AWSConfig.region][policy.Arn].err = err; } diff --git a/collectors/aws/iam/getRole.js b/collectors/aws/iam/getRole.js index 5ec172fe45..4b37a4ab0b 100644 --- a/collectors/aws/iam/getRole.js +++ b/collectors/aws/iam/getRole.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var iam = new AWS.IAM(AWSConfig); if (!collection.iam || @@ -21,7 +21,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { collection.iam.getRole[AWSConfig.region][role.RoleName] = {}; - helpers.makeCustomCollectorCall(iam, 'getRole', {RoleName: role.RoleName}, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(iam, 'getRole', {RoleName: role.RoleName}, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.iam.getRole[AWSConfig.region][role.RoleName].err = err; } diff --git a/collectors/aws/iam/getRolePolicy.js b/collectors/aws/iam/getRolePolicy.js index 239d1e45a9..e050c89ffc 100644 --- a/collectors/aws/iam/getRolePolicy.js +++ b/collectors/aws/iam/getRolePolicy.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var iam = new AWS.IAM(AWSConfig); if (!collection.iam || @@ -51,7 +51,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { async.eachLimit(collection.iam.listRolePolicies[AWSConfig.region][role.RoleName].data.PolicyNames, 5, function(policyName, pCb){ collection.iam.getRolePolicy[AWSConfig.region][role.RoleName][policyName] = {}; - helpers.makeCustomCollectorCall(iam, 'getRolePolicy', {PolicyName: policyName,RoleName: role.RoleName}, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(iam, 'getRolePolicy', {PolicyName: policyName,RoleName: role.RoleName}, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.iam.getRolePolicy[AWSConfig.region][role.RoleName][policyName].err = err; return pCb(); diff --git a/collectors/aws/iam/getUserPolicy.js b/collectors/aws/iam/getUserPolicy.js index d40a3a20d9..077ad47274 100644 --- a/collectors/aws/iam/getUserPolicy.js +++ b/collectors/aws/iam/getUserPolicy.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var iam = new AWS.IAM(AWSConfig); if (!collection.iam || @@ -49,7 +49,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { async.each(collection.iam.listUserPolicies[AWSConfig.region][user.UserName].data.PolicyNames, function(policyName, pCb){ collection.iam.getUserPolicy[AWSConfig.region][user.UserName][policyName] = {}; - helpers.makeCustomCollectorCall(iam, 'getUserPolicy', {PolicyName: policyName,UserName: user.UserName}, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(iam, 'getUserPolicy', {PolicyName: policyName,UserName: user.UserName}, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.iam.getUserPolicy[AWSConfig.region][user.UserName][policyName].err = err; return pCb(); diff --git a/collectors/aws/iam/listRoles.js b/collectors/aws/iam/listRoles.js index c16f2a5c49..86540d6d66 100644 --- a/collectors/aws/iam/listRoles.js +++ b/collectors/aws/iam/listRoles.js @@ -1,7 +1,7 @@ var AWS = require('aws-sdk'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var iam = new AWS.IAM(AWSConfig); collection.iam.listRoles[AWSConfig.region] = {}; var params = {}; @@ -33,7 +33,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { function execute(marker) { var localParams = JSON.parse(JSON.stringify(params || {})); if (marker) localParams['Marker'] = marker; - helpers.makeCustomCollectorCall(iam, 'listRoles', localParams, retries, null, null, null, paginateCb); + helpers.makeCustomCollectorCall(iam, 'listRoles', localParams, retries, null, null, null, settings, scanAWSConfig, AWSConfig, paginateCb); } execute(); diff --git a/collectors/aws/kinesis/describeStream.js b/collectors/aws/kinesis/describeStream.js index 31bcb0b1a1..a06defbda8 100644 --- a/collectors/aws/kinesis/describeStream.js +++ b/collectors/aws/kinesis/describeStream.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var kinesis = new AWS.Kinesis(AWSConfig); async.eachLimit(collection.kinesis.listStreams[AWSConfig.region].data, 15, function(stream, cb){ @@ -12,7 +12,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { StreamName: stream }; - helpers.makeCustomCollectorCall(kinesis, 'describeStream', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(kinesis, 'describeStream', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.kinesis.describeStream[AWSConfig.region][stream].err = err; } diff --git a/collectors/aws/kms/getKeyPolicy.js b/collectors/aws/kms/getKeyPolicy.js index 4e562042f3..d11091aa36 100644 --- a/collectors/aws/kms/getKeyPolicy.js +++ b/collectors/aws/kms/getKeyPolicy.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var kms = new AWS.KMS(AWSConfig); async.eachLimit(collection.kms.listKeys[AWSConfig.region].data, 15, function(key, cb){ @@ -16,7 +16,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { PolicyName: 'default' }; - helpers.makeCustomCollectorCall(kms, 'getKeyPolicy', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(kms, 'getKeyPolicy', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.kms.getKeyPolicy[AWSConfig.region][key.KeyId].err = err; } diff --git a/collectors/aws/kms/listGrants.js b/collectors/aws/kms/listGrants.js index 4272e478b5..a5c24a9df6 100644 --- a/collectors/aws/kms/listGrants.js +++ b/collectors/aws/kms/listGrants.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var kms = new AWS.KMS(AWSConfig); async.eachLimit(collection.kms.listKeys[AWSConfig.region].data, 15, function(key, cb) { collection.kms.listGrants[AWSConfig.region][key.KeyId] = {}; @@ -36,9 +36,9 @@ module.exports = function(AWSConfig, collection, retries, callback) { var localParams = JSON.parse(JSON.stringify(params || {})); if (marker) localParams['Marker'] = marker; if (marker) { - helpers.makeCustomCollectorCall(kms, 'listGrants', localParams, retries, null, null, null, paginateCb); + helpers.makeCustomCollectorCall(kms, 'listGrants', localParams, retries, null, null, null, settings, scanAWSConfig, AWSConfig, paginateCb); } else { - helpers.makeCustomCollectorCall(kms, 'listGrants', params, retries, null, null, null, paginateCb); + helpers.makeCustomCollectorCall(kms, 'listGrants', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, paginateCb); } } diff --git a/collectors/aws/lexmodelsv2/describeBotAlias.js b/collectors/aws/lexmodelsv2/describeBotAlias.js index fb6c951af8..a4ba34ea31 100644 --- a/collectors/aws/lexmodelsv2/describeBotAlias.js +++ b/collectors/aws/lexmodelsv2/describeBotAlias.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var lexmodelsv2 = new AWS.LexModelsV2(AWSConfig); if (!collection.lexmodelsv2 || @@ -24,7 +24,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { async.eachLimit(collection.lexmodelsv2.listBotAliases[AWSConfig.region][bot.botId].data.botAliasSummaries, 3, function(alias, pCb){ collection.lexmodelsv2.describeBotAlias[AWSConfig.region][alias.botAliasId] = {}; - helpers.makeCustomCollectorCall(lexmodelsv2, 'describeBotAlias', {botAliasId: alias.botAliasId,botId: bot.botId}, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(lexmodelsv2, 'describeBotAlias', {botAliasId: alias.botAliasId,botId: bot.botId}, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.lexmodelsv2.describeBotAlias[AWSConfig.region][alias.botAliasId].err = err; } diff --git a/collectors/aws/lookoutvision/describeModel.js b/collectors/aws/lookoutvision/describeModel.js index a3216bf2c2..75d543d3aa 100644 --- a/collectors/aws/lookoutvision/describeModel.js +++ b/collectors/aws/lookoutvision/describeModel.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var lookoutvision = new AWS.LookoutVision(AWSConfig); if (!collection.lookoutvision || @@ -26,7 +26,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { collection.lookoutvision.describeModel[AWSConfig.region][model.ModelArn] = {}; // Make the describe Models call - helpers.makeCustomCollectorCall(lookoutvision, 'describeModel', {ModelVersion: model.ModelVersion,ProjectName: project.ProjectName}, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(lookoutvision, 'describeModel', {ModelVersion: model.ModelVersion,ProjectName: project.ProjectName}, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.lookoutvision.describeModel[AWSConfig.region][model.ModelArn].err = err; } diff --git a/collectors/aws/managedblockchain/getMember.js b/collectors/aws/managedblockchain/getMember.js index 17b99ffe65..eb6bf5e604 100644 --- a/collectors/aws/managedblockchain/getMember.js +++ b/collectors/aws/managedblockchain/getMember.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var managedblockchain = new AWS.ManagedBlockchain(AWSConfig); if (!collection.managedblockchain || @@ -23,7 +23,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { async.eachLimit(collection.managedblockchain.listMembers[AWSConfig.region][network.Id].data.Members, 5, function(member, mcb){ collection.managedblockchain.getMember[AWSConfig.region][member.Id] = {}; - helpers.makeCustomCollectorCall(managedblockchain, 'getMember', {MemberId: member.Id,NetworkId: network.Id}, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(managedblockchain, 'getMember', {MemberId: member.Id,NetworkId: network.Id}, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.managedblockchain.getMember[AWSConfig.region][member.Id].err = err; } diff --git a/collectors/aws/mwaa/getEnvironment.js b/collectors/aws/mwaa/getEnvironment.js index 9d992a124b..21d95a357f 100644 --- a/collectors/aws/mwaa/getEnvironment.js +++ b/collectors/aws/mwaa/getEnvironment.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var mwaa = new AWS.MWAA(AWSConfig); async.eachLimit(collection.mwaa.listEnvironments[AWSConfig.region].data, 15, function(env, cb){ @@ -12,7 +12,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { Name: env }; - helpers.makeCustomCollectorCall(mwaa, 'getEnvironment', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(mwaa, 'getEnvironment', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.mwaa.getEnvironment[AWSConfig.region][env].err = err; } diff --git a/collectors/aws/opensearchserverless/getEncryptionSecurityPolicy.js b/collectors/aws/opensearchserverless/getEncryptionSecurityPolicy.js index 8944a652cd..bea3e24fbe 100644 --- a/collectors/aws/opensearchserverless/getEncryptionSecurityPolicy.js +++ b/collectors/aws/opensearchserverless/getEncryptionSecurityPolicy.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var ecs = new AWS.OpenSearchServerless(AWSConfig); async.eachLimit(collection.opensearchserverless.listEncryptionSecurityPolicies[AWSConfig.region].data, 10, function(policy, cb){ @@ -12,7 +12,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { type: 'encryption' }; - helpers.makeCustomCollectorCall(ecs, 'getSecurityPolicy', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(ecs, 'getSecurityPolicy', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.opensearchserverless.getEncryptionSecurityPolicy[AWSConfig.region][policy.name].err = err; } diff --git a/collectors/aws/opensearchserverless/getNetworkSecurityPolicy.js b/collectors/aws/opensearchserverless/getNetworkSecurityPolicy.js index cc87011fcf..ba30f6aef1 100644 --- a/collectors/aws/opensearchserverless/getNetworkSecurityPolicy.js +++ b/collectors/aws/opensearchserverless/getNetworkSecurityPolicy.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var ecs = new AWS.OpenSearchServerless(AWSConfig); async.eachLimit(collection.opensearchserverless.listNetworkSecurityPolicies[AWSConfig.region].data, 10, function(policy, cb){ collection.opensearchserverless.getNetworkSecurityPolicy[AWSConfig.region][policy.name] = {}; @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { type: 'network' }; - helpers.makeCustomCollectorCall(ecs, 'getSecurityPolicy', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(ecs, 'getSecurityPolicy', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.opensearchserverless.getNetworkSecurityPolicy[AWSConfig.region][policy.name].err = err; } diff --git a/collectors/aws/opensearchserverless/listEncryptionSecurityPolicies.js b/collectors/aws/opensearchserverless/listEncryptionSecurityPolicies.js index 590dbc71dc..a7e285aaea 100644 --- a/collectors/aws/opensearchserverless/listEncryptionSecurityPolicies.js +++ b/collectors/aws/opensearchserverless/listEncryptionSecurityPolicies.js @@ -1,13 +1,13 @@ var AWS = require('aws-sdk'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var opensearch = new AWS.OpenSearchServerless(AWSConfig); collection.opensearchserverless.listEncryptionSecurityPolicies[AWSConfig.region] = {}; let params = { type: 'encryption' }; - helpers.makeCustomCollectorCall(opensearch, 'listSecurityPolicies', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(opensearch, 'listSecurityPolicies', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.opensearchserverless.listEncryptionSecurityPolicies[AWSConfig.region].err = err; } else if (data && data.securityPolicySummaries){ diff --git a/collectors/aws/opensearchserverless/listNetworkSecurityPolicies.js b/collectors/aws/opensearchserverless/listNetworkSecurityPolicies.js index f1f55ca919..c1742478ad 100644 --- a/collectors/aws/opensearchserverless/listNetworkSecurityPolicies.js +++ b/collectors/aws/opensearchserverless/listNetworkSecurityPolicies.js @@ -1,13 +1,13 @@ var AWS = require('aws-sdk'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var opensearch = new AWS.OpenSearchServerless(AWSConfig); collection.opensearchserverless.listNetworkSecurityPolicies[AWSConfig.region] = {}; let params = { type: 'network' }; - helpers.makeCustomCollectorCall(opensearch, 'listSecurityPolicies', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(opensearch, 'listSecurityPolicies', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.opensearchserverless.listNetworkSecurityPolicies[AWSConfig.region].err = err; } else if (data && data.securityPolicySummaries) { diff --git a/collectors/aws/rds/describeDBParameters.js b/collectors/aws/rds/describeDBParameters.js index 5cf608fa16..c158137981 100644 --- a/collectors/aws/rds/describeDBParameters.js +++ b/collectors/aws/rds/describeDBParameters.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var rds = new AWS.RDS(AWSConfig); async.eachLimit(collection.rds.describeDBParameterGroups[AWSConfig.region].data, 15, function(group, cb) { collection.rds.describeDBParameters[AWSConfig.region][group.DBParameterGroupName] = {}; @@ -36,9 +36,9 @@ module.exports = function(AWSConfig, collection, retries, callback) { var localParams = JSON.parse(JSON.stringify(params || {})); if (marker) localParams['Marker'] = marker; if (marker) { - helpers.makeCustomCollectorCall(rds, 'describeDBParameters', localParams, retries, null, null, null, paginateCb); + helpers.makeCustomCollectorCall(rds, 'describeDBParameters', localParams, retries, null, null, null, settings, scanAWSConfig, AWSConfig, paginateCb); } else { - helpers.makeCustomCollectorCall(rds, 'describeDBParameters', params, retries, null, null, null, paginateCb); + helpers.makeCustomCollectorCall(rds, 'describeDBParameters', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, paginateCb); } } diff --git a/collectors/aws/s3/getBucketAcl.js b/collectors/aws/s3/getBucketAcl.js index e0dc545e47..0c38c123ed 100644 --- a/collectors/aws/s3/getBucketAcl.js +++ b/collectors/aws/s3/getBucketAcl.js @@ -1,5 +1,5 @@ var index = require(__dirname + '/index.js'); -module.exports = function(AWSConfig, collection, retries, callback) { - index('getBucketAcl', false, AWSConfig, collection, retries, callback); +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { + index('getBucketAcl', false, AWSConfig, collection, retries, settings, scanAWSConfig, callback); }; \ No newline at end of file diff --git a/collectors/aws/s3/getBucketEncryption.js b/collectors/aws/s3/getBucketEncryption.js index 07eb28a2a7..8ff58568d9 100644 --- a/collectors/aws/s3/getBucketEncryption.js +++ b/collectors/aws/s3/getBucketEncryption.js @@ -1,5 +1,5 @@ var index = require(__dirname + '/index.js'); -module.exports = function(AWSConfig, collection, retries, callback) { - index('getBucketEncryption', false, AWSConfig, collection, retries, callback); +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { + index('getBucketEncryption', false, AWSConfig, collection, retries, settings, scanAWSConfig, callback); }; \ No newline at end of file diff --git a/collectors/aws/s3/getBucketLifecycleConfiguration.js b/collectors/aws/s3/getBucketLifecycleConfiguration.js index 2ccd972743..2f2540c70c 100644 --- a/collectors/aws/s3/getBucketLifecycleConfiguration.js +++ b/collectors/aws/s3/getBucketLifecycleConfiguration.js @@ -1,5 +1,5 @@ var index = require(__dirname + '/index.js'); -module.exports = function(AWSConfig, collection, retries, callback) { - index('getBucketLifecycleConfiguration', false, AWSConfig, collection, retries, callback); +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { + index('getBucketLifecycleConfiguration', false, AWSConfig, collection, retries, settings, scanAWSConfig, callback); }; \ No newline at end of file diff --git a/collectors/aws/s3/getBucketLocation.js b/collectors/aws/s3/getBucketLocation.js index 1f765eebf8..b1105bf6d4 100644 --- a/collectors/aws/s3/getBucketLocation.js +++ b/collectors/aws/s3/getBucketLocation.js @@ -1,5 +1,5 @@ var index = require(__dirname + '/index.js'); -module.exports = function(AWSConfig, collection, retries, callback) { - index('getBucketLocation', false, AWSConfig, collection, retries, callback); +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { + index('getBucketLocation', false, AWSConfig, collection, retries, settings, scanAWSConfig, callback); }; \ No newline at end of file diff --git a/collectors/aws/s3/getBucketLogging.js b/collectors/aws/s3/getBucketLogging.js index f9eb082c3a..29fdce76dc 100644 --- a/collectors/aws/s3/getBucketLogging.js +++ b/collectors/aws/s3/getBucketLogging.js @@ -1,5 +1,5 @@ var index = require(__dirname + '/index.js'); -module.exports = function(AWSConfig, collection, retries, callback) { - index('getBucketLogging', false, AWSConfig, collection, retries, callback); +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { + index('getBucketLogging', false, AWSConfig, collection, retries, settings, scanAWSConfig, callback); }; \ No newline at end of file diff --git a/collectors/aws/s3/getBucketPolicy.js b/collectors/aws/s3/getBucketPolicy.js index 0d02b83d42..667129ce5a 100644 --- a/collectors/aws/s3/getBucketPolicy.js +++ b/collectors/aws/s3/getBucketPolicy.js @@ -1,5 +1,5 @@ var index = require(__dirname + '/index.js'); -module.exports = function(AWSConfig, collection, retries, callback) { - index('getBucketPolicy', false, AWSConfig, collection, retries, callback); +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { + index('getBucketPolicy', false, AWSConfig, collection, retries, settings, scanAWSConfig, callback); }; \ No newline at end of file diff --git a/collectors/aws/s3/getBucketPolicyStatus.js b/collectors/aws/s3/getBucketPolicyStatus.js index 7f91143fa1..7b30fb8533 100644 --- a/collectors/aws/s3/getBucketPolicyStatus.js +++ b/collectors/aws/s3/getBucketPolicyStatus.js @@ -1,5 +1,5 @@ var index = require(__dirname + '/index.js'); -module.exports = function(AWSConfig, collection, retries, callback) { - index('getBucketPolicyStatus', false, AWSConfig, collection, retries, callback); +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { + index('getBucketPolicyStatus', false, AWSConfig, collection, retries, settings, scanAWSConfig, callback); }; \ No newline at end of file diff --git a/collectors/aws/s3/getBucketTagging.js b/collectors/aws/s3/getBucketTagging.js index b6197f9f12..ddf2f234bc 100644 --- a/collectors/aws/s3/getBucketTagging.js +++ b/collectors/aws/s3/getBucketTagging.js @@ -1,5 +1,5 @@ var index = require(__dirname + '/index.js'); -module.exports = function(AWSConfig, collection, retries, callback) { - index('getBucketTagging', false, AWSConfig, collection, retries, callback); +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { + index('getBucketTagging', false, AWSConfig, collection, retries, settings, scanAWSConfig, callback); }; diff --git a/collectors/aws/s3/getBucketVersioning.js b/collectors/aws/s3/getBucketVersioning.js index 8a114cfe52..9a842f761f 100644 --- a/collectors/aws/s3/getBucketVersioning.js +++ b/collectors/aws/s3/getBucketVersioning.js @@ -1,5 +1,5 @@ var index = require(__dirname + '/index.js'); -module.exports = function(AWSConfig, collection, retries, callback) { - index('getBucketVersioning', false, AWSConfig, collection, retries, callback); +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { + index('getBucketVersioning', false, AWSConfig, collection, retries, settings, scanAWSConfig, callback); }; \ No newline at end of file diff --git a/collectors/aws/s3/getBucketWebsite.js b/collectors/aws/s3/getBucketWebsite.js index 0357b60df0..ab61437a65 100644 --- a/collectors/aws/s3/getBucketWebsite.js +++ b/collectors/aws/s3/getBucketWebsite.js @@ -1,5 +1,5 @@ var index = require(__dirname + '/index.js'); -module.exports = function(AWSConfig, collection, retries, callback) { - index('getBucketWebsite', false, AWSConfig, collection, retries, callback); +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { + index('getBucketWebsite', false, AWSConfig, collection, retries, settings, scanAWSConfig, callback); }; \ No newline at end of file diff --git a/collectors/aws/s3/getObjectLockConfiguration.js b/collectors/aws/s3/getObjectLockConfiguration.js index fb280059d8..1c61e923f0 100644 --- a/collectors/aws/s3/getObjectLockConfiguration.js +++ b/collectors/aws/s3/getObjectLockConfiguration.js @@ -1,5 +1,5 @@ var index = require(__dirname + '/index.js'); -module.exports = function(AWSConfig, collection, retries, callback) { - index('getObjectLockConfiguration', false, AWSConfig, collection, retries, callback); +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { + index('getObjectLockConfiguration', false, AWSConfig, collection, retries, settings, scanAWSConfig, callback); }; \ No newline at end of file diff --git a/collectors/aws/s3/getPublicAccessBlock.js b/collectors/aws/s3/getPublicAccessBlock.js index dddf5be6a6..f14ea6dcef 100644 --- a/collectors/aws/s3/getPublicAccessBlock.js +++ b/collectors/aws/s3/getPublicAccessBlock.js @@ -1,5 +1,5 @@ var index = require(__dirname + '/index.js'); -module.exports = function(AWSConfig, collection, retries, callback) { - index('getPublicAccessBlock', false, AWSConfig, collection, retries, callback); +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { + index('getPublicAccessBlock', false, AWSConfig, collection, retries, settings, scanAWSConfig, callback); }; \ No newline at end of file diff --git a/collectors/aws/s3/index.js b/collectors/aws/s3/index.js index bbcac26df5..761decdb06 100644 --- a/collectors/aws/s3/index.js +++ b/collectors/aws/s3/index.js @@ -2,8 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(callKey, forceCloudTrail, AWSConfig, collection, retries, callback) { - var s3 = new AWS.S3(AWSConfig); +module.exports = function(callKey, forceCloudTrail, AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var knownBuckets = []; @@ -26,7 +25,7 @@ module.exports = function(callKey, forceCloudTrail, AWSConfig, collection, retri for (var t in collection.cloudtrail.describeTrails[region].data) { var trail = collection.cloudtrail.describeTrails[region].data[t]; - + if (knownBuckets.indexOf(trail.S3BucketName) === -1) { knownBuckets.push(trail.S3BucketName); } @@ -37,18 +36,19 @@ module.exports = function(callKey, forceCloudTrail, AWSConfig, collection, retri if (!knownBuckets || !knownBuckets.length) return callback(); async.eachLimit(knownBuckets, 10, function(bucket, bcb){ + var s3 = new AWS.S3(AWSConfig); collection['s3'][callKey][AWSConfig.region][bucket] = {}; - helpers.makeCustomCollectorCall(s3, callKey, {Bucket:bucket}, retries, null, null, null, function(bErr, bData) { + helpers.makeCustomCollectorCall(s3, callKey, {Bucket:bucket}, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(bErr, bData) { if (bErr) { collection['s3'][callKey][AWSConfig.region][bucket].err = bErr; if (bErr.statusCode && bErr.statusCode == 301) { - helpers.makeCustomCollectorCall(s3, 'getBucketLocation', {Bucket:bucket}, retries, null, null, null, function(locErr, locData) { + helpers.makeCustomCollectorCall(s3, 'getBucketLocation', {Bucket:bucket}, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(locErr, locData) { if (locErr || !locData || !locData.LocationConstraint) return bcb(); // Special case where location constraint is EU - rewrite as eu-west-1 if (locData.LocationConstraint == 'EU') locData.LocationConstraint = 'eu-west-1'; - + var altAWSConfig = JSON.parse(JSON.stringify(AWSConfig)); altAWSConfig.region = locData.LocationConstraint; var s3Alt = new AWS.S3(altAWSConfig); @@ -74,4 +74,4 @@ module.exports = function(callKey, forceCloudTrail, AWSConfig, collection, retri }, function(){ callback(); }); -}; \ No newline at end of file +}; diff --git a/collectors/aws/s3control/getPublicAccessBlock.js b/collectors/aws/s3control/getPublicAccessBlock.js index 0ea179f5f1..6d5b90cd2e 100644 --- a/collectors/aws/s3control/getPublicAccessBlock.js +++ b/collectors/aws/s3control/getPublicAccessBlock.js @@ -1,7 +1,7 @@ var AWS = require('aws-sdk'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var s3control = new AWS.S3Control(AWSConfig); var accountId = collection.sts.getCallerIdentity[AWSConfig.region].data; @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { AccountId: accountId }; - helpers.makeCustomCollectorCall(s3control, 'getPublicAccessBlock', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(s3control, 'getPublicAccessBlock', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.s3control.getPublicAccessBlock[AWSConfig.region][accountId].err = err; } diff --git a/collectors/aws/securityhub/getFindings.js b/collectors/aws/securityhub/getFindings.js index 52e94a459d..2b7f84f8fb 100644 --- a/collectors/aws/securityhub/getFindings.js +++ b/collectors/aws/securityhub/getFindings.js @@ -1,7 +1,7 @@ var AWS = require('aws-sdk'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var securityhub = new AWS.SecurityHub(AWSConfig); collection.securityhub.getFindings[AWSConfig.region] = {}; @@ -34,7 +34,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { }; function execute() { - helpers.makeCustomCollectorCall(securityhub, 'getFindings', params, retries, null, null, null, paginateCb); + helpers.makeCustomCollectorCall(securityhub, 'getFindings', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, paginateCb); } execute(); }; diff --git a/collectors/aws/ses/getIdentityDkimAttributes.js b/collectors/aws/ses/getIdentityDkimAttributes.js index 3e51064970..d47ed4fec6 100644 --- a/collectors/aws/ses/getIdentityDkimAttributes.js +++ b/collectors/aws/ses/getIdentityDkimAttributes.js @@ -1,7 +1,7 @@ var AWS = require('aws-sdk'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var ses = new AWS.SES(AWSConfig); collection.ses.getIdentityDkimAttributes[AWSConfig.region] = {}; @@ -23,7 +23,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { }; setTimeout(function() { - helpers.makeCustomCollectorCall(ses, 'getIdentityDkimAttributes', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(ses, 'getIdentityDkimAttributes', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.ses.getIdentityDkimAttributes[AWSConfig.region].err = err; } else if (data && data.DkimAttributes) { diff --git a/collectors/aws/sqs/getQueueAttributes.js b/collectors/aws/sqs/getQueueAttributes.js index b85e355c25..64ad1e3cb9 100644 --- a/collectors/aws/sqs/getQueueAttributes.js +++ b/collectors/aws/sqs/getQueueAttributes.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var sqs = new AWS.SQS(AWSConfig); async.eachLimit(collection.sqs.listQueues[AWSConfig.region].data, 15, function(queue, cb){ @@ -15,7 +15,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { ] }; - helpers.makeCustomCollectorCall(sqs, 'getQueueAttributes', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(sqs, 'getQueueAttributes', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.sqs.getQueueAttributes[AWSConfig.region][queue].err = err; } diff --git a/collectors/aws/ssm/describeParameters.js b/collectors/aws/ssm/describeParameters.js index 4c7eb39321..0a5257af49 100644 --- a/collectors/aws/ssm/describeParameters.js +++ b/collectors/aws/ssm/describeParameters.js @@ -1,7 +1,7 @@ var AWS = require('aws-sdk'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var ssm = new AWS.SSM(AWSConfig); collection.ssm.describeParameters[AWSConfig.region] = {}; var params = {}; @@ -33,7 +33,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { function execute(marker) { var localParams = JSON.parse(JSON.stringify(params || {})); if (marker) localParams['NextToken'] = marker; - helpers.makeCustomCollectorCall(ssm, 'describeParameters', localParams, retries, null, null, null, paginateCb); + helpers.makeCustomCollectorCall(ssm, 'describeParameters', localParams, retries, null, null, null, settings, scanAWSConfig, AWSConfig, paginateCb); } execute(); diff --git a/collectors/aws/support/describeTrustedAdvisorCheckResult.js b/collectors/aws/support/describeTrustedAdvisorCheckResult.js index 76ed78cd1e..c535a9cab0 100644 --- a/collectors/aws/support/describeTrustedAdvisorCheckResult.js +++ b/collectors/aws/support/describeTrustedAdvisorCheckResult.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var support = new AWS.Support(AWSConfig); async.eachLimit(collection.support.describeTrustedAdvisorChecks[AWSConfig.region].data, 15, function(check, cb) { @@ -12,7 +12,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { checkId: check, }; - helpers.makeCustomCollectorCall(support, 'describeTrustedAdvisorCheckResult', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(support, 'describeTrustedAdvisorCheckResult', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.support.describeTrustedAdvisorChecks[AWSConfig.region][check].err = err; } diff --git a/collectors/aws/wafregional/listResourcesForWebACL.js b/collectors/aws/wafregional/listResourcesForWebACL.js index c1728c507d..9424b9ed34 100644 --- a/collectors/aws/wafregional/listResourcesForWebACL.js +++ b/collectors/aws/wafregional/listResourcesForWebACL.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var wafregional = new AWS.WAFRegional(AWSConfig); async.eachLimit(collection.wafregional.listWebACLs[AWSConfig.region].data, 15, function(dep, depCb){ async.eachLimit(['APPLICATION_LOAD_BALANCER', 'API_GATEWAY'], 1, function(thisCheck, tcCb){ @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { var filter = {}; filter['WebACLId'] = dep['WebACLId']; filter['ResourceType'] = thisCheck; - helpers.makeCustomCollectorCall(wafregional, 'listResourcesForWebACL', filter, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(wafregional, 'listResourcesForWebACL', filter, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection['wafregional']['listResourcesForWebACL'][AWSConfig.region][dep['WebACLId']].err = err; return tcCb(); diff --git a/collectors/aws/wafv2/getWebACL.js b/collectors/aws/wafv2/getWebACL.js index e2ed82a7c1..e58f56ff1d 100644 --- a/collectors/aws/wafv2/getWebACL.js +++ b/collectors/aws/wafv2/getWebACL.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var wafv2 = new AWS.WAFV2(AWSConfig); async.eachLimit(collection.wafv2.listWebACLs[AWSConfig.region].data, 15, function(acl, cb){ @@ -12,7 +12,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'Scope': 'REGIONAL' }; - helpers.makeCustomCollectorCall(wafv2, 'getWebACL', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(wafv2, 'getWebACL', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { collection.wafv2.getWebACL[AWSConfig.region][acl.ARN] = {}; if (err) { diff --git a/collectors/aws/wafv2/getWebACLForCognitoUserPool.js b/collectors/aws/wafv2/getWebACLForCognitoUserPool.js index 756032c4d8..caf80e738b 100644 --- a/collectors/aws/wafv2/getWebACLForCognitoUserPool.js +++ b/collectors/aws/wafv2/getWebACLForCognitoUserPool.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var wafv2 = new AWS.WAFV2(AWSConfig); var region = 'us-east-1'; @@ -20,7 +20,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { 'ResourceArn':`arn:${partition}:cognito-idp:${AWSConfig.region}:${collection.sts.getCallerIdentity[region].data}:userpool/${up.Id}` }; - helpers.makeCustomCollectorCall(wafv2, 'getWebACLForResource', params, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(wafv2, 'getWebACLForResource', params, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection.wafv2.getWebACLForCognitoUserPool[AWSConfig.region][up.Id].err = err; } diff --git a/collectors/aws/wafv2/listResourcesForWebACL.js b/collectors/aws/wafv2/listResourcesForWebACL.js index 711a45dbef..36c039cc89 100644 --- a/collectors/aws/wafv2/listResourcesForWebACL.js +++ b/collectors/aws/wafv2/listResourcesForWebACL.js @@ -2,7 +2,7 @@ var AWS = require('aws-sdk'); var async = require('async'); var helpers = require(__dirname + '/../../../helpers/aws'); -module.exports = function(AWSConfig, collection, retries, callback) { +module.exports = function(AWSConfig, collection, retries, settings, scanAWSConfig, callback) { var wafv2 = new AWS.WAFV2(AWSConfig); async.eachLimit(collection.wafv2.listWebACLs[AWSConfig.region].data, 15, function(dep, depCb){ async.eachLimit(['APPLICATION_LOAD_BALANCER', 'API_GATEWAY'], 1, function(thisCheck, tcCb){ @@ -11,7 +11,7 @@ module.exports = function(AWSConfig, collection, retries, callback) { var filter = {}; filter['WebACLArn'] = dep['ARN']; filter['ResourceType'] = thisCheck; - helpers.makeCustomCollectorCall(wafv2, 'listResourcesForWebACL', filter, retries, null, null, null, function(err, data) { + helpers.makeCustomCollectorCall(wafv2, 'listResourcesForWebACL', filter, retries, null, null, null, settings, scanAWSConfig, AWSConfig, function(err, data) { if (err) { collection['wafv2']['listResourcesForWebACL'][AWSConfig.region][dep['ARN']].err = err; return tcCb(); diff --git a/engine.spec.js b/engine.spec.js index 4faabcf89f..22b0cca6e4 100644 --- a/engine.spec.js +++ b/engine.spec.js @@ -2,6 +2,8 @@ var engine = require('./engine'); describe('engine', function () { + this.timeout(10000); + it('should run with no arguments', function () { // Although we don't pass in anything, this is enough to test // that our dependencies are actually installed. diff --git a/exports.js b/exports.js index 6d0032525d..261e4485ff 100644 --- a/exports.js +++ b/exports.js @@ -207,7 +207,6 @@ module.exports = { 'vpcEndpointExposed' : require(__dirname + '/plugins/aws/ec2/vpcEndpointExposed.js'), 'vpcEndpointCrossAccount' : require(__dirname + '/plugins/aws/ec2/vpcEndpointCrossAccount.js'), 'vpcPeeringConnections' : require(__dirname + '/plugins/aws/ec2/vpcPeeringConnections.js'), - 'vpcPeeringLeastAccessRoutes' : require(__dirname + '/plugins/aws/ec2/vpcPeeringLeastAccessRoutes.js'), 'ebsEncryptedSnapshots' : require(__dirname + '/plugins/aws/ec2/ebsEncryptedSnapshots.js'), 'ebsDefaultEncryptionEnabled' : require(__dirname + '/plugins/aws/ec2/ebsDefaultEncryptionEnabled.js'), 'ec2MetadataOptions' : require(__dirname + '/plugins/aws/ec2/ec2MetadataOptions.js'), @@ -358,7 +357,6 @@ module.exports = { 'accessKeysLastUsed' : require(__dirname + '/plugins/aws/iam/accessKeysLastUsed.js'), 'accessKeysRotated' : require(__dirname + '/plugins/aws/iam/accessKeysRotated.js'), 'certificateExpiry' : require(__dirname + '/plugins/aws/iam/certificateExpiry.js'), - 'cloudShellFullAccess' : require(__dirname + '/plugins/aws/iam/cloudShellFullAccess.js'), 'crossAccountMfaExtIdAccess' : require(__dirname + '/plugins/aws/iam/crossAccountMfaExtIdAccess.js'), 'emptyGroups' : require(__dirname + '/plugins/aws/iam/emptyGroups.js'), 'groupInlinePolicies' : require(__dirname + '/plugins/aws/iam/groupInlinePolicies.js'), diff --git a/exports.spec.js b/exports.spec.js index 2bfbd7b192..425d079c94 100644 --- a/exports.spec.js +++ b/exports.spec.js @@ -13,6 +13,8 @@ function getParamNames(func) { } describe('exports', function () { + this.timeout(10000); + it('should use the proper format for each test', function () { for (var cloud in tests) { for (var test in tests[cloud]) { diff --git a/helpers/aws/api.js b/helpers/aws/api.js index 8f0dc0758c..392fb1f939 100644 --- a/helpers/aws/api.js +++ b/helpers/aws/api.js @@ -1057,7 +1057,8 @@ var calls = { paginate: 'NextToken' }, describeAddresses: { - property: 'Addresses' + property: 'Addresses', + override: true }, describeVolumes: { property: 'Volumes' @@ -1274,11 +1275,6 @@ var calls = { property: 'TargetGroups', paginate: 'NextMarker', paginateReqProp: 'Marker' - }, - describeTargetHealth: { - property: 'TargetGroups', - paginate: 'NextMarker', - paginateReqProp: 'Marker' } }, EMR: { @@ -1457,6 +1453,9 @@ var calls = { paginate: 'NextToken', } }, + Macie2: { + getAutomatedDiscoveryConfiguration: {}, + }, Kendra: { listIndices: { property: 'IndexConfigurationSummaryItems', diff --git a/helpers/aws/api_multipart.js b/helpers/aws/api_multipart.js index b4576bf397..b002138537 100644 --- a/helpers/aws/api_multipart.js +++ b/helpers/aws/api_multipart.js @@ -375,7 +375,8 @@ var calls = [ paginate: 'NextToken' }, describeAddresses: { - property: 'Addresses' + property: 'Addresses', + override: true }, describeVolumes: { property: 'Volumes' @@ -1136,11 +1137,6 @@ var calls = [ property: 'TargetGroups', paginate: 'NextMarker', paginateReqProp: 'Marker' - }, - describeTargetHealth: { - property: 'TargetGroups', - paginate: 'NextMarker', - paginateReqProp: 'Marker' } }, Imagebuilder: { diff --git a/helpers/aws/functions.js b/helpers/aws/functions.js index 4824e94f8e..2ae5d8f480 100644 --- a/helpers/aws/functions.js +++ b/helpers/aws/functions.js @@ -1024,7 +1024,32 @@ var isRateError = function(err) { return isError; }; -function makeCustomCollectorCall(executor, callKey, params, retries, apiRetryAttempts=2, apiRetryCap=1000, apiRetryBackoff=500, callback) { +function makeCustomCollectorCall(executor, callKey, params, retries, apiRetryAttempts, apiRetryCap, apiRetryBackoff, settings, scanAWSConfig, localAWSConfig, callback) { + if (apiRetryAttempts == null) apiRetryAttempts = 2; + if (apiRetryCap == null) apiRetryCap = 1000; + if (apiRetryBackoff == null) apiRetryBackoff = 500; + + var execRef = { current: executor }; + function runOnce(cb) { + execRef.current[callKey](params, function(err, data) { + if (!settings || !scanAWSConfig || !localAWSConfig) { + return cb(err, data); + } + refreshCredentialsIfTokenExpired(err, settings, scanAWSConfig, localAWSConfig, function(refreshErr, newCreds) { + if (!newCreds) { + if (refreshErr) console.log('[WARN] Token refresh failed'); + return cb(err, data); + } + try { + execRef.current = new execRef.current.constructor(localAWSConfig); + } catch (e) { + return cb(err, data); + } + execRef.current[callKey](params, cb); + }); + }); + } + async.retry({ times: apiRetryAttempts, interval: function(retryCount){ @@ -1042,14 +1067,49 @@ function makeCustomCollectorCall(executor, callKey, params, retries, apiRetryAtt return isRateError(err); } }, function(cb) { - executor[callKey](params, function(err, data) { - return cb(err, data); + runOnce(cb); + }, function(err, result) { + callback(err, result); + }); +} + +function buildV3ClientConfig(AWSConfig) { + return { + region: AWSConfig.region, + credentials: AWSConfig + }; +} + +function makeCustomCollectorCallV3(client, Command, params, retries, apiRetryAttempts=2, apiRetryCap=1000, apiRetryBackoff=500, callback) { + async.retry({ + times: apiRetryAttempts, + interval: function(retryCount){ + let retryExponential = 3; + let retryLeveler = 3; + let timestamp = parseInt(((new Date()).getTime()).toString().slice(-1)); + let retry_temp = Math.min(apiRetryCap, (apiRetryBackoff * (retryExponential + timestamp) ** retryCount)); + let retry_seconds = Math.round(retry_temp/retryLeveler + Math.random(0, retry_temp) * 5000); + + console.log(`Trying ${Command.name} again in: ${retry_seconds/1000} seconds`); + retries.push({seconds: Math.round(retry_seconds/1000)}); + return retry_seconds; + }, + errorFilter: function(err) { + return isRateError(err); + } + }, function(cb) { + var command = new Command(params); + client.send(command).then(function(data) { + return cb(null, data); + }).catch(function(err) { + return cb(err, null); }); }, function(err, result) { callback(err, result); }); } + var debugApiCalls = function(call, service, debugMode, finished) { if (!debugMode) return; finished ? console.log(`[INFO] ${service}:${call} returned`) : console.log(`[INFO] ${service}:${call} invoked`); @@ -1119,6 +1179,68 @@ var collectRateError = function(err, rateError) { return isError; }; + +function isTokenExpiredError(err) { + if (!err) return false; + var code = (err.code || err.name || '').toString(); + var msg = (err.message || '').toString().toLowerCase(); + if (code === 'ExpiredToken' || code === 'RequestExpired' || code === 'ExpiredTokenException') return true; + return msg.indexOf('the security token included in the request is expired') > -1 || + msg.indexOf('the security token included in the request is invalid') > -1 || + msg.indexOf('the provided token has expired') > -1 || + msg.indexOf('the security token isn\'t valid') > -1 || + msg.indexOf('the security token is not valid') > -1 || + msg.indexOf('security token has expired') > -1 || + msg.indexOf('security token is expired') > -1 || + msg.indexOf('token has expired') > -1 || + msg.indexOf('token is invalid') > -1; +} +function assumeRoleForRefresh(roleArn, externalId, callback) { + if (!roleArn || !externalId) return callback(new Error('role_arn and external_id required to refresh credentials')); + var sts = new AWS.STS(); + sts.assumeRole({ + RoleArn: roleArn, + RoleSessionName: 'cloudsploit_scan', + DurationSeconds: 1800, + ExternalId: externalId + }, function(err, data) { + if (err || !data || !data.Credentials) return callback(err || new Error('No credentials returned')); + callback(null, { + accessKeyId: data.Credentials.AccessKeyId, + secretAccessKey: data.Credentials.SecretAccessKey, + sessionToken: data.Credentials.SessionToken + }); + }); +} + +function refreshCredentialsIfTokenExpired(err, settings, AWSConfig, LocalAWSConfig, cb) { + if (!err || !isTokenExpiredError(err) || !settings.role_arn || !settings.external_id) { + return cb(null, null); + } + if (settings._lastTokenRefresh && (Date.now() - settings._lastTokenRefresh < 60000)) { + console.log(`[INFO] Assigning new creds ${settings.role_arn} : ${Date.now()}`); + LocalAWSConfig.accessKeyId = AWSConfig.accessKeyId; + LocalAWSConfig.secretAccessKey = AWSConfig.secretAccessKey; + LocalAWSConfig.sessionToken = AWSConfig.sessionToken; + return cb(null, AWSConfig); + } + return assumeRoleForRefresh(settings.role_arn, settings.external_id, function(refreshErr, newCreds) { + if (refreshErr) { + console.log('[WARN] Token refresh failed'); + return cb(refreshErr, null); + } + settings._lastTokenRefresh = Date.now(); + console.log(`[INFO] Refresh succeeded, got new creds for role: ${settings.role_arn} : ${settings._lastTokenRefresh}`); + AWSConfig.accessKeyId = newCreds.accessKeyId; + AWSConfig.secretAccessKey = newCreds.secretAccessKey; + AWSConfig.sessionToken = newCreds.sessionToken; + LocalAWSConfig.accessKeyId = newCreds.accessKeyId; + LocalAWSConfig.secretAccessKey = newCreds.secretAccessKey; + LocalAWSConfig.sessionToken = newCreds.sessionToken; + return cb(null, newCreds); + }); +} + function processFieldSelectors(fieldSelectors,buckets ,startsWithBuckets,notEndsWithBuckets,endsWithBuckets, notStartsWithBuckets) { fieldSelectors.forEach(f => { if (f.Field === 'resources.ARN') { @@ -1644,9 +1766,14 @@ module.exports = { getPrivateSubnets: getPrivateSubnets, getSubnetRTMap: getSubnetRTMap, makeCustomCollectorCall: makeCustomCollectorCall, + makeCustomCollectorCallV3: makeCustomCollectorCallV3, + buildV3ClientConfig: buildV3ClientConfig, debugApiCalls: debugApiCalls, logError: logError, collectRateError: collectRateError, + isTokenExpiredError: isTokenExpiredError, + assumeRoleForRefresh: assumeRoleForRefresh, + refreshCredentialsIfTokenExpired: refreshCredentialsIfTokenExpired, checkTags: checkTags, checkConditions: checkConditions, processFieldSelectors: processFieldSelectors, diff --git a/helpers/aws/regions.js b/helpers/aws/regions.js index a7bf758558..d2bffc7ddf 100644 --- a/helpers/aws/regions.js +++ b/helpers/aws/regions.js @@ -123,6 +123,7 @@ module.exports = { waf: ['us-east-1'], organizations: ['us-east-1'], guardduty: [...regions, ...newRegionsUpdate], + macie2: [...regions, ...newRegionsUpdate], workspaces: ['us-east-1', 'us-west-2', 'ca-central-1', 'sa-east-1', 'ap-south-1', 'eu-west-1', 'eu-central-1', 'eu-west-2', 'ap-southeast-1', 'ap-northeast-1', 'ap-southeast-2', 'ap-northeast-2', 'af-south-1', 'il-central-1'], diff --git a/helpers/aws/regions_china.js b/helpers/aws/regions_china.js index 5a7e38a712..de92b2c6e3 100644 --- a/helpers/aws/regions_china.js +++ b/helpers/aws/regions_china.js @@ -75,6 +75,7 @@ module.exports = { directoryservice: [], organizations: ['cn-north-1'], guardduty: [], + macie2: [], wafregional: [], wafv2: [], waf: regions, diff --git a/helpers/aws/regions_gov.js b/helpers/aws/regions_gov.js index df2b454615..c559d52724 100644 --- a/helpers/aws/regions_gov.js +++ b/helpers/aws/regions_gov.js @@ -77,6 +77,7 @@ module.exports = { directoryservice: [], organizations: regions, guardduty: regions, + macie2: regions, wafregional: [], wafv2: regions, waf: regions, diff --git a/helpers/aws/regions_gov_fedramp_east_1.js b/helpers/aws/regions_gov_fedramp_east_1.js index 84ca9e0673..b6a1073e52 100644 --- a/helpers/aws/regions_gov_fedramp_east_1.js +++ b/helpers/aws/regions_gov_fedramp_east_1.js @@ -73,6 +73,7 @@ module.exports = { directoryservice: [], organizations: regions, guardduty: regions, + macie2: regions, wafregional: [], wafv2: regions, waf: regions, diff --git a/helpers/aws/regions_gov_fedramp_west_1.js b/helpers/aws/regions_gov_fedramp_west_1.js index b4793ef189..58577dc9b3 100644 --- a/helpers/aws/regions_gov_fedramp_west_1.js +++ b/helpers/aws/regions_gov_fedramp_west_1.js @@ -73,6 +73,7 @@ module.exports = { directoryservice: [], organizations: regions, guardduty: regions, + macie2: regions, wafregional: [], wafv2: regions, waf: regions, diff --git a/helpers/aws/resources.js b/helpers/aws/resources.js index e853f19aef..1362ce315a 100644 --- a/helpers/aws/resources.js +++ b/helpers/aws/resources.js @@ -374,6 +374,9 @@ module.exports = { listModels: 'ModelArn', describeModel: 'ModelDescription.ModelArn' }, + macie2: { + getAutomatedDiscoveryConfiguration: '', + }, managedblockchain: { listMembers: 'Arn', listNetworks: 'Arn', diff --git a/helpers/azure/api.js b/helpers/azure/api.js index c55ad527fd..4682c1e2d1 100644 --- a/helpers/azure/api.js +++ b/helpers/azure/api.js @@ -199,12 +199,12 @@ var serviceMap = { }, 'Virtual Machines': { - enabled: true, isSingleSource: true, InvAsset: 'vm_scaleset', InvService: 'virtualmachines', - InvResourceCategory: 'cloud_resources', InvResourceType: 'VM_ScaleSet', BridgeServiceName: 'virtualmachinescalesets', - BridgePluginCategoryName: 'Virtual Machines', BridgeProvider: 'Azure', BridgeCall: 'listAll', - BridgeArnIdentifier: '', BridgeIdTemplate: '', BridgeResourceType: 'virtualMachineScaleSets', + enabled: true, isSingleSource: true, InvAsset: 'vm_scaleset_vm', InvService: 'virtualmachines', + InvResourceCategory: 'cloud_resources', InvResourceType: 'VM_ScaleSet_VM', BridgeServiceName: 'virtualmachinescalesetvms', + BridgePluginCategoryName: 'Virtual Machines', BridgeProvider: 'Azure', BridgeCall: 'list', + BridgeArnIdentifier: '', BridgeIdTemplate: '', BridgeResourceType: 'virtualMachines', BridgeResourceNameIdentifier: 'name', BridgeExecutionService: 'Virtual Machines', - BridgeCollectionService: 'virtualmachinescalesets', DataIdentifier: 'data', + BridgeCollectionService: 'virtualmachinescalesetvms', DataIdentifier: 'data', }, 'Event Grid': { @@ -545,8 +545,7 @@ var calls = { virtualMachineScaleSets: { listAll: { url: 'https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Compute/virtualMachineScaleSets?api-version=2023-07-01' - }, - sendIntegration: serviceMap['Virtual Machines'] + } }, bastionHosts: { listAll: { @@ -909,8 +908,9 @@ var postcalls = { list: { reliesOnPath: 'virtualMachineScaleSets.listAll', properties: ['id'], - url: 'https://management.azure.com/{id}/virtualMachines?api-version=2020-12-01' - } + url: 'https://management.azure.com/{id}/virtualMachines?api-version=2025-11-01' + }, + sendIntegration: serviceMap['Virtual Machines'] }, virtualNetworkGateways: { listByResourceGroup: { diff --git a/helpers/google/index.js b/helpers/google/index.js index f8e2837e8d..32679d6f71 100644 --- a/helpers/google/index.js +++ b/helpers/google/index.js @@ -414,6 +414,7 @@ var isQuotaError = function(err) { function makeApiCall(client, originalUrl, callCb, nextToken, config) { let retries = []; var apiRetryAttempts = 3; + var quotaRetryAttempts = 6; // only for quota/access limit errors var apiRetryBackoff = 500; var apiRetryCap = 1000; var quotaRetryDelay = 60000; // 60 seconds (1 minute) for quota limit errors @@ -430,9 +431,10 @@ function makeApiCall(client, originalUrl, callCb, nextToken, config) { // Track the last error to determine retry strategy let lastError = null; + let failureCount = 0; async.retry({ - times: apiRetryAttempts, + times: Math.max(apiRetryAttempts, quotaRetryAttempts) + 1, interval: function(retryCount){ // Check if last error was a quota error - apply 1 minute delay for all quota errors if (lastError && isQuotaError(lastError)) { @@ -454,8 +456,9 @@ function makeApiCall(client, originalUrl, callCb, nextToken, config) { }, errorFilter: function(err) { lastError = err; - // Retry on rate errors or quota errors (for all API calls) - return isRateError(err) || isQuotaError(err); + failureCount++; + var maxRetries = isQuotaError(err) ? quotaRetryAttempts : (isRateError(err) ? apiRetryAttempts : 0); + return failureCount <= maxRetries; } }, function(cb) { diff --git a/helpers/oracle/regions.js b/helpers/oracle/regions.js index d36ef93060..8af1defa8b 100644 --- a/helpers/oracle/regions.js +++ b/helpers/oracle/regions.js @@ -23,14 +23,28 @@ var regions = [ 'me-jeddah-1', 'ap-chuncheon-1', 'me-dubai-1', + 'me-abudhabi-1', 'uk-cardiff-1', 'us-sanjose-1', 'mx-queretaro-1', 'eu-marseille-1', 'eu-milan-1', 'ap-singapore-1', + 'ap-singapore-2', 'af-johannesburg-1', - 'eu-stockholm-1' + 'af-casablanca-1', + 'eu-stockholm-1', + 'eu-paris-1', + 'eu-madrid-1', + 'eu-madrid-3', + 'eu-turin-1', + 'ap-batam-1', + 'ap-kulai-2', + 'me-riyadh-1', + 'mx-monterrey-1', + 'sa-bogota-1', + 'sa-valparaiso-1', + 'us-chicago-1' ]; module.exports = { diff --git a/package.json b/package.json index 741c0ba80f..3ef70b837f 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ }, "dependencies": { "@alicloud/pop-core": "^1.7.10", + "@aws-sdk/client-ec2": "^3.876.0", "@azure/data-tables": "^13.2.2", "@azure/storage-file-share": "^12.14.0", "@azure/storage-queue": "^12.13.0", diff --git a/plugins/aws/cloudformation/cloudformationAdminPriviliges.js b/plugins/aws/cloudformation/cloudformationAdminPriviliges.js index b778b56e7b..7d7c0d14b9 100644 --- a/plugins/aws/cloudformation/cloudformationAdminPriviliges.js +++ b/plugins/aws/cloudformation/cloudformationAdminPriviliges.js @@ -62,9 +62,9 @@ module.exports = { return cb(); } - var roleName = describeStacks.data.Stacks[0].RoleARN.split('/')[1] ? - describeStacks.data.Stacks[0].RoleARN.split('/')[1] : describeStacks.data.Stacks[0].RoleARN; - var adminPrivileged; + var roleNameArr = describeStacks.data.Stacks[0].RoleARN.split('/'); + var roleName = roleNameArr[roleNameArr.length - 1]; + var adminPrivileged = false; var listAttachedRolePolicies = helpers.addSource(cache, source, ['iam', 'listAttachedRolePolicies', defaultRegion, roleName]); @@ -75,24 +75,45 @@ module.exports = { var getRolePolicy = helpers.addSource(cache, source, ['iam', 'getRolePolicy', defaultRegion, roleName]); - if (!listAttachedRolePolicies || - listAttachedRolePolicies.err || - !listAttachedRolePolicies.data || - !listAttachedRolePolicies.data.AttachedPolicies) { + if (!listAttachedRolePolicies || !listRolePolicies) { + helpers.addResult(results, 0, + 'No IAM Attached Role Found', + region, resource); + return cb(); + } + + if (listAttachedRolePolicies.err || !listAttachedRolePolicies.data) { helpers.addResult(results, 3, `Unable to query for IAM attached policy for role "${roleName}": ${helpers.addError(listAttachedRolePolicies)}`, region, resource); return cb(); } - if (!listRolePolicies || listRolePolicies.err || !listRolePolicies.data || !listRolePolicies.data.PolicyNames) { + if (listRolePolicies.err || !listRolePolicies.data) { helpers.addResult(results, 3, - `Unable to query for IAM role policy for role "${roleName}": ${helpers.addError(listRolePolicies)}`, + `Unable to query for IAM role policy for role "${roleName}": ${helpers.addError(listRolePolicies)}`, region, resource); return cb(); } - for (var policy of listAttachedRolePolicies.data.AttachedPolicies) { + var listRoles = helpers.addSource(cache, source, ['iam', 'listRoles', defaultRegion]); + var enrichedRole = null; + if (listRoles && listRoles.data && Array.isArray(listRoles.data)) { + enrichedRole = listRoles.data.find(r => r.RoleName === roleName); + } + + var hasAttachedPolicies = listAttachedRolePolicies.data.AttachedPolicies && listAttachedRolePolicies.data.AttachedPolicies.length; + var hasInlinePolicies = listRolePolicies.data.PolicyNames && listRolePolicies.data.PolicyNames.length; + + var attachedPolicies = hasAttachedPolicies + ? listAttachedRolePolicies.data.AttachedPolicies + : (enrichedRole && enrichedRole.attachedPolicies && Array.isArray(enrichedRole.attachedPolicies) && enrichedRole.attachedPolicies.length ? enrichedRole.attachedPolicies : []); + + var inlinePolicyNames = hasInlinePolicies + ? listRolePolicies.data.PolicyNames + : (enrichedRole && enrichedRole.inlinePolicies && Array.isArray(enrichedRole.inlinePolicies) && enrichedRole.inlinePolicies.length ? enrichedRole.inlinePolicies : []); + + for (var policy of attachedPolicies) { if (!policy.PolicyArn) continue; if (policy.PolicyArn === managedAdminPolicy) { @@ -134,13 +155,13 @@ module.exports = { if (adminPrivileged) break; } - for (var policyName of listRolePolicies.data.PolicyNames) { + for (var policyName of inlinePolicyNames) { if (getRolePolicy && getRolePolicy[policyName] && getRolePolicy[policyName].data && getRolePolicy[policyName].data.PolicyDocument) { - let statements = getRolePolicy[policyName].data.PolicyDocument; - if (!statements) break; + let statements = helpers.normalizePolicyDocument(getRolePolicy[policyName].data.PolicyDocument); + if (!statements) continue; // Loop through statements to see if admin privileges for (let statement of statements) { diff --git a/plugins/aws/cloudfront/cloudfrontLoggingEnabled.js b/plugins/aws/cloudfront/cloudfrontLoggingEnabled.js index 6d23190f20..2fca857eba 100644 --- a/plugins/aws/cloudfront/cloudfrontLoggingEnabled.js +++ b/plugins/aws/cloudfront/cloudfrontLoggingEnabled.js @@ -82,9 +82,6 @@ module.exports = { helpers.addResult(results, 2, 'S3 legacy logging is not enabled', 'global', Distribution.ARN); } - } else { - helpers.addResult(results, 2, - 'S3 legacy logging is not enabled', 'global', Distribution.ARN); } }); diff --git a/plugins/aws/cloudtrail/cloudtrailBucketAccessLogging.js b/plugins/aws/cloudtrail/cloudtrailBucketAccessLogging.js index aa6099f37a..717fe9fc3b 100644 --- a/plugins/aws/cloudtrail/cloudtrailBucketAccessLogging.js +++ b/plugins/aws/cloudtrail/cloudtrailBucketAccessLogging.js @@ -106,7 +106,7 @@ module.exports = { 'Bucket: ' + trail.S3BucketName + ' has S3 access logs enabled', region, `arn:${awsOrGov}:s3:::` + trail.S3BucketName); } else { - helpers.addResult(results, 2, + helpers.addResult(results, 1, 'Bucket: ' + trail.S3BucketName + ' has S3 access logs disabled', region, `arn:${awsOrGov}:s3:::` + trail.S3BucketName); } diff --git a/plugins/aws/cloudtrail/cloudtrailBucketAccessLogging.spec.js b/plugins/aws/cloudtrail/cloudtrailBucketAccessLogging.spec.js index 397429acb9..a5ad27e0b0 100644 --- a/plugins/aws/cloudtrail/cloudtrailBucketAccessLogging.spec.js +++ b/plugins/aws/cloudtrail/cloudtrailBucketAccessLogging.spec.js @@ -131,11 +131,11 @@ describe('cloudtrailBucketAccessLogging', function () { }); }); - it('should FAIL if bucket has S3 access logs disabled', function (done) { + it('should WARN if bucket has S3 access logs disabled', function (done) { const cache = createCache([trails[1]], [listBuckets[1]], getBucketLogging[1]); cloudtrailBucketAccessLogging.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); - expect(results[0].status).to.equal(2); + expect(results[0].status).to.equal(1); done(); }); }); diff --git a/plugins/aws/cloudtrail/cloudtrailManagementEvents.js b/plugins/aws/cloudtrail/cloudtrailManagementEvents.js index 560c97f4f6..08dbc0bae4 100644 --- a/plugins/aws/cloudtrail/cloudtrailManagementEvents.js +++ b/plugins/aws/cloudtrail/cloudtrailManagementEvents.js @@ -42,48 +42,22 @@ module.exports = { var getEventSelectors = helpers.addSource(cache, source, ['cloudtrail', 'getEventSelectors', region, trail.TrailARN]); - if (!getEventSelectors || getEventSelectors.err || !getEventSelectors.data || - (!getEventSelectors.data.EventSelectors && !getEventSelectors.data.AdvancedEventSelectors)) { + if (!getEventSelectors || getEventSelectors.err || + !getEventSelectors.data || !getEventSelectors.data.EventSelectors) { helpers.addResult(results, 3, `Unable to query for event selectors: ${helpers.addError(getEventSelectors)}`, region, resource); return cb(); } - var managementEventsConfigured = false; - - if (getEventSelectors.data.AdvancedEventSelectors && - getEventSelectors.data.AdvancedEventSelectors.length) { - for (var advancedSelector of getEventSelectors.data.AdvancedEventSelectors) { - var hasManagementCategory = false; - var hasReadOnlyField = false; - - if (advancedSelector.FieldSelectors) { - for (var fieldSelector of advancedSelector.FieldSelectors) { - if (fieldSelector.Field === 'readOnly') hasReadOnlyField = true; - if (fieldSelector.Field === 'eventCategory' && - fieldSelector.Equals && - fieldSelector.Equals.indexOf('Management') > -1) { - hasManagementCategory = true; - } - } - } - - if (hasManagementCategory && !hasReadOnlyField) { - managementEventsConfigured = true; - break; - } - } - } else if (getEventSelectors.data.EventSelectors) { - for (var eventSelector of getEventSelectors.data.EventSelectors) { - if (eventSelector.IncludeManagementEvents && - eventSelector.ReadWriteType === 'All') { - managementEventsConfigured = true; - break; - } + var managementResourceFound = false; + for (var eventSelector of getEventSelectors.data.EventSelectors){ + if (eventSelector.IncludeManagementEvents) { + managementResourceFound = true; + break; } } - if (managementEventsConfigured) { + if (managementResourceFound) { helpers.addResult(results, 0, `CloudTrail trail "${trail.Name}" is configured to log management events`, region, resource); diff --git a/plugins/aws/cloudtrail/cloudtrailManagementEvents.spec.js b/plugins/aws/cloudtrail/cloudtrailManagementEvents.spec.js index 881c406a23..c061bf14b9 100644 --- a/plugins/aws/cloudtrail/cloudtrailManagementEvents.spec.js +++ b/plugins/aws/cloudtrail/cloudtrailManagementEvents.spec.js @@ -104,41 +104,6 @@ describe('cloudtrailManagementEvents', function () { }); }); - it('should FAIL if management events are read-only only', function (done) { - const cache = createCache([describeTrails[0]], { - TrailARN: describeTrails[0].TrailARN, - EventSelectors: [{ - ReadWriteType: 'ReadOnly', - IncludeManagementEvents: true, - DataResources: [], - ExcludeManagementEventSources: [] - }] - }); - cloudtrailManagementEvents.run(cache, {}, (err, results) => { - expect(results.length).to.equal(1); - expect(results[0].status).to.equal(2); - done(); - }); - }); - - it('should PASS if advanced event selectors log all management events', function (done) { - const cache = createCache([describeTrails[0]], { - TrailARN: describeTrails[0].TrailARN, - AdvancedEventSelectors: [{ - Name: 'Management events selector', - FieldSelectors: [{ - Field: 'eventCategory', - Equals: ['Management'] - }] - }] - }); - cloudtrailManagementEvents.run(cache, {}, (err, results) => { - expect(results.length).to.equal(1); - expect(results[0].status).to.equal(0); - done(); - }); - }); - it('should FAIL if CloudTrail trail is not configured to log management events', function (done) { const cache = createCache([describeTrails[1]], getEventSelectors[1]); cloudtrailManagementEvents.run(cache, {}, (err, results) => { diff --git a/plugins/aws/configservice/configServiceEnabled.js b/plugins/aws/configservice/configServiceEnabled.js index 3274aaee42..bbd237ba84 100644 --- a/plugins/aws/configservice/configServiceEnabled.js +++ b/plugins/aws/configservice/configServiceEnabled.js @@ -58,14 +58,6 @@ module.exports = { if (describeConfigurationRecorderStatus.data[0]) { var crs = describeConfigurationRecorderStatus.data[0]; - var recorder = describeConfigurationRecorders.data && - describeConfigurationRecorders.data[0]; - - if (!recorder || !recorder.recordingGroup || !recorder.recordingGroup.allSupported) { - helpers.addResult(results, 2, - 'Config Service is not configured to record all supported resources', region); - return rcb(); - } if (crs.recording) { if (crs.lastStatus && diff --git a/plugins/aws/configservice/configServiceEnabled.spec.js b/plugins/aws/configservice/configServiceEnabled.spec.js index fc15921712..8ec5cb6fa9 100644 --- a/plugins/aws/configservice/configServiceEnabled.spec.js +++ b/plugins/aws/configservice/configServiceEnabled.spec.js @@ -19,15 +19,6 @@ const describeConfigurationRecorders = [ "includeGlobalResourceTypes": false, "resourceTypes": [] } - }, - { // not recording all supported resources - "name": "default", - "roleARN": "arn:aws:iam::111111111111:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig", - "recordingGroup": { - "allSupported": false, - "includeGlobalResourceTypes": true, - "resourceTypes": ["AWS::EC2::Instance"] - } } ] @@ -166,15 +157,6 @@ describe('configServiceEnabled', () => { done(); }); }); - it('should FAIL if configuration recorders are not recording all supported resources', (done) => { - const cache = createCache([describeConfigurationRecorders[2]], [describeConfigurationRecorderStatus[0]]); - configServiceEnabled.run(cache, {}, (err, results) => { - expect(results.length).to.equal(2); - expect(results[0].status).to.equal(2); - done(); - }); - }); - it('should FAIL if configuration recorders does not have last status property', (done) => { const cache = createCache([describeConfigurationRecorders[0]], [describeConfigurationRecorderStatus[3]]); configServiceEnabled.run(cache, {}, (err, results) => { diff --git a/plugins/aws/ec2/appTierInstanceIamRole.js b/plugins/aws/ec2/appTierInstanceIamRole.js index 2088e85081..b7be76475f 100644 --- a/plugins/aws/ec2/appTierInstanceIamRole.js +++ b/plugins/aws/ec2/appTierInstanceIamRole.js @@ -16,7 +16,7 @@ module.exports = { ec2_app_tier_tag_key: { name: 'EC2 App-Tier Tag Key', description: 'Tag key to indicate App-Tier EC2 instances', - regex: '^.*$s', + regex: '^.*$', default: '' }, }, diff --git a/plugins/aws/ec2/openCIFS.js b/plugins/aws/ec2/openCIFS.js index bed75c0050..45272ace8a 100644 --- a/plugins/aws/ec2/openCIFS.js +++ b/plugins/aws/ec2/openCIFS.js @@ -6,10 +6,10 @@ module.exports = { category: 'EC2', domain: 'Compute', severity: 'High', - description: 'Determine if TCP or UDP port 445 for CIFS is open to the public', + description: 'Determine if UDP port 445 for CIFS is open to the public', more_info: 'While some ports such as HTTP and HTTPS are required to be open to the public to function properly, more sensitive services such as CIFS should be restricted to known IP addresses.', link: 'http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html', - recommended_action: 'Restrict TCP and UDP port 445 to known IP addresses', + recommended_action: 'Restrict UDP port 445 to known IP addresses', apis: ['EC2:describeSecurityGroups', 'EC2:describeNetworkInterfaces', 'Lambda:listFunctions'], settings: { ec2_skip_unused_groups: { @@ -66,7 +66,6 @@ module.exports = { var regions = helpers.regions(settings); var ports = { - 'tcp': [445], 'udp': [445] }; diff --git a/plugins/aws/ec2/openCIFS.spec.js b/plugins/aws/ec2/openCIFS.spec.js index 9565ff9122..5acf3ee44c 100644 --- a/plugins/aws/ec2/openCIFS.spec.js +++ b/plugins/aws/ec2/openCIFS.spec.js @@ -17,7 +17,7 @@ const describeSecurityGroups = [ "IpPermissions": [ { "FromPort": 0, - "IpProtocol": "tcp", + "IpProtocol": "udp", "IpRanges": [ { "CidrIp": "0.0.0.0/0" @@ -63,29 +63,6 @@ const describeSecurityGroups = [ } ], "VpcId": "vpc-99de2fe4" - }, - { - "Description": "CIFS UDP", - "GroupName": "CIFS-UDP-Access", - "IpPermissions": [ - { - "FromPort": 445, - "IpProtocol": "udp", - "IpRanges": [ - { - "CidrIp": "0.0.0.0/0" - } - ], - "Ipv6Ranges": [], - "PrefixListIds": [], - "ToPort": 445, - "UserIdGroupPairs": [] - } - ], - "OwnerId": "111122223333", - "GroupId": "sg-00263f564442dfec", - "IpPermissionsEgress": [], - "VpcId": "vpc-99de2fe4" } ]; @@ -242,17 +219,8 @@ describe('openCIFS', function () { }); }); - it('should FAIL if security group has CIFS TCP port open to public', function (done) { - const cache = createCache([describeSecurityGroups[1]], [describeNetworkInterfaces[0]], [listFunctions[0]]); - openCIFS.run(cache, {}, (err, results) => { - expect(results.length).to.equal(1); - expect(results[0].status).to.equal(2); - done(); - }); - }); - it('should FAIL if security group has CIFS UDP port open to public', function (done) { - const cache = createCache([describeSecurityGroups[2]], [describeNetworkInterfaces[0]], [listFunctions[0]]); + const cache = createCache([describeSecurityGroups[1]], [describeNetworkInterfaces[0]], [listFunctions[0]]); openCIFS.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(2); diff --git a/plugins/aws/ec2/openRDP.js b/plugins/aws/ec2/openRDP.js index f1c3e337db..4a1a801f93 100644 --- a/plugins/aws/ec2/openRDP.js +++ b/plugins/aws/ec2/openRDP.js @@ -6,10 +6,10 @@ module.exports = { category: 'EC2', domain: 'Compute', severity: 'High', - description: 'Determine if TCP or UDP port 3389 for RDP is open to the public', + description: 'Determine if TCP port 3389 for RDP is open to the public', more_info: 'While some ports such as HTTP and HTTPS are required to be open to the public to function properly, more sensitive services such as RDP should be restricted to known IP addresses.', link: 'http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html', - recommended_action: 'Restrict TCP and UDP port 3389 to known IP addresses', + recommended_action: 'Restrict TCP port 3389 to known IP addresses', apis: ['EC2:describeSecurityGroups', 'EC2:describeNetworkInterfaces', 'Lambda:listFunctions'], settings: { ec2_skip_unused_groups: { @@ -69,8 +69,7 @@ module.exports = { var regions = helpers.regions(settings); var ports = { - 'tcp': [3389], - 'udp': [3389] + 'tcp': [3389] }; var service = 'RDP'; diff --git a/plugins/aws/ec2/openSSH.js b/plugins/aws/ec2/openSSH.js index 7249274715..854801d769 100644 --- a/plugins/aws/ec2/openSSH.js +++ b/plugins/aws/ec2/openSSH.js @@ -6,10 +6,10 @@ module.exports = { category: 'EC2', domain: 'Compute', severity: 'High', - description: 'Determine if TCP or UDP port 22 for SSH is open to the public', + description: 'Determine if TCP port 22 for SSH is open to the public', more_info: 'While some ports such as HTTP and HTTPS are required to be open to the public to function properly, more sensitive services such as SSH should be restricted to known IP addresses.', link: 'http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html', - recommended_action: 'Restrict TCP and UDP port 22 to known IP addresses', + recommended_action: 'Restrict TCP port 22 to known IP addresses', apis: ['EC2:describeSecurityGroups', 'EC2:describeNetworkInterfaces', 'Lambda:listFunctions'], settings: { ec2_skip_unused_groups: { @@ -69,8 +69,7 @@ module.exports = { var regions = helpers.regions(settings); var ports = { - 'tcp': [22], - 'udp': [22] + 'tcp': [22] }; var service = 'SSH'; diff --git a/plugins/aws/ec2/webTierInstanceIamRole.js b/plugins/aws/ec2/webTierInstanceIamRole.js index 42b03a5e0b..a695150386 100644 --- a/plugins/aws/ec2/webTierInstanceIamRole.js +++ b/plugins/aws/ec2/webTierInstanceIamRole.js @@ -16,7 +16,7 @@ module.exports = { ec2_web_tier_tag_key: { name: 'EC2 Web-Tier Tag Key', description: 'Tag key to indicate Web-Tier EC2 instances', - regex: '^.*$s', + regex: '^.*$', default: '' }, }, diff --git a/plugins/aws/ecr/ecrRepositoryTagImmutability.js b/plugins/aws/ecr/ecrRepositoryTagImmutability.js index 9aade5142c..3cf11deb6d 100644 --- a/plugins/aws/ecr/ecrRepositoryTagImmutability.js +++ b/plugins/aws/ecr/ecrRepositoryTagImmutability.js @@ -41,13 +41,17 @@ module.exports = { var arn = repository.repositoryArn; var immutability = repository.imageTagMutability; - if (immutability == 'IMMUTABLE') { + if (immutability === 'IMMUTABLE') { helpers.addResult(results, 0, 'ECR repository mutability setting is set to IMMUTABLE', region, arn); + } else if (immutability === 'IMMUTABLE_WITH_EXCLUSION') { + helpers.addResult(results, 0, + 'ECR repository mutability setting is set to IMMUTABLE_WITH_EXCLUSION', + region, arn); } else { helpers.addResult(results, 2, - 'ECR repository mutability setting is set to MUTABLE', + 'ECR repository mutability setting is set to ' + immutability, region, arn); } } diff --git a/plugins/aws/ecr/ecrRepositoryTagImmutability.spec.js b/plugins/aws/ecr/ecrRepositoryTagImmutability.spec.js index 34c1e8015d..a17487d36c 100644 --- a/plugins/aws/ecr/ecrRepositoryTagImmutability.spec.js +++ b/plugins/aws/ecr/ecrRepositoryTagImmutability.spec.js @@ -30,6 +30,40 @@ const describeRepositories = [ "encryptionType": "AES256" } }, + { + "repositoryArn": "arn:aws:ecr:us-east-1:111111111111:repository/test", + "registryId": "111111111111", + "repositoryName": "test", + "repositoryUri": "111111111111.dkr.ecr.us-east-1.amazonaws.com/test", + "createdAt": "2021-07-24T12:20:58.000Z", + "imageTagMutability": "IMMUTABLE_WITH_EXCLUSION", + "imageTagMutabilityExclusionFilters": [ + { "filterType": "WILDCARD", "filter": "latest*" } + ], + "imageScanningConfiguration": { + "scanOnPush": false + }, + "encryptionConfiguration": { + "encryptionType": "AES256" + } + }, + { + "repositoryArn": "arn:aws:ecr:us-east-1:111111111111:repository/test", + "registryId": "111111111111", + "repositoryName": "test", + "repositoryUri": "111111111111.dkr.ecr.us-east-1.amazonaws.com/test", + "createdAt": "2021-07-24T12:20:58.000Z", + "imageTagMutability": "MUTABLE_WITH_EXCLUSION", + "imageTagMutabilityExclusionFilters": [ + { "filterType": "WILDCARD", "filter": "prod*" } + ], + "imageScanningConfiguration": { + "scanOnPush": false + }, + "encryptionConfiguration": { + "encryptionType": "AES256" + } + }, ] const createCache = (ecrRepository) => { @@ -82,6 +116,22 @@ describe('ecrRepositoryTagImmutability', () => { }) }); + it('should PASS if repository is immutable with exclusion filters', () => { + const cache = createCache([describeRepositories[2]]); + ecrRepositoryTagImmutability.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + }) + }); + + it('should FAIL if repository is mutable with exclusion filters', () => { + const cache = createCache([describeRepositories[3]]); + ecrRepositoryTagImmutability.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + }) + }); + it('should UNKNOWN if unable to get repository policy', () => { const cache = repositoryErrorCache(); ecrRepositoryTagImmutability.run(cache,{}, (err, results) => { diff --git a/plugins/aws/eks/eksKubernetesVersion.js b/plugins/aws/eks/eksKubernetesVersion.js index 26d362c82b..81b000a8d6 100644 --- a/plugins/aws/eks/eksKubernetesVersion.js +++ b/plugins/aws/eks/eksKubernetesVersion.js @@ -45,7 +45,10 @@ module.exports = { '1.29': '2025-03-23', '1.30': '2025-07-23', '1.31': '2025-11-26', - '1.32': '2026-03-23' + '1.32': '2026-03-23', + '1.33': '2026-06-29', + '1.34': '2026-12-02', + '1.35': '2027-03-27' }; var outdatedVersions = { diff --git a/plugins/aws/eks/eksKubernetesVersion.spec.js b/plugins/aws/eks/eksKubernetesVersion.spec.js index da6e641bb6..2b01ccbf93 100644 --- a/plugins/aws/eks/eksKubernetesVersion.spec.js +++ b/plugins/aws/eks/eksKubernetesVersion.spec.js @@ -82,7 +82,7 @@ describe('eksKubernetesVersion', function () { "cluster": { "name": "mycluster", "arn": "arn:aws:eks:us-east-1:012345678911:cluster/mycluster", - "version": "1.33", + "version": "1.35", } } ); diff --git a/plugins/aws/iam/accessKeysLastUsed.js b/plugins/aws/iam/accessKeysLastUsed.js index e0078c4e65..b8a29e1317 100644 --- a/plugins/aws/iam/accessKeysLastUsed.js +++ b/plugins/aws/iam/accessKeysLastUsed.js @@ -21,13 +21,13 @@ module.exports = { name: 'Access Keys Last Used Fail', description: 'Return a failing result when access keys exceed this number of days without being used', regex: '^[1-9]{1}[0-9]{0,3}$', - default: 45 + default: 180 }, access_keys_last_used_warn: { name: 'Access Keys Last Used Warn', description: 'Return a warning result when access keys exceed this number of days without being used', regex: '^[1-9]{1}[0-9]{0,3}$', - default: 30 + default: 90 } }, asl: { @@ -38,7 +38,7 @@ module.exports = { property: 'access_key_1_last_used_date', transform: 'DAYSFROM', op: 'GT', - value: 45 + value: 90 } ] }, diff --git a/plugins/aws/iam/accessKeysLastUsed.spec.js b/plugins/aws/iam/accessKeysLastUsed.spec.js index 4da05c61dc..92468d010c 100644 --- a/plugins/aws/iam/accessKeysLastUsed.spec.js +++ b/plugins/aws/iam/accessKeysLastUsed.spec.js @@ -147,20 +147,14 @@ describe('accessKeysLastUsed', function () { describe('run', function () { it('should PASS if the user access key was last used within the pass limit', function (done) { const cache = createCache([generateCredentialReport[0],generateCredentialReport[0],generateCredentialReport[1]]); - accessKeysLastUsed.run(cache, {}, (err, results) => { + var settings = { + access_keys_last_used_fail: 180, + access_keys_last_used_warn: 90 + }; + accessKeysLastUsed.run(cache, settings, (err, results) => { expect(results.length).to.equal(2); expect(results[0].status).to.equal(0); - expect(results[1].status).to.equal(0); - done(); - }); - }); - - it('should FAIL if the user access key was last used more than 45 days ago', function (done) { - const cache = createCache([generateCredentialReport[0],generateCredentialReport[0],generateCredentialReport[2]]); - accessKeysLastUsed.run(cache, {}, (err, results) => { - expect(results.length).to.equal(2); - expect(results[0].status).to.equal(2); - expect(results[1].status).to.equal(2); + expect(results[0].status).to.equal(0); done(); }); }); @@ -181,7 +175,11 @@ describe('accessKeysLastUsed', function () { it('should FAIL if the user access key was last used more than the fail limit', function (done) { const cache = createCache([generateCredentialReport[0],generateCredentialReport[0],generateCredentialReport[3]]); - accessKeysLastUsed.run(cache, {}, (err, results) => { + var settings = { + access_keys_last_used_fail: 180, + access_keys_last_used_warn: 90 + }; + accessKeysLastUsed.run(cache, settings, (err, results) => { expect(results.length).to.equal(2); expect(results[0].status).to.equal(2); expect(results[1].status).to.equal(2); diff --git a/plugins/aws/iam/accessKeysRotated.js b/plugins/aws/iam/accessKeysRotated.js index 56a190012f..18713ffabb 100644 --- a/plugins/aws/iam/accessKeysRotated.js +++ b/plugins/aws/iam/accessKeysRotated.js @@ -6,7 +6,7 @@ module.exports = { category: 'IAM', domain: 'Identity and Access Management', severity: 'Low', - description: 'Ensures access keys are not older than 90 days in order to reduce accidental exposures', + description: 'Ensures access keys are not older than 180 days in order to reduce accidental exposures', more_info: 'Access keys should be rotated frequently to avoid having them accidentally exposed.', link: 'http://docs.aws.amazon.com/IAM/latest/UserGuide/ManagingCredentials.html', recommended_action: 'To rotate an access key, first create a new key, replace the key and secret throughout your app or scripts, then set the previous key to disabled. Once you ensure that no services are broken, then fully delete the old key.', @@ -25,13 +25,13 @@ module.exports = { name: 'Access Keys Rotated Fail', description: 'Return a failing result when access keys exceed this number of days without being rotated', regex: '^[1-9]{1}[0-9]{0,3}$', - default: 90 + default: 180 }, access_keys_rotated_warn: { name: 'Access Keys Rotated Warn', description: 'Return a warning result when access keys exceed this number of days without being rotated', regex: '^[1-9]{1}[0-9]{0,3}$', - default: 45 + default: 90 } }, realtime_triggers: ['iam:CreateAccessKey','iam:DeleteAccessKey'], diff --git a/plugins/aws/iam/accessKeysRotated.spec.js b/plugins/aws/iam/accessKeysRotated.spec.js index e83c07c1e4..726e449d55 100644 --- a/plugins/aws/iam/accessKeysRotated.spec.js +++ b/plugins/aws/iam/accessKeysRotated.spec.js @@ -4,7 +4,7 @@ const accessKeysRotated = require('./accessKeysRotated'); var warnDate = new Date(); warnDate.setMonth(warnDate.getMonth() - 4); var passDate = new Date(); -passDate.setMonth(passDate.getMonth() - 1); +passDate.setMonth(passDate.getMonth() - 2); var failDate = new Date(); failDate.setMonth(failDate.getMonth() - 7); @@ -147,7 +147,11 @@ describe('accessKeysRotated', function () { describe('run', function () { it('should PASS if the user access key was last rotated within the pass limit', function (done) { const cache = createCache([generateCredentialReport[0], generateCredentialReport[2]]); - accessKeysRotated.run(cache, {}, (err, results) => { + var settings = { + access_keys_rotated_fail: 180, + access_keys_rotated_warn: 90 + }; + accessKeysRotated.run(cache, settings, (err, results) => { expect(results.length).to.equal(2); expect(results[0].status).to.equal(0); expect(results[1].status).to.equal(0); @@ -155,16 +159,6 @@ describe('accessKeysRotated', function () { }); }); - it('should FAIL if the user access key was last rotated more than 90 days ago', function (done) { - const cache = createCache([generateCredentialReport[0], generateCredentialReport[1]]); - accessKeysRotated.run(cache, {}, (err, results) => { - expect(results.length).to.equal(2); - expect(results[0].status).to.equal(2); - expect(results[1].status).to.equal(2); - done(); - }); - }); - it('should WARN if the user access key was last rotated within the warn limit', function (done) { const cache = createCache([generateCredentialReport[0], generateCredentialReport[1]]); var settings = { @@ -181,7 +175,11 @@ describe('accessKeysRotated', function () { it('should FAIL if the user access key was last rotated more than the fail limit', function (done) { const cache = createCache([generateCredentialReport[0],generateCredentialReport[0],generateCredentialReport[3]]); - accessKeysRotated.run(cache, {}, (err, results) => { + var settings = { + access_keys_rotated_fail: 180, + access_keys_rotated_warn: 90 + }; + accessKeysRotated.run(cache, settings, (err, results) => { expect(results.length).to.equal(2); expect(results[0].status).to.equal(2); expect(results[1].status).to.equal(2); diff --git a/plugins/aws/iam/iamPoliciesPresent.js b/plugins/aws/iam/iamPoliciesPresent.js index 5d35354e32..279c2bb844 100644 --- a/plugins/aws/iam/iamPoliciesPresent.js +++ b/plugins/aws/iam/iamPoliciesPresent.js @@ -86,8 +86,20 @@ module.exports = { } } + if (role.attachedPolicies && Array.isArray(role.attachedPolicies) && role.attachedPolicies.length) { + for (let policy of role.attachedPolicies) { + if (!attachedPolicies.includes(policy.PolicyName)) attachedPolicies.push(policy.PolicyName); + } + } + if (listRolePolicies.data && listRolePolicies.data.PolicyNames) attachedPolicies = attachedPolicies.concat(listRolePolicies.data.PolicyNames); + if (role.inlinePolicies && Array.isArray(role.inlinePolicies) && role.inlinePolicies.length) { + for (let policy of role.inlinePolicies) { + if (!attachedPolicies.includes(policy)) attachedPolicies.push(policy); + } + } + for (let policy of config.iam_required_policy_names) { if (!attachedPolicies.includes(policy)) difference.push(policy); } diff --git a/plugins/aws/iam/iamRolePolicies.js b/plugins/aws/iam/iamRolePolicies.js index 9180eeb59d..bcecc7dbf1 100644 --- a/plugins/aws/iam/iamRolePolicies.js +++ b/plugins/aws/iam/iamRolePolicies.js @@ -252,8 +252,54 @@ module.exports = { } } + if (role.attachedPolicies && Array.isArray(role.attachedPolicies) && role.attachedPolicies.length) { + for (var enrichedPolicy of role.attachedPolicies) { + if (enrichedPolicy.PolicyArn === managedAdminPolicy) { + if (config.iam_policy_message_format) { + roleFailures.admin = 'managedAdminPolicy'; + } else { + roleFailures.push('Role has managed AdministratorAccess policy'); + } + break; + } + + if (config.ignore_aws_managed_iam_policies && new RegExp(`^arn:${awsOrGov}:iam::aws:.*`).test(enrichedPolicy.PolicyArn)) continue; + + if (config.ignore_customer_managed_iam_policies && new RegExp(`^arn:${awsOrGov}:iam::[0-9]{12}:.*`).test(enrichedPolicy.PolicyArn)) continue; + + var enrichedGetPolicy = helpers.addSource(cache, source, + ['iam', 'getPolicy', region, enrichedPolicy.PolicyArn]); + + if (enrichedGetPolicy && + enrichedGetPolicy.data && + enrichedGetPolicy.data.Policy && + enrichedGetPolicy.data.Policy.DefaultVersionId) { + var enrichedGetPolicyVersion = helpers.addSource(cache, source, + ['iam', 'getPolicyVersion', region, enrichedPolicy.PolicyArn]); + + if (enrichedGetPolicyVersion && + enrichedGetPolicyVersion.data && + enrichedGetPolicyVersion.data.PolicyVersion && + enrichedGetPolicyVersion.data.PolicyVersion.Document) { + let enrichedStatements = helpers.normalizePolicyDocument( + enrichedGetPolicyVersion.data.PolicyVersion.Document); + if (!enrichedStatements) break; + + if (config.iam_policy_message_format) { + addRoleFailuresPolicyName(roleFailures, enrichedStatements, 'managed', enrichedPolicy.PolicyName, config.ignore_service_specific_wildcards, allowedRegex, config.ignore_iam_policy_resource_wildcards); + } else { + addRoleFailures(roleFailures, enrichedStatements, 'managed', config.ignore_service_specific_wildcards, allowedRegex, config.ignore_iam_policy_resource_wildcards); + } + } + } + } + } + + var processedInlinePolicies = new Set(); + if (listRolePolicies.data && - listRolePolicies.data.PolicyNames) { + listRolePolicies.data.PolicyNames && + listRolePolicies.data.PolicyNames.length) { for (var p in listRolePolicies.data.PolicyNames) { var policyName = listRolePolicies.data.PolicyNames[p]; @@ -263,8 +309,10 @@ module.exports = { getRolePolicy[policyName].data && getRolePolicy[policyName].data.PolicyDocument) { - var statements = getRolePolicy[policyName].data.PolicyDocument; - if (!statements) break; + processedInlinePolicies.add(policyName); + var policyDoc = getRolePolicy[policyName].data.PolicyDocument; + var statements = Array.isArray(policyDoc) ? policyDoc : helpers.normalizePolicyDocument(policyDoc); + if (!statements) continue; if (config.iam_policy_message_format) { addRoleFailuresPolicyName(roleFailures, statements, 'inline', policyName, config.ignore_service_specific_wildcards, allowedRegex, config.ignore_iam_policy_resource_wildcards); } else { @@ -274,13 +322,30 @@ module.exports = { } } + if (role.inlinePolicies && Array.isArray(role.inlinePolicies) && role.inlinePolicies.length) { + for (var enrichedInlinePolicy of role.inlinePolicies) { + if (!enrichedInlinePolicy || !enrichedInlinePolicy.PolicyDocument) continue; + + var enrichedPolicyName = enrichedInlinePolicy.PolicyName; + if (processedInlinePolicies.has(enrichedPolicyName)) continue; + + var enrichedPolicyDoc = enrichedInlinePolicy.PolicyDocument; + var enrichedStatementsInline = Array.isArray(enrichedPolicyDoc) ? enrichedPolicyDoc : helpers.normalizePolicyDocument(enrichedPolicyDoc); + if (!enrichedStatementsInline) continue; + if (config.iam_policy_message_format) { + addRoleFailuresPolicyName(roleFailures, enrichedStatementsInline, 'inline', enrichedPolicyName, config.ignore_service_specific_wildcards, allowedRegex, config.ignore_iam_policy_resource_wildcards); + } else { + addRoleFailures(roleFailures, enrichedStatementsInline, 'inline', config.ignore_service_specific_wildcards, allowedRegex, config.ignore_iam_policy_resource_wildcards); + } + } + } + if (config.iam_policy_message_format) { compileFormattedResults(roleFailures, role, results, custom); } else { compileSimpleResults(roleFailures, role, results, custom); } - cb(); }, function(){ callback(null, results, source); @@ -407,7 +472,7 @@ function hasFailures(roleFailures) { if (roleFailures.managed.allActionsSelectedResources.length) return true; if (roleFailures.managed.actionsAllResources.length) return true; if (Object.keys(roleFailures.managed.wildcardActions).length) return true; - if (roleFailures.managed.regexMismatch.length) return true; + if (Object.keys(roleFailures.managed.regexMismatch).length) return true; } if (roleFailures.inline) { @@ -415,7 +480,7 @@ function hasFailures(roleFailures) { if (roleFailures.inline.allActionsSelectedResources.length) return true; if (roleFailures.inline.actionsAllResources.length) return true; if (Object.keys(roleFailures.inline.wildcardActions).length) return true; - if (roleFailures.inline.regexMismatch.length) return true; + if (Object.keys(roleFailures.inline.regexMismatch).length) return true; } return false; diff --git a/plugins/aws/iam/iamSupportPolicy.js b/plugins/aws/iam/iamSupportPolicy.js index 151de61f92..dab41998c9 100644 --- a/plugins/aws/iam/iamSupportPolicy.js +++ b/plugins/aws/iam/iamSupportPolicy.js @@ -9,61 +9,37 @@ module.exports = { more_info: 'AWS provides a support center that can be used for incident notification and response, as well as technical support and customer services. An IAM Role should be present to allow authorized users to manage incidents with AWS Support.', link: 'https://docs.aws.amazon.com/awssupport/latest/user/accessing-support.html', recommended_action: 'Ensure that an IAM role has permission to access support center.', - apis: ['IAM:listRoles', 'IAM:listAttachedRolePolicies'], - realtime_triggers: ['iam:CreateRole','iam:DeleteRole','iam:AttachRolePolicy','iam:DetachRolePolicy'], + apis: ['IAM:listPolicies'], + realtime_triggers: ['iam:CreateRole','iam:DeleteRole','iam:AttachRolePolicy', 'iam:DetachRolePolicy','iam:CreateUser','iam:DeleteUser','iam:AttachUserPolicy','iam:DetachUserPolicy','iam:CreateGroup','iam:DeleteGroup','iam:AttachGroupPolicy','iam:DetachGroupPolicy'], run: function(cache, settings, callback) { var results = []; var source = {}; var region = helpers.defaultRegion(settings); - var supportPolicyArn = `arn:${helpers.defaultPartition(settings)}:iam::aws:policy/AWSSupportAccess`; - var listRoles = helpers.addSource(cache, source, ['iam', 'listRoles', region]); + const listPolicies = helpers.addSource(cache, source, + ['iam', 'listPolicies', region]); - if (!listRoles) return callback(null, results, source); + if (!listPolicies) return callback(null, results, source); - if (listRoles.err || !listRoles.data) { + if (listPolicies.err || !listPolicies.data) { helpers.addResult(results, 3, - 'Unable to query for IAM roles: ' + helpers.addError(listRoles)); + 'Unable to query for IAM policies: ' + helpers.addError(listPolicies)); return callback(null, results, source); } - if (!listRoles.data.length) { + if (!listPolicies.data.length) { helpers.addResult(results, 0, 'No IAM policies found'); return callback(null, results, source); } - var supportRoleArn = null; + var found = listPolicies.data.find(policy => policy.PolicyName == 'AWSSupportAccess'); - for (var role of listRoles.data) { - if (!role.RoleName || supportRoleArn) continue; - - var listAttachedRolePolicies = helpers.addSource(cache, source, - ['iam', 'listAttachedRolePolicies', region, role.RoleName]); - - if (!listAttachedRolePolicies || listAttachedRolePolicies.err) { - helpers.addResult(results, 3, - 'Unable to query for IAM attached policy for role: ' + role.RoleName + ': ' + - helpers.addError(listAttachedRolePolicies), 'global', role.Arn); - continue; - } - - if (listAttachedRolePolicies.data && - listAttachedRolePolicies.data.AttachedPolicies) { - for (var policy of listAttachedRolePolicies.data.AttachedPolicies) { - if (policy.PolicyArn === supportPolicyArn) { - supportRoleArn = role.Arn; - break; - } - } - } - } - - if (supportRoleArn) { + if (found) { helpers.addResult(results, 0, - 'AWSSupportAccess policy is attached to a user, role or group', 'global', supportRoleArn); - } else if (!results.length) { + 'AWSSupportAccess policy is attached to a user, role or group', 'global', found.Arn); + } else { helpers.addResult(results, 2, 'No role, user or group attached to the AWSSupportAccess policy', 'global'); } diff --git a/plugins/aws/iam/iamSupportPolicy.spec.js b/plugins/aws/iam/iamSupportPolicy.spec.js index 54d82ec719..d5a294ad68 100644 --- a/plugins/aws/iam/iamSupportPolicy.spec.js +++ b/plugins/aws/iam/iamSupportPolicy.spec.js @@ -1,133 +1,119 @@ const expect = require('chai').expect; var iamSupportPolicy = require('./iamSupportPolicy'); -const supportPolicyArn = 'arn:aws:iam::aws:policy/AWSSupportAccess'; - -const listRoles = [ +const listPolicies = [ { - RoleName: 'support-role', - Arn: 'arn:aws:iam::111111111111:role/support-role' + PolicyName: "CloudTrailCloudwatchRole", + PolicyId: "ANPAYE32SRU52MRBE7GDH", + Arn: "arn:aws:iam::111111111111:policy/CloudTrailCloudwatchRole", + Path: "/", + DefaultVersionId: "v2", + AttachmentCount: 0, + PermissionsBoundaryUsageCount: 0, + IsAttachable: true, + CreateDate: "", + UpdateDate: "", + Tags: [], }, { - RoleName: 'other-role', - Arn: 'arn:aws:iam::111111111111:role/other-role' - } -]; - -const listAttachedRolePolicies = { - 'support-role': { - AttachedPolicies: [ - { - PolicyName: 'AWSSupportAccess', - PolicyArn: supportPolicyArn - } - ] + PolicyName: "AWSSupportAccess", + PolicyId: "ANPAYE32SRU52MRBE7GDH", + Arn: "arn:aws:iam::111111111111:policy/AWSSupportAccess", + Path: "/", + DefaultVersionId: "v2", + AttachmentCount: 0, + PermissionsBoundaryUsageCount: 0, + IsAttachable: true, + CreateDate: "", + UpdateDate: "", + Tags: [], }, - 'other-role': { - AttachedPolicies: [ - { - PolicyName: 'ReadOnlyAccess', - PolicyArn: 'arn:aws:iam::aws:policy/ReadOnlyAccess' - } - ] + { + PolicyName: "AWSSupportAccess", + PolicyId: "ANPAYE32SRU52MRBE7GDH", + Arn: "arn:aws:iam::111111111111:policy/AWSSupportAccess", + Path: "/", + DefaultVersionId: "v2", + AttachmentCount: 1, + PermissionsBoundaryUsageCount: 0, + IsAttachable: true, + CreateDate: "", + UpdateDate: "", + Tags: [], } -}; +]; -const createCache = (roles, attachedPoliciesByRole) => { - var cache = { +const createCache = (policies, entities) => { + return { iam: { - listRoles: { - 'us-east-1': { - data: roles + listPolicies: { + "us-east-1": { + data: policies } - }, - listAttachedRolePolicies: { - 'us-east-1': {} + } } - }; - - if (roles && roles.length) { - roles.forEach(function(role) { - if (!role.RoleName) return; - cache.iam.listAttachedRolePolicies['us-east-1'][role.RoleName] = { - data: attachedPoliciesByRole && attachedPoliciesByRole[role.RoleName] ? - attachedPoliciesByRole[role.RoleName] : { AttachedPolicies: [] } - }; - }); } - return cache; -}; +} -const createErrorCache = () => { +const createNullCachePolicies = () => { return { iam: { - listRoles: { - 'us-east-1': { - err: { - message: 'error listing roles' - } + listPolicies: { + "us-east-1": { + data: null } - } + }, } - }; -}; + } +} -const createNullCache = () => { +const createNullCacheEntities = (policies) => { return { iam: { - listRoles: { - 'us-east-1': null + listPolicies: { + "us-east-1": { + data: policies + } + } } - }; -}; + } +} -describe('iamSupportPolicy', function () { - describe('run', function () { - it('should PASS if AWSSupportAccess is attached to a role', function (done) { - const cache = createCache([listRoles[0]], listAttachedRolePolicies); +describe('iamSupportPolicy',() =>{ + describe('run', () => { + it('should PASS if no policy attachment to access support center',() => { + const cache = createCache([listPolicies[2]]); iamSupportPolicy.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(0); - done(); - }); + }) }); - it('should PASS if no roles found', function (done) { + it('should PASS if no policies',() => { const cache = createCache([]); iamSupportPolicy.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(0); - done(); - }); + }) }); - - it('should FAIL if no role has AWSSupportAccess attached', function (done) { - const cache = createCache([listRoles[1]], listAttachedRolePolicies); + + it('should FAIL if no policy attachment to access support center',() => { + const cache = createCache([listPolicies[0]]); iamSupportPolicy.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(2); - done(); - }); + }) }); - it('should UNKNOWN if unable to query for IAM roles', function (done) { - const cache = createErrorCache(); + it('should UNKNOWN if no policy returned',() => { + const cache = createNullCachePolicies(); iamSupportPolicy.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(3); - done(); - }); - }); - - it('should not return anything if list roles response not found', function (done) { - const cache = createNullCache(); - iamSupportPolicy.run(cache, {}, (err, results) => { - expect(results.length).to.equal(0); - done(); }); }); - }); -}); + }) +}) \ No newline at end of file diff --git a/plugins/aws/iam/iamUserAdmins.js b/plugins/aws/iam/iamUserAdmins.js index 27b154a0d7..5c8da755fb 100644 --- a/plugins/aws/iam/iamUserAdmins.js +++ b/plugins/aws/iam/iamUserAdmins.js @@ -119,8 +119,50 @@ module.exports = { if (listAttachedUserPolicies.data && listAttachedUserPolicies.data.AttachedPolicies) { for (var a in listAttachedUserPolicies.data.AttachedPolicies) { - var policy = listAttachedUserPolicies.data.AttachedPolicies[a]; + var attachedPolicy = listAttachedUserPolicies.data.AttachedPolicies[a]; + if (!attachedPolicy.PolicyArn) continue; + + if (attachedPolicy.PolicyArn === managedAdminPolicy) { + userAdmins.push({name: user.UserName, arn: user.Arn}); + return cb(); + } + + var managedGetPolicy = helpers.addSource(cache, source, + ['iam', 'getPolicy', region, attachedPolicy.PolicyArn]); + + if (managedGetPolicy && + managedGetPolicy.data && + managedGetPolicy.data.Policy && + managedGetPolicy.data.Policy.DefaultVersionId) { + var managedGetPolicyVersion = helpers.addSource(cache, source, + ['iam', 'getPolicyVersion', region, attachedPolicy.PolicyArn]); + + if (managedGetPolicyVersion && + managedGetPolicyVersion.data && + managedGetPolicyVersion.data.PolicyVersion && + managedGetPolicyVersion.data.PolicyVersion.Document) { + let managedStatements = helpers.normalizePolicyDocument( + managedGetPolicyVersion.data.PolicyVersion.Document); + if (!managedStatements) break; + + // Loop through statements to see if admin privileges + for (let managedStmt of managedStatements) { + if (managedStmt.Effect && managedStmt.Effect.toUpperCase() === 'ALLOW' && + managedStmt.Action && managedStmt.Action.indexOf('*') > -1 && + managedStmt.Resource && managedStmt.Resource.indexOf('*') > -1) { + userAdmins.push({name: user.UserName, arn: user.Arn}); + return cb(); + } + } + } + } + } + } + + // See if user has admin managed policy (enriched) + if (user.attachedPolicies && Array.isArray(user.attachedPolicies) && user.attachedPolicies.length) { + for (var policy of user.attachedPolicies) { if (!policy.PolicyArn) continue; if (policy.PolicyArn === managedAdminPolicy) { @@ -146,7 +188,6 @@ module.exports = { getPolicyVersion.data.PolicyVersion.Document); if (!statements) break; - // Loop through statements to see if admin privileges for (let statement of statements) { if (statement.Effect && statement.Effect.toUpperCase() === 'ALLOW' && statement.Action && statement.Action.indexOf('*') > -1 && @@ -165,8 +206,36 @@ module.exports = { listUserPolicies.data.PolicyNames) { for (var p in listUserPolicies.data.PolicyNames) { - var policyName = listUserPolicies.data.PolicyNames[p]; + var userPolicyName = listUserPolicies.data.PolicyNames[p]; + if (getUserPolicy && + getUserPolicy[userPolicyName] && + getUserPolicy[userPolicyName].data && + getUserPolicy[userPolicyName].data.PolicyDocument) { + + var userPolicyStatements = helpers.normalizePolicyDocument( + getUserPolicy[userPolicyName].data.PolicyDocument); + if (!userPolicyStatements) break; + + // Loop through statements to see if admin privileges + for (var sp in userPolicyStatements) { + var userStmt = userPolicyStatements[sp]; + + if (userStmt.Effect === 'Allow' && + userStmt.Action.indexOf('*') > -1 && + userStmt.Resource && + userStmt.Resource.indexOf('*') > -1) { + userAdmins.push({name: user.UserName, arn: user.Arn}); + return cb(); + } + } + } + } + } + + // See if user has admin inline policy (enriched) + if (user.inlinePolicies && Array.isArray(user.inlinePolicies) && user.inlinePolicies.length) { + for (var policyName of user.inlinePolicies) { if (getUserPolicy && getUserPolicy[policyName] && getUserPolicy[policyName].data && @@ -176,7 +245,6 @@ module.exports = { getUserPolicy[policyName].data.PolicyDocument); if (!statements) break; - // Loop through statements to see if admin privileges for (var s in statements) { var statement = statements[s]; @@ -210,6 +278,12 @@ module.exports = { var getGroupPolicy = helpers.addSource(cache, source, ['iam', 'getGroupPolicy', region, group.GroupName]); + var listGroups = helpers.addSource(cache, source, ['iam', 'listGroups', region]); + var enrichedGroup = null; + if (listGroups && listGroups.data && Array.isArray(listGroups.data)) { + enrichedGroup = listGroups.data.find(g => g.GroupName === group.GroupName); + } + // See if group has admin managed policy if (listAttachedGroupPolicies && listAttachedGroupPolicies.data && @@ -225,6 +299,16 @@ module.exports = { } } + // See if group has admin managed policy (enriched) + if (enrichedGroup && enrichedGroup.attachedPolicies && Array.isArray(enrichedGroup.attachedPolicies) && enrichedGroup.attachedPolicies.length) { + for (var enrichedPolicy of enrichedGroup.attachedPolicies) { + if (enrichedPolicy.PolicyArn === managedAdminPolicy) { + userAdmins.push({name: user.UserName, arn: user.Arn}); + return cb(); + } + } + } + // See if group has admin inline policy if (listGroupPolicies && listGroupPolicies.data && @@ -238,11 +322,37 @@ module.exports = { getGroupPolicy[policyGroupName].data && getGroupPolicy[policyGroupName].data.PolicyDocument) { - var statementsGroup = helpers.normalizePolicyDocument( + var groupPolicyStatements = helpers.normalizePolicyDocument( getGroupPolicy[policyGroupName].data.PolicyDocument); - if (!statementsGroup) break; + if (!groupPolicyStatements) break; // Loop through statements to see if admin privileges + for (var sg in groupPolicyStatements) { + var groupStmt = groupPolicyStatements[sg]; + + if (groupStmt.Effect === 'Allow' && + groupStmt.Action.indexOf('*') > -1 && + groupStmt.Resource.indexOf('*') > -1) { + userAdmins.push({name: user.UserName, arn: user.Arn}); + return cb(); + } + } + } + } + } + + // See if group has admin inline policy (enriched) + if (enrichedGroup && enrichedGroup.inlinePolicies && Array.isArray(enrichedGroup.inlinePolicies) && enrichedGroup.inlinePolicies.length) { + for (var enrichedPolicyName of enrichedGroup.inlinePolicies) { + if (getGroupPolicy && + getGroupPolicy[enrichedPolicyName] && + getGroupPolicy[enrichedPolicyName].data && + getGroupPolicy[enrichedPolicyName].data.PolicyDocument) { + + var statementsGroup = helpers.normalizePolicyDocument( + getGroupPolicy[enrichedPolicyName].data.PolicyDocument); + if (!statementsGroup) break; + for (s in statementsGroup) { var statementGroup = statementsGroup[s]; diff --git a/plugins/aws/iam/iamUserUnauthorizedToEdit.js b/plugins/aws/iam/iamUserUnauthorizedToEdit.js index 27cb90f765..7a242d2cc7 100644 --- a/plugins/aws/iam/iamUserUnauthorizedToEdit.js +++ b/plugins/aws/iam/iamUserUnauthorizedToEdit.js @@ -125,6 +125,16 @@ module.exports = { } } + // See if user has administrator access or IAM full access (enriched) + if (user.attachedPolicies && Array.isArray(user.attachedPolicies) && user.attachedPolicies.length) { + for (var policy of user.attachedPolicies) { + if (policy.PolicyArn === adminAccessArn || + policy.PolicyArn === iamFullAccessArn) { + addPolicyToUserObj(restrictedUser, user, policy.PolicyName); + } + } + } + // See if user has IAM full access inline policy if (listUserPolicies.data && listUserPolicies.data.PolicyNames) { for (var up in listUserPolicies.data.PolicyNames) { @@ -140,6 +150,29 @@ module.exports = { if (!statements) break; // Loop through statements to see if admin privileges + for (var si in statements) { + let statement = statements[si]; + + if (helpers.userGlobalAccess(statement, iamEditAccessPermissions)) { + addPolicyToUserObj(restrictedUser, user, policyName); + } + } + } + } + } + + // See if user has IAM full access inline policy (enriched) + if (user.inlinePolicies && Array.isArray(user.inlinePolicies) && user.inlinePolicies.length) { + for (var policyName of user.inlinePolicies) { + if (getUserPolicy && + getUserPolicy[policyName] && + getUserPolicy[policyName].data && + getUserPolicy[policyName].data.PolicyDocument) { + + let statements = helpers.normalizePolicyDocument( + getUserPolicy[policyName].data.PolicyDocument); + if (!statements) break; + for (var s in statements) { let statement = statements[s]; @@ -169,6 +202,12 @@ module.exports = { var getGroupPolicy = helpers.addSource(cache, source, ['iam', 'getGroupPolicy', region, group.GroupName]); + var listGroups = helpers.addSource(cache, source, ['iam', 'listGroups', region]); + var enrichedGroup = null; + if (listGroups && listGroups.data && Array.isArray(listGroups.data)) { + enrichedGroup = listGroups.data.find(g => g.GroupName === group.GroupName); + } + // See if group has admin managed policy if (listAttachedGroupPolicies && listAttachedGroupPolicies.data && @@ -183,6 +222,16 @@ module.exports = { } } + // See if group has admin managed policy (enriched) + if (enrichedGroup && enrichedGroup.attachedPolicies && Array.isArray(enrichedGroup.attachedPolicies) && enrichedGroup.attachedPolicies.length) { + for (var enrichedPolicy of enrichedGroup.attachedPolicies) { + if (enrichedPolicy.PolicyArn === adminAccessArn || + enrichedPolicy.PolicyArn === iamFullAccessArn) { + addPolicyToUserObj(restrictedUser, user, enrichedPolicy.PolicyName); + } + } + } + // See if group has admin inline policy if (listGroupPolicies && listGroupPolicies.data && @@ -195,16 +244,38 @@ module.exports = { getGroupPolicy[policyGroupName] && getGroupPolicy[policyGroupName].data && getGroupPolicy[policyGroupName].data.PolicyDocument) { - var statementsGroup = helpers.normalizePolicyDocument( + var groupPolicyStatements = helpers.normalizePolicyDocument( getGroupPolicy[policyGroupName].data.PolicyDocument); - if (!statementsGroup) break; + if (!groupPolicyStatements) break; // Loop through statements to see if admin privileges + for (var sgi in groupPolicyStatements) { + let statementGroup = groupPolicyStatements[sgi]; + + if (helpers.userGlobalAccess(statementGroup, iamEditAccessPermissions)) { + addPolicyToUserObj(restrictedUser, user, policyGroupName); + } + } + } + } + } + // See if group has admin inline policy (enriched) + if (enrichedGroup && enrichedGroup.inlinePolicies && Array.isArray(enrichedGroup.inlinePolicies) && enrichedGroup.inlinePolicies.length) { + for (var enrichedPolicyName of enrichedGroup.inlinePolicies) { + if (getGroupPolicy && + getGroupPolicy[enrichedPolicyName] && + getGroupPolicy[enrichedPolicyName].data && + getGroupPolicy[enrichedPolicyName].data.PolicyDocument) { + + var statementsGroup = helpers.normalizePolicyDocument( + getGroupPolicy[enrichedPolicyName].data.PolicyDocument); + if (!statementsGroup) break; + for (s in statementsGroup) { let statementGroup = statementsGroup[s]; if (helpers.userGlobalAccess(statementGroup, iamEditAccessPermissions)) { - addPolicyToUserObj(restrictedUser, user, policyGroupName); + addPolicyToUserObj(restrictedUser, user, enrichedPolicyName); } } } diff --git a/plugins/aws/iam/iamUserWithoutPermissions.js b/plugins/aws/iam/iamUserWithoutPermissions.js index 37a940c548..6ebe4dc09c 100644 --- a/plugins/aws/iam/iamUserWithoutPermissions.js +++ b/plugins/aws/iam/iamUserWithoutPermissions.js @@ -72,7 +72,10 @@ module.exports = { } var listGroupPolicies, listAttachedGroupPolicies; + var hasGroupPermissions = false; if (listGroupsForUser.data && listGroupsForUser.data.Groups){ + var listGroups = helpers.addSource(cache, source, ['iam', 'listGroups', region]); + for (let group of listGroupsForUser.data.Groups){ listGroupPolicies = helpers.addSource(cache, source, ['iam', 'listGroupPolicies', region, group.GroupName]); @@ -92,19 +95,41 @@ module.exports = { return cb(); } - if ((listGroupPolicies.data.PolicyNames && listGroupPolicies.data.PolicyNames.length) || - (listAttachedGroupPolicies.data.AttachedPolicies && listAttachedGroupPolicies.data.AttachedPolicies.length)){ + var hasInlineGroupPolicies = listGroupPolicies.data.PolicyNames && listGroupPolicies.data.PolicyNames.length; + var hasAttachedGroupPolicies = listAttachedGroupPolicies.data.AttachedPolicies && listAttachedGroupPolicies.data.AttachedPolicies.length; + + var enrichedGroup = null; + if ((!hasAttachedGroupPolicies || !hasInlineGroupPolicies) && listGroups && listGroups.data && Array.isArray(listGroups.data)) { + enrichedGroup = listGroups.data.find(g => g.GroupName === group.GroupName); + } + + if (!hasAttachedGroupPolicies && enrichedGroup && enrichedGroup.attachedPolicies && Array.isArray(enrichedGroup.attachedPolicies) && enrichedGroup.attachedPolicies.length) { + hasAttachedGroupPolicies = true; + } + + if (!hasInlineGroupPolicies && enrichedGroup && enrichedGroup.inlinePolicies && Array.isArray(enrichedGroup.inlinePolicies) && enrichedGroup.inlinePolicies.length) { + hasInlineGroupPolicies = true; + } + + if (hasInlineGroupPolicies || hasAttachedGroupPolicies){ + hasGroupPermissions = true; break; } } } - if ((listAttachedUserPolicies.data.AttachedPolicies && - listAttachedUserPolicies.data.AttachedPolicies.length) || - (listUserPolicies.data.PolicyNames && - listUserPolicies.data.PolicyNames.length) || (listAttachedGroupPolicies && listAttachedGroupPolicies.data.AttachedPolicies && - listAttachedGroupPolicies.data.AttachedPolicies.length) || - (listGroupPolicies && listGroupPolicies.data.PolicyNames && listGroupPolicies.data.PolicyNames.length)) { + var hasAttachedUserPolicies = listAttachedUserPolicies.data.AttachedPolicies && listAttachedUserPolicies.data.AttachedPolicies.length; + var hasInlineUserPolicies = listUserPolicies.data.PolicyNames && listUserPolicies.data.PolicyNames.length; + + if (!hasAttachedUserPolicies && user.attachedPolicies && Array.isArray(user.attachedPolicies) && user.attachedPolicies.length) { + hasAttachedUserPolicies = true; + } + + if (!hasInlineUserPolicies && user.inlinePolicies && Array.isArray(user.inlinePolicies) && user.inlinePolicies.length) { + hasInlineUserPolicies = true; + } + + if (hasAttachedUserPolicies || hasInlineUserPolicies || hasGroupPermissions) { helpers.addResult(results, 0, 'IAM user has permissions', 'global', user.Arn); } else { helpers.addResult(results, 2, 'IAM user does not have any permissions', 'global', user.Arn); diff --git a/plugins/aws/iam/minPasswordLength.js b/plugins/aws/iam/minPasswordLength.js index 8fcc929033..316c5e9212 100644 --- a/plugins/aws/iam/minPasswordLength.js +++ b/plugins/aws/iam/minPasswordLength.js @@ -39,13 +39,13 @@ module.exports = { name: 'Min Password Length Fail', description: 'Return a failing result when min password length is fewer than this number of characters', regex: '^[1-9]{1}[0-9]{0,2}$', - default: 14 + default: 10 }, min_password_length_warn: { name: 'Min Password Length Warn', description: 'Return a warning result when min password length is fewer than this number of characters', regex: '^[1-9]{1}[0-9]{0,2}$', - default: 16 + default: 14 } }, asl: { diff --git a/plugins/aws/iam/minPasswordLength.spec.js b/plugins/aws/iam/minPasswordLength.spec.js index 350780e913..2102865388 100644 --- a/plugins/aws/iam/minPasswordLength.spec.js +++ b/plugins/aws/iam/minPasswordLength.spec.js @@ -89,23 +89,18 @@ describe('minPasswordLength', function () { describe('run', function () { it('should PASS if minimum password length is suitable', function (done) { const cache = createCache(getAccountPasswordPolicy[0]); - minPasswordLength.run(cache, {}, (err, results) => { + var settings = { + min_password_length_fail: 10, + min_password_length_warn: 14 + }; + minPasswordLength.run(cache, settings, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(0); done(); }); }); - it('should FAIL if minimum password length is less than 14 characters', function (done) { - const cache = createCache(getAccountPasswordPolicy[1]); - minPasswordLength.run(cache, {}, (err, results) => { - expect(results.length).to.equal(1); - expect(results[0].status).to.equal(2); - done(); - }); - }); - - it('should WARN if minimum password length is less than warn limit', function (done) { + it('should WARN if minimum password length is less than 14 characters', function (done) { const cache = createCache(getAccountPasswordPolicy[1]); var settings = { min_password_length_fail: 10, @@ -118,9 +113,13 @@ describe('minPasswordLength', function () { }); }); - it('should FAIL if minimum password length is less than fail limit', function (done) { + it('should FAIL if minimum password length is less than 10 characters', function (done) { const cache = createCache(getAccountPasswordPolicy[2]); - minPasswordLength.run(cache, {}, (err, results) => { + var settings = { + min_password_length_fail: 10, + min_password_length_warn: 14 + }; + minPasswordLength.run(cache, settings, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(2); done(); diff --git a/plugins/aws/iam/noUserIamPolicies.js b/plugins/aws/iam/noUserIamPolicies.js index f915ea02ec..5756fe24fb 100644 --- a/plugins/aws/iam/noUserIamPolicies.js +++ b/plugins/aws/iam/noUserIamPolicies.js @@ -80,7 +80,7 @@ module.exports = { } if (hasAttachedPolicies || hasInlinePolicies) { - helpers.addResult(results, 2, 'User is using attached or inline policies', 'global', user.Arn); + helpers.addResult(results, 1, 'User is using attached or inline policies', 'global', user.Arn); } else { helpers.addResult(results, 0, 'User is not using attached or inline policies', 'global', user.Arn); } diff --git a/plugins/aws/iam/noUserIamPolicies.spec.js b/plugins/aws/iam/noUserIamPolicies.spec.js index 1b7e15a56b..7aeca97da0 100644 --- a/plugins/aws/iam/noUserIamPolicies.spec.js +++ b/plugins/aws/iam/noUserIamPolicies.spec.js @@ -187,11 +187,11 @@ describe('noUserIamPolicies', function () { }); }); - it('should FAIL if user is using attached or inline policies', function (done) { + it('should WARN if user is using attached or inline policies', function (done) { const cache = createCache([listUsers[0]], listAttachedUserPolicies[1], listUserPolicies[1]); noUserIamPolicies.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); - expect(results[0].status).to.equal(2); + expect(results[0].status).to.equal(1); done(); }); }); diff --git a/plugins/aws/iam/passwordReusePrevention.js b/plugins/aws/iam/passwordReusePrevention.js index aaf7d69eb5..ab6d75b25d 100644 --- a/plugins/aws/iam/passwordReusePrevention.js +++ b/plugins/aws/iam/passwordReusePrevention.js @@ -39,6 +39,12 @@ module.exports = { name: 'Password Reuse Fail', description: 'Return a failing result when password reuse policy remembers fewer than this many past passwords', regex: '^[1-9]{1}[0-9]{0,2}$', + default: 5 + }, + password_reuse_warn: { + name: 'Password Reuse Warn', + description: 'Return a warning result when password reuse policy remembers fewer than this many past passwords', + regex: '^[1-9]{1}[0-9]{0,2}$', default: 24 } }, @@ -46,7 +52,8 @@ module.exports = { run: function(cache, settings, callback) { var config = { - password_reuse_fail: settings.password_reuse_fail || this.settings.password_reuse_fail.default + password_reuse_fail: settings.password_reuse_fail || this.settings.password_reuse_fail.default, + password_reuse_warn: settings.password_reuse_warn || this.settings.password_reuse_warn.default }; var custom = helpers.isCustom(settings, this.settings); @@ -82,6 +89,9 @@ module.exports = { } else if (passwordPolicy.PasswordReusePrevention < config.password_reuse_fail) { helpers.addResult(results, 2, 'Maximum password reuse of: ' + passwordPolicy.PasswordReusePrevention + ' passwords is less than ' + config.password_reuse_fail, 'global', null, custom); + } else if (passwordPolicy.PasswordReusePrevention < config.password_reuse_warn) { + helpers.addResult(results, 1, + 'Maximum password reuse of: ' + passwordPolicy.PasswordReusePrevention + ' passwords is less than ' + config.password_reuse_warn, 'global', null, custom); } else { helpers.addResult(results, 0, 'Maximum password reuse of: ' + passwordPolicy.PasswordReusePrevention + ' passwords is suitable', 'global', null, custom); diff --git a/plugins/aws/iam/passwordReusePrevention.spec.js b/plugins/aws/iam/passwordReusePrevention.spec.js index 92a1ff2c90..9b45e2c225 100644 --- a/plugins/aws/iam/passwordReusePrevention.spec.js +++ b/plugins/aws/iam/passwordReusePrevention.spec.js @@ -92,25 +92,37 @@ describe('passwordReusePrevention', function () { describe('run', function () { it('should PASS if maximum password reuse is suitable', function (done) { const cache = createCache(getAccountPasswordPolicy[0]); - passwordReusePrevention.run(cache, {}, (err, results) => { + var settings = { + password_reuse_fail: 5, + password_reuse_warn: 24 + }; + passwordReusePrevention.run(cache, settings, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(0); done(); }); }); - it('should FAIL if maximum password reuse is less than 24 passwords', function (done) { + it('should WARN if maximum password reuse is less than warn limit', function (done) { const cache = createCache(getAccountPasswordPolicy[1]); - passwordReusePrevention.run(cache, {}, (err, results) => { + var settings = { + password_reuse_fail: 5, + password_reuse_warn: 24 + }; + passwordReusePrevention.run(cache, settings, (err, results) => { expect(results.length).to.equal(1); - expect(results[0].status).to.equal(2); + expect(results[0].status).to.equal(1); done(); }); }); it('should FAIL if maximum password reuse is less than fail limit', function (done) { const cache = createCache(getAccountPasswordPolicy[2]); - passwordReusePrevention.run(cache, {}, (err, results) => { + var settings = { + password_reuse_fail: 5, + password_reuse_warn: 24 + }; + passwordReusePrevention.run(cache, settings, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(2); done(); diff --git a/plugins/aws/iam/rolePolicyUnusedServices.js b/plugins/aws/iam/rolePolicyUnusedServices.js index bfca0f39c2..8babf58611 100644 --- a/plugins/aws/iam/rolePolicyUnusedServices.js +++ b/plugins/aws/iam/rolePolicyUnusedServices.js @@ -334,7 +334,62 @@ module.exports = { if (listAttachedRolePolicies.data && listAttachedRolePolicies.data.AttachedPolicies) { - for (var policy of listAttachedRolePolicies.data.AttachedPolicies) { + for (var attachedPolicy of listAttachedRolePolicies.data.AttachedPolicies) { + if (attachedPolicy.PolicyArn === managedAdminPolicy) { + roleFailures.push('Role has managed AdministratorAccess policy'); + break; + } + + if (config.ignore_aws_managed_iam_policies && new RegExp(`^arn:${awsOrGov}:iam::aws:.*`).test(attachedPolicy.PolicyArn)) continue; + + if (config.ignore_customer_managed_iam_policies && new RegExp(`^arn:${awsOrGov}:iam::[0-9]{12}:.*`).test(attachedPolicy.PolicyArn)) continue; + + var managedGetPolicy = helpers.addSource(cache, source, + ['iam', 'getPolicy', iamRegion, attachedPolicy.PolicyArn]); + + if (managedGetPolicy && + managedGetPolicy.data && + managedGetPolicy.data.Policy && + managedGetPolicy.data.Policy.DefaultVersionId) { + var managedGetPolicyVersion = helpers.addSource(cache, source, + ['iam', 'getPolicyVersion', iamRegion, attachedPolicy.PolicyArn]); + + if (managedGetPolicyVersion && + managedGetPolicyVersion.data && + managedGetPolicyVersion.data.PolicyVersion && + managedGetPolicyVersion.data.PolicyVersion.Document) { + let managedStatements = helpers.normalizePolicyDocument( + managedGetPolicyVersion.data.PolicyVersion.Document); + if (!managedStatements) break; + for (let statement of managedStatements) { + if (statement.Action && statement.Action.length) { + + for (let action of statement.Action) { + if (config.whitelist_unused_actions_for_resources.includes(action.toLowerCase())) continue; + let service = action.split(':')[0] ? action.split(':')[0].toLowerCase() : ''; + let resourceAction = action.split(':')[1] ? action.split(':')[1].toLowerCase() : ''; + + if (allServices[service] && !config.whitelist_unused_services.includes(service)) { + for (let supportedResource of allServices[service]) { + if (resourceAction.includes(supportedResource)) { + if (!allResources[service] || !allResources[service].includes(supportedResource)) { + if (policyFailures.indexOf(action) === -1) policyFailures.push(action); + } + } + } + } + } + } + } + + addRoleFailures(roleFailures, managedStatements, 'managed', config.ignore_service_specific_wildcards, allowedRegex, config.ignore_iam_policy_resource_wildcards); + } + } + } + } + + if (role.attachedPolicies && Array.isArray(role.attachedPolicies) && role.attachedPolicies.length) { + for (var policy of role.attachedPolicies) { if (policy.PolicyArn === managedAdminPolicy) { roleFailures.push('Role has managed AdministratorAccess policy'); break; @@ -391,8 +446,52 @@ module.exports = { if (listRolePolicies.data && listRolePolicies.data.PolicyNames) { for (var p in listRolePolicies.data.PolicyNames) { - var policyName = listRolePolicies.data.PolicyNames[p]; + var rolePolicyName = listRolePolicies.data.PolicyNames[p]; + if (getRolePolicy && + getRolePolicy[rolePolicyName] && + getRolePolicy[rolePolicyName].data && + getRolePolicy[rolePolicyName].data.PolicyDocument) { + var inlinePolicyStatements = getRolePolicy[rolePolicyName].data.PolicyDocument; + + if (!inlinePolicyStatements) break; + + for (let statement of inlinePolicyStatements) { + if ((statement.Action && statement.Action.length && statement.Action[0] === '*') || + (statement.Resource && statement.Resource.length && statement.Resource[0] === '*')) { + continue; + } + + if (statement.Action && statement.Action.length && + statement.Resource && statement.Resource.length) { + let service = statement.Resource[0].includes('arn') ? statement.Resource[0].split(':')[2].toLowerCase() : + statement.Action[0].split(':')[1].toLowerCase(); + if (statement.Action.length > 1 || statement.Action[0] !== '*') { + for (let action of statement.Action) { + if (config.whitelist_unused_actions_for_resources.includes(action)) continue; + let resourceAction = action.split(':')[1].toLowerCase(); + + if (allServices[service] && !config.whitelist_unused_services.includes(service)) { + for (let supportedResource of allServices[service]) { + if (resourceAction.includes(supportedResource)) { + if (!allResources[service] || !allResources[service].includes(supportedResource)) { + if (policyFailures.indexOf(action) === -1) policyFailures.push(action); + } + } + } + } + } + } + } + } + + addRoleFailures(roleFailures, inlinePolicyStatements, 'inline', config.ignore_service_specific_wildcards, allowedRegex, config.ignore_iam_policy_resource_wildcards); + } + } + } + + if (role.inlinePolicies && Array.isArray(role.inlinePolicies) && role.inlinePolicies.length) { + for (var policyName of role.inlinePolicies) { if (getRolePolicy && getRolePolicy[policyName] && getRolePolicy[policyName].data && @@ -446,6 +545,7 @@ module.exports = { } cb(); + }, function() { callback(null, results, source); }); diff --git a/plugins/aws/iam/usersPasswordLastUsed.js b/plugins/aws/iam/usersPasswordLastUsed.js index 09896b85db..81d30b96be 100644 --- a/plugins/aws/iam/usersPasswordLastUsed.js +++ b/plugins/aws/iam/usersPasswordLastUsed.js @@ -24,13 +24,13 @@ module.exports = { name: 'Users Password Last Used Fail', description: 'Return a failing result when users with password logins exceed this number of days without being used', regex: '^[1-9]{1}[0-9]{0,3}$', - default: 45 + default: 180 }, users_password_last_used_warn: { name: 'Users Password Last Used Warn', description: 'Return a warning result when users with password logins exceed this number of days without being used', regex: '^[1-9]{1}[0-9]{0,3}$', - default: 30 + default: 90 } }, realtime_triggers: ['iam:CreateUser','iam:DeleteUser'], diff --git a/plugins/aws/iam/usersPasswordLastUsed.spec.js b/plugins/aws/iam/usersPasswordLastUsed.spec.js index b382abee64..3e1224a925 100644 --- a/plugins/aws/iam/usersPasswordLastUsed.spec.js +++ b/plugins/aws/iam/usersPasswordLastUsed.spec.js @@ -4,7 +4,7 @@ const usersPasswordLastUsed = require('./usersPasswordLastUsed'); var warnDate = new Date(); warnDate.setMonth(warnDate.getMonth() - 4); var passDate = new Date(); -passDate.setDate(passDate.getDate() - 30); +passDate.setMonth(passDate.getMonth() - 2); var failDate = new Date(); failDate.setMonth(failDate.getMonth() - 7); @@ -219,7 +219,11 @@ describe('usersPasswordLastUsed', function () { describe('run', function () { it('should PASS if the user password was last used within the pass limit', function (done) { const cache = createCache([generateCredentialReport[0],generateCredentialReport[0],generateCredentialReport[1]]); - usersPasswordLastUsed.run(cache, {}, (err, results) => { + var settings = { + users_password_last_used_fail: 180, + users_password_last_used_warn: 90 + }; + usersPasswordLastUsed.run(cache, settings, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(0); done(); @@ -228,22 +232,17 @@ describe('usersPasswordLastUsed', function () { it('should PASS if the user was created within the pass limit but never used', function (done) { const cache = createCache([generateCredentialReport[0],generateCredentialReport[0],generateCredentialReport[4]]); - usersPasswordLastUsed.run(cache, {}, (err, results) => { + var settings = { + users_password_last_used_fail: 180, + users_password_last_used_warn: 90 + }; + usersPasswordLastUsed.run(cache, settings, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(0); done(); }); }); - it('should FAIL if the password was last used more than 45 days ago', function (done) { - const cache = createCache([generateCredentialReport[0],generateCredentialReport[0],generateCredentialReport[2]]); - usersPasswordLastUsed.run(cache, {}, (err, results) => { - expect(results.length).to.equal(1); - expect(results[0].status).to.equal(2); - done(); - }); - }); - it('should WARN if the password was last used within the warn limit', function (done) { const cache = createCache([generateCredentialReport[0],generateCredentialReport[0],generateCredentialReport[2]]); var settings = { @@ -272,7 +271,11 @@ describe('usersPasswordLastUsed', function () { it('should FAIL if the user password was last used more than the fail limit', function (done) { const cache = createCache([generateCredentialReport[0],generateCredentialReport[0],generateCredentialReport[3]]); - usersPasswordLastUsed.run(cache, {}, (err, results) => { + var settings = { + users_password_last_used_fail: 180, + users_password_last_used_warn: 90 + }; + usersPasswordLastUsed.run(cache, settings, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(2); done(); @@ -281,7 +284,11 @@ describe('usersPasswordLastUsed', function () { it('should FAIL if the user was created more than the fail limit but never used', function (done) { const cache = createCache([generateCredentialReport[0],generateCredentialReport[0],generateCredentialReport[6]]); - usersPasswordLastUsed.run(cache, {}, (err, results) => { + var settings = { + users_password_last_used_fail: 180, + users_password_last_used_warn: 90 + }; + usersPasswordLastUsed.run(cache, settings, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(2); done(); diff --git a/plugins/aws/imagebuilder/imageRecipeVolumeEncrypted.js b/plugins/aws/imagebuilder/imageRecipeVolumeEncrypted.js index 6f93d806ad..20b50012d0 100644 --- a/plugins/aws/imagebuilder/imageRecipeVolumeEncrypted.js +++ b/plugins/aws/imagebuilder/imageRecipeVolumeEncrypted.js @@ -89,9 +89,19 @@ module.exports = { `Unable to get image Recipe description: ${helpers.addError(getImageRecipe)}`, region, resource); continue; - } + } + + let blockDeviceMappings = getImageRecipe.data.imageRecipe.blockDeviceMappings; + + if (!blockDeviceMappings || !blockDeviceMappings.length) { + helpers.addResult(results, 0, + 'Image recipe does not have any block device mappings', + region, resource); + continue; + } + let poorlyEncrypted = []; - for (let mapping of getImageRecipe.data.imageRecipe.blockDeviceMappings){ + for (let mapping of blockDeviceMappings){ if (mapping.ebs && !mapping.ebs.encrypted){ poorlyEncrypted.push(mapping.ebs); continue; diff --git a/plugins/aws/lambda/lambdaAdminPrivileges.js b/plugins/aws/lambda/lambdaAdminPrivileges.js index 5c08a4263a..c034aa8267 100644 --- a/plugins/aws/lambda/lambdaAdminPrivileges.js +++ b/plugins/aws/lambda/lambdaAdminPrivileges.js @@ -13,7 +13,7 @@ module.exports = { apis: ['Lambda:listFunctions', 'IAM:listRoles', 'IAM:listAttachedRolePolicies', 'IAM:listRolePolicies', 'IAM:listPolicies', 'IAM:getPolicy', 'IAM:getPolicyVersion', 'IAM:getRolePolicy'], realtime_triggers: ['lambda:CreateFunction','lambda:UpdateFunctionConfiguration', 'lambda:DeleteFunction'], - + run: function(cache, settings, callback) { var results = []; var source = {}; @@ -28,7 +28,6 @@ module.exports = { ['lambda', 'listFunctions', region]); if (!listFunctions) return rcb(); - if (listFunctions.err || !listFunctions.data) { helpers.addResult(results, 3, `Unable to query for Lambda functions: ${helpers.addError(listFunctions)}`, region); @@ -62,91 +61,92 @@ module.exports = { var getRolePolicy = helpers.addSource(cache, source, ['iam', 'getRolePolicy', defaultRegion, roleName]); - if (!listAttachedRolePolicies || !listRolePolicies ) { + if (!listAttachedRolePolicies || !listRolePolicies) { helpers.addResult(results, 0, 'No IAM Attached Role Found', region, resource); return fcb(); } - if (listAttachedRolePolicies.err || - !listAttachedRolePolicies.data || - !listAttachedRolePolicies.data.AttachedPolicies) { + if (listAttachedRolePolicies.err || !listAttachedRolePolicies.data) { helpers.addResult(results, 3, `Unable to query for IAM attached policy for role "${roleName}": ${helpers.addError(listAttachedRolePolicies)}`, region, resource); return fcb(); } - if (listRolePolicies.err || !listRolePolicies.data || !listRolePolicies.data.PolicyNames) { + if (listRolePolicies.err || !listRolePolicies.data) { helpers.addResult(results, 3, - `Unable to query for IAM role policy for role "${roleName}": ${helpers.addError(listRolePolicies)}`, + `Unable to query for IAM role policy for role "${roleName}": ${helpers.addError(listRolePolicies)}`, region, resource); return fcb(); } - for (var policy of listAttachedRolePolicies.data.AttachedPolicies) { - if (!policy.PolicyArn) continue; + var listRoles = helpers.addSource(cache, source, ['iam', 'listRoles', defaultRegion]); + var enrichedRole = null; + if (listRoles && listRoles.data && Array.isArray(listRoles.data)) { + enrichedRole = listRoles.data.find(r => r.RoleName === roleName); + } + + var hasAttachedPolicies = listAttachedRolePolicies.data.AttachedPolicies && listAttachedRolePolicies.data.AttachedPolicies.length; + var hasInlinePolicies = listRolePolicies.data.PolicyNames && listRolePolicies.data.PolicyNames.length; + var attachedPolicies = hasAttachedPolicies + ? listAttachedRolePolicies.data.AttachedPolicies + : (enrichedRole && enrichedRole.attachedPolicies && Array.isArray(enrichedRole.attachedPolicies) && enrichedRole.attachedPolicies.length + ? enrichedRole.attachedPolicies : []); + + var inlinePolicyNames = hasInlinePolicies + ? listRolePolicies.data.PolicyNames + : (enrichedRole && enrichedRole.inlinePolicies && Array.isArray(enrichedRole.inlinePolicies) && enrichedRole.inlinePolicies.length + ? enrichedRole.inlinePolicies : []); + + // check attached managed policies + for (var policy of attachedPolicies) { + if (!policy.PolicyArn) continue; if (policy.PolicyArn === managedAdminPolicy) { - helpers.addResult(results, 2, - 'Function has admin privileges', region, resource); - return fcb(); + adminPrivileged = true; + break; } var getPolicy = helpers.addSource(cache, source, ['iam', 'getPolicy', defaultRegion, policy.PolicyArn]); - - if (getPolicy && - getPolicy.data && - getPolicy.data.Policy && - getPolicy.data.Policy.DefaultVersionId) { + if (getPolicy && getPolicy.data && getPolicy.data.Policy && getPolicy.data.Policy.DefaultVersionId) { var getPolicyVersion = helpers.addSource(cache, source, ['iam', 'getPolicyVersion', defaultRegion, policy.PolicyArn]); + if (getPolicyVersion && getPolicyVersion.data && getPolicyVersion.data.PolicyVersion && getPolicyVersion.data.PolicyVersion.Document) { + let statements = helpers.normalizePolicyDocument(getPolicyVersion.data.PolicyVersion.Document); + if (!statements) continue; - if (getPolicyVersion && - getPolicyVersion.data && - getPolicyVersion.data.PolicyVersion && - getPolicyVersion.data.PolicyVersion.Document) { - let statements = helpers.normalizePolicyDocument( - getPolicyVersion.data.PolicyVersion.Document); - if (!statements) break; - - // Loop through statements to see if admin privileges for (let statement of statements) { if (statement.Effect && statement.Effect.toUpperCase() === 'ALLOW' && - statement.Action && statement.Action.indexOf('*') > -1 && - statement.Resource && statement.Resource.indexOf('*') > -1) { + statement.Action && statement.Action.indexOf('*') > -1 && + statement.Resource && statement.Resource.indexOf('*') > -1) { adminPrivileged = true; break; } } } } - if (adminPrivileged) break; } - - for (var policyName of listRolePolicies.data.PolicyNames) { - if (getRolePolicy && - getRolePolicy[policyName] && - getRolePolicy[policyName].data && - getRolePolicy[policyName].data.PolicyDocument) { - let statements = getRolePolicy[policyName].data.PolicyDocument; - if (!statements) break; - - // Loop through statements to see if admin privileges + for (var policyName of inlinePolicyNames) { + if (getRolePolicy && getRolePolicy[policyName] && getRolePolicy[policyName].data && getRolePolicy[policyName].data.PolicyDocument) { + let statements = helpers.normalizePolicyDocument(getRolePolicy[policyName].data.PolicyDocument); + if (!statements) continue; for (let statement of statements) { if (statement.Effect && statement.Effect.toUpperCase() === 'ALLOW' && - statement.Action && statement.Action.indexOf('*') > -1 && - statement.Resource && statement.Resource.indexOf('*') > -1) { + statement.Action && statement.Action.indexOf('*') > -1 && + statement.Resource && statement.Resource.indexOf('*') > -1) { adminPrivileged = true; break; } } } + if (adminPrivileged) break; } + // final decision if (!adminPrivileged) { helpers.addResult(results, 0, 'Function does not have admin privileges', region, resource); @@ -163,4 +163,4 @@ module.exports = { callback(null, results, source); }); } -}; +}; \ No newline at end of file diff --git a/plugins/aws/lambda/lambdaEnhancedMonitoring.js b/plugins/aws/lambda/lambdaEnhancedMonitoring.js index c13b64d5d0..604dc4ae43 100644 --- a/plugins/aws/lambda/lambdaEnhancedMonitoring.js +++ b/plugins/aws/lambda/lambdaEnhancedMonitoring.js @@ -49,11 +49,12 @@ module.exports = { continue; } - if (functionInfo.data && - functionInfo.data.Configuration && - functionInfo.data.Configuration.Layers && - functionInfo.data.Configuration.Layers[0] && - functionInfo.data.Configuration.Layers[0].Arn) { + var layers = functionInfo.data && functionInfo.data.Configuration && functionInfo.data.Configuration.Layers; + var hasInsightsLayer = layers && layers.some(function(layer) { + return layer.Arn && layer.Arn.includes('LambdaInsightsExtension'); + }); + + if (hasInsightsLayer) { helpers.addResult(results, 0, 'Lambda function has enhanced monitoring enabled', region, resource); } else { helpers.addResult(results, 2, 'Lambda function does not have enhanced monitoring enabled', region, resource); diff --git a/plugins/aws/lambda/lambdaEnhancedMonitoring.spec.js b/plugins/aws/lambda/lambdaEnhancedMonitoring.spec.js index c6273116ff..d4f1ca4954 100644 --- a/plugins/aws/lambda/lambdaEnhancedMonitoring.spec.js +++ b/plugins/aws/lambda/lambdaEnhancedMonitoring.spec.js @@ -84,6 +84,44 @@ describe('Lambda Enhanced Monitoring Enabled', function () { lambdaEnableEnhancedMonitoring.run(cache, {}, callback); }); + it('should return failing result if lambda function has only unrelated layers', function (done) { + const lambdaData = [ + { + "FunctionName": "test-lambda", + "FunctionArn": "arn:aws:lambda:us-east-1:000011112222:function:test-lambda" + } + ]; + + const functionInfoData = { + "us-east-1": { + "test-lambda": { + "err": null, + "data": { + "Configuration": { + "Layers": [ + { + "Arn": "arn:aws:lambda:us-east-1:336392948345:layer:AWSSDKPandas-Python39:6" + } + ] + } + } + } + } + }; + + 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('Lambda function does not have enhanced monitoring enabled'); + done(); + }; + + const cache = createCache(lambdaData, functionInfoData); + + lambdaEnableEnhancedMonitoring.run(cache, {}, callback); + }); + it('should return failing result if lambda function does not have enhanced monitoring enabled', function (done) { const lambdaData = [ { diff --git a/plugins/aws/mwaa/environmentAdminPrivileges.js b/plugins/aws/mwaa/environmentAdminPrivileges.js index 36c20010e9..2a6ada3c41 100644 --- a/plugins/aws/mwaa/environmentAdminPrivileges.js +++ b/plugins/aws/mwaa/environmentAdminPrivileges.js @@ -71,24 +71,40 @@ module.exports = { var getRolePolicy = helpers.addSource(cache, source, ['iam', 'getRolePolicy', defaultRegion, roleName]); - if (!listAttachedRolePolicies || - listAttachedRolePolicies.err || - !listAttachedRolePolicies.data || - !listAttachedRolePolicies.data.AttachedPolicies) { + if (!listAttachedRolePolicies || listAttachedRolePolicies.err || !listAttachedRolePolicies.data) { helpers.addResult(results, 3, `Unable to query for IAM attached policy for role "${roleName}": ${helpers.addError(listAttachedRolePolicies)}`, region, resource); return cb(); } - if (!listRolePolicies || listRolePolicies.err || !listRolePolicies.data || !listRolePolicies.data.PolicyNames) { + if (!listRolePolicies || listRolePolicies.err || !listRolePolicies.data) { helpers.addResult(results, 3, `Unable to query for IAM role policy for role "${roleName}": ${helpers.addError(listRolePolicies)}`, region, resource); return cb(); } - for (var policy of listAttachedRolePolicies.data.AttachedPolicies) { + var listRoles = helpers.addSource(cache, source, ['iam', 'listRoles', defaultRegion]); + var enrichedRole = null; + if (listRoles && listRoles.data && Array.isArray(listRoles.data)) { + enrichedRole = listRoles.data.find(r => r.RoleName === roleName); + } + + var hasAttachedPolicies = listAttachedRolePolicies.data.AttachedPolicies && listAttachedRolePolicies.data.AttachedPolicies.length; + var hasInlinePolicies = listRolePolicies.data.PolicyNames && listRolePolicies.data.PolicyNames.length; + + var attachedPolicies = hasAttachedPolicies + ? listAttachedRolePolicies.data.AttachedPolicies + : (enrichedRole && enrichedRole.attachedPolicies && Array.isArray(enrichedRole.attachedPolicies) && enrichedRole.attachedPolicies.length + ? enrichedRole.attachedPolicies : []); + + var inlinePolicyNames = hasInlinePolicies + ? listRolePolicies.data.PolicyNames + : (enrichedRole && enrichedRole.inlinePolicies && Array.isArray(enrichedRole.inlinePolicies) && enrichedRole.inlinePolicies.length + ? enrichedRole.inlinePolicies : []); + + for (var policy of attachedPolicies) { if (!policy.PolicyArn) continue; if (policy.PolicyArn === managedAdminPolicy) { @@ -130,13 +146,13 @@ module.exports = { if (adminPrivileged) break; } - for (var policyName of listRolePolicies.data.PolicyNames) { + for (var policyName of inlinePolicyNames) { if (getRolePolicy && getRolePolicy[policyName] && getRolePolicy[policyName].data && getRolePolicy[policyName].data.PolicyDocument) { - let statements = getRolePolicy[policyName].data.PolicyDocument; - if (!statements) break; + let statements = helpers.normalizePolicyDocument(getRolePolicy[policyName].data.PolicyDocument); + if (!statements) continue; // Loop through statements to see if admin privileges for (let statement of statements) { diff --git a/plugins/azure/cosmosdb/cosmosPublicAccessDisabled.js b/plugins/azure/cosmosdb/cosmosPublicAccessDisabled.js index 4e1ecf6a4f..22091079be 100644 --- a/plugins/azure/cosmosdb/cosmosPublicAccessDisabled.js +++ b/plugins/azure/cosmosdb/cosmosPublicAccessDisabled.js @@ -82,7 +82,6 @@ module.exports = { return; } - helpers.addResult(results, 2, 'Cosmos DB account allows public access', location, account.id); }); diff --git a/plugins/azure/monitor/logProfileArchiveData.js b/plugins/azure/monitor/logProfileArchiveData.js index 35d5dd789b..c689d31100 100644 --- a/plugins/azure/monitor/logProfileArchiveData.js +++ b/plugins/azure/monitor/logProfileArchiveData.js @@ -6,11 +6,12 @@ module.exports = { category: 'Monitor', domain: 'Management and Governance', severity: 'Low', - description: 'Ensures the Log Profile is configured to export all activities from the control and management planes in all active locations', + description: 'Ensures the Log Profile is configured to export all activities a storage account', more_info: 'Exporting log activity for control plane activity allows for audited access to the Azure account with event data in the case of a security incident.', - recommended_action: 'Ensure that all activity is logged to the Event Hub or storage account for archiving.' , + recommended_action: 'Ensure that all activity is logged to a storage account for archiving.' , link: 'https://learn.microsoft.com/en-us/azure/azure-monitor/platform/archive-activity-log', - apis: ['logProfiles:list'], + apis: ['diagnosticSettingsOperations:list'], + realtime_triggers: ['microsoftinsights:diagnosticsettings:write', 'microsoftinsights:diagnosticsettings:delete'], compliance: { hipaa: 'HIPAA has clearly defined audit requirements for environments ' + 'containing sensitive data. Log Profiles are the recommended ' + @@ -25,61 +26,34 @@ module.exports = { const source = {}; const locations = helpers.locations(settings.govcloud); - async.each(locations.logProfiles, (location, rcb) => { - const logProfiles = helpers.addSource(cache, source, - ['logProfiles', 'list', location]); + async.each(locations.diagnosticSettingsOperations, (location, rcb) => { + const diagnosticSettings = helpers.addSource(cache, source, + ['diagnosticSettingsOperations', 'list', location]); - if (!logProfiles) return rcb(); + if (!diagnosticSettings) return rcb(); - if (logProfiles.err || !logProfiles.data) { + if (diagnosticSettings.err || !diagnosticSettings.data) { helpers.addResult(results, 3, - 'Unable to query for Log Profiles: ' + helpers.addError(logProfiles), location); + 'Unable to query for Diagnostic Settings: ' + helpers.addError(diagnosticSettings), location); return rcb(); } - if (!logProfiles.data.length) { - helpers.addResult(results, 2, 'No existing Log Profiles found', location); + if (!diagnosticSettings.data.length) { + helpers.addResult(results, 2, 'No existing Diagnostic Settings found', location); return rcb(); } - logProfiles.data.forEach(function(logProfile){ - var issues = []; - if (logProfile.locations && logProfile.locations.length) { - var unmatchedRegions = []; - locations.all.forEach(function(region){ - if (region !== 'global' && logProfile.locations.indexOf(region) === -1) { - unmatchedRegions.push(region); - } - }); - if (unmatchedRegions.length) { - issues.push('the following regions are not being monitored: ' + unmatchedRegions.join(', ')); - } - } else { - issues.push('no regions are being monitored'); - } + const archivingSetting = diagnosticSettings.data.find(s => + s.storageAccountId && s.storageAccountId.length && + s.logs && s.logs.some(log => log.enabled)); - if (logProfile.categories && logProfile.categories.length) { - var unmatchedCats = []; - ['Write', 'Delete', 'Action'].forEach(function(cat){ - if (logProfile.categories.indexOf(cat) === -1) { - unmatchedCats.push(cat); - } - }); - if (unmatchedCats.length) { - issues.push('the following categories are not being monitored: ' + unmatchedCats.join(', ')); - } - } else { - issues.push('no log categories are being monitored'); - } - - if (issues.length) { - helpers.addResult(results, 2, - 'Log Profile has the following issues: ' + issues.join('; '), location, logProfile.id); - } else { - helpers.addResult(results, 0, - 'Log Profile is archiving all activities in all regions.', location, logProfile.id); - } - }); + if (archivingSetting) { + helpers.addResult(results, 0, + 'Diagnostic Setting is archiving Activity Logs to a storage account.', location, archivingSetting.id); + } else { + helpers.addResult(results, 2, + 'No Diagnostic Setting is archiving Activity Logs to a storage account.', location); + } rcb(); }, function() { diff --git a/plugins/azure/monitor/logProfileArchiveData.spec.js b/plugins/azure/monitor/logProfileArchiveData.spec.js index e3cc5158aa..7d4549584a 100644 --- a/plugins/azure/monitor/logProfileArchiveData.spec.js +++ b/plugins/azure/monitor/logProfileArchiveData.spec.js @@ -1,107 +1,50 @@ var expect = require('chai').expect; var logProfileArchiveData = require('./logProfileArchiveData'); -const logProfile = [ +const diagnosticSettings = [ { - "id": "/subscriptions/1234/providers/microsoft.insights/logprofiles/test", - "type": null, - "name": "default", - "location": null, - "kind": null, - "tags": null, - "identity": null, - "storageAccountId": "/subscriptions/1234/resourceGroups/Default-ActivityLogAlerts/providers/Microsoft.Storage/storageAccounts/devstoragetwo", - "serviceBusRuleId": null, - "locations": [ - "australiacentral", - "australiacentral2", - "australiaeast", - "australiasoutheast", - "brazilsouth", - "canadacentral", - "canadaeast", - "centralindia", - "centralus", - "eastasia", - "eastus", - "eastus2", - "francecentral", - "francesouth", - "japaneast", - "japanwest", - "koreacentral", - "koreasouth", - "northcentralus", - "northeurope", - "southafricanorth", - "southafricawest", - "southcentralus", - "southindia", - "southeastasia", - "uaecentral", - "uaenorth", - "uksouth", - "ukwest", - "westcentralus", - "westeurope", - "westindia", - "westus", - "westus2", - "westus3", - "eastus2euap", - "centraluseuap", - "jioindiawest", - "jioindiacentral", - "swedencentral", - "germanywestcentral", - "germanycentral", - "germanynortheast", - "germanynorth", - "norwayeast", - "switzerlandnorth", - "norwaywest", - "switzerlandwest", - "brazilsoutheast", - "global", - "qatarcentral", - "polandcentral", - "italynorth", - "israelcentral" - ], - "categories": [ - "Write", - "Delete", - "Action" - ], - "retentionPolicy": { - "enabled": true, - "days": 82 - } + 'id': '/subscriptions/123/providers/microsoft.insights/diagnosticSettings/test-setting', + 'type': 'Microsoft.Insights/diagnosticSettings', + 'name': 'test-setting', + 'location': 'global', + 'storageAccountId': '/subscriptions/123/resourceGroups/devresourcegroup/providers/Microsoft.Storage/storageAccounts/test-storage-account', + 'logs': [ + { 'category': 'Administrative', 'enabled': true }, + { 'category': 'Security', 'enabled': true } + ] }, { - "id": "/subscriptions/1234/providers/microsoft.insights/logprofiles/default", - "type": null, - "name": "default", - "location": null, - "kind": null, - "tags": null, - "identity": null, - "storageAccountId": "/subscriptions/1234/resourceGroups/Default-ActivityLogAlerts/providers/Microsoft.Storage/storageAccounts/devstoragetwo", - "serviceBusRuleId": null, - "retentionPolicy": { - "enabled": true, - "days": 82 - } + 'id': '/subscriptions/123/providers/microsoft.insights/diagnosticSettings/test-setting-eventhub', + 'type': 'Microsoft.Insights/diagnosticSettings', + 'name': 'test-setting-eventhub', + 'location': 'global', + 'eventHubAuthorizationRuleId': '/subscriptions/123/resourceGroups/aqua-resource-group/providers/Microsoft.EventHub/namespaces/test-setting/authorizationrules/RootManageSharedAccessKey', + 'eventHubName': '', + 'logs': [ + { 'category': 'Administrative', 'enabled': true }, + { 'category': 'Security', 'enabled': true } + ] + }, + { + 'id': '/subscriptions/123/providers/microsoft.insights/diagnosticSettings/test-setting-disabled', + 'type': 'Microsoft.Insights/diagnosticSettings', + 'name': 'test-setting-disabled', + 'location': 'global', + 'storageAccountId': '/subscriptions/123/resourceGroups/devresourcegroup/providers/Microsoft.Storage/storageAccounts/test-storage-account', + 'logs': [ + { 'category': 'Administrative', 'enabled': false }, + { 'category': 'Security', 'enabled': false } + ] } ]; -const createCache = (logProfile) => { +const createCache = (diagnosticSettings) => { let settings = {}; - if (logProfile) { - settings['data'] = logProfile; + if (diagnosticSettings) { + settings['data'] = diagnosticSettings; } return { - logProfiles: { + diagnosticSettingsOperations: { list: { 'global': settings } @@ -111,45 +54,56 @@ const createCache = (logProfile) => { describe('logProfileArchiveData', function() { describe('run', function() { - it('should give passing result if No existing Log Profiles found', function(done) { + it('should give failing result if no diagnostic settings found', function(done) { const cache = createCache([]); logProfileArchiveData.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(2); - expect(results[0].message).to.include('No existing Log Profiles found'); + expect(results[0].message).to.include('No existing Diagnostic Settings found'); expect(results[0].region).to.equal('global'); done(); }); }); - it('should give unknown result if Unable to query for Log Profiles', function(done) { + it('should give unknown result if unable to query for diagnostic settings', function(done) { const cache = createCache(); logProfileArchiveData.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(3); - expect(results[0].message).to.include('Unable to query for Log Profiles'); + expect(results[0].message).to.include('Unable to query for Diagnostic Settings'); expect(results[0].region).to.equal('global'); done(); }); }); - it('should give passing result if Log Profile is archiving all activities in all regions', function(done) { - const cache = createCache([logProfile[0]]); + it('should give passing result if a diagnostic setting archives activity logs to a storage account', function(done) { + const cache = createCache([diagnosticSettings[0]]); logProfileArchiveData.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(0); - expect(results[0].message).to.include('Log Profile is archiving all activities in all regions'); + expect(results[0].message).to.include('Diagnostic Setting is archiving Activity Logs to a storage account'); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should give failing result if no diagnostic setting archives activity logs to a storage account', function(done) { + const cache = createCache([diagnosticSettings[1]]); + logProfileArchiveData.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].message).to.include('No Diagnostic Setting is archiving Activity Logs to a storage account'); expect(results[0].region).to.equal('global'); done(); }); }); - it('should give failing result if Log Profile has the following issues', function(done) { - const cache = createCache([logProfile[1]]); + it('should give failing result if diagnostic setting has a storage account but no enabled logs', function(done) { + const cache = createCache([diagnosticSettings[2]]); logProfileArchiveData.run(cache, {}, (err, results) => { expect(results.length).to.equal(1); expect(results[0].status).to.equal(2); - expect(results[0].message).to.include('Log Profile has the following issues'); + expect(results[0].message).to.include('No Diagnostic Setting is archiving Activity Logs to a storage account'); expect(results[0].region).to.equal('global'); done(); }); diff --git a/plugins/azure/openai/accountCMKEncrypted.js b/plugins/azure/openai/accountCMKEncrypted.js index 82e68a978d..858576bb2b 100644 --- a/plugins/azure/openai/accountCMKEncrypted.js +++ b/plugins/azure/openai/accountCMKEncrypted.js @@ -37,9 +37,13 @@ module.exports = { for (let account of accounts.data) { - if (account.properties && account.properties.encryption && - account.properties.encryption.keySource && - account.properties.encryption.keySource.toLowerCase() == 'microsoft.keyvault') { + if (!account.id) continue; + + if (!account.kind || account.kind.toLowerCase() !== 'openai') continue; + + if (account.encryption && + account.encryption.keySource && + account.encryption.keySource.toLowerCase() == 'microsoft.keyvault') { helpers.addResult(results, 0, 'OpenAI Account is encrypted using CMK', location, account.id); } else { diff --git a/plugins/azure/openai/accountCMKEncrypted.spec.js b/plugins/azure/openai/accountCMKEncrypted.spec.js index 954c7f4432..d4fa76922a 100644 --- a/plugins/azure/openai/accountCMKEncrypted.spec.js +++ b/plugins/azure/openai/accountCMKEncrypted.spec.js @@ -5,17 +5,17 @@ const accounts = [ { "id": "/subscriptions/12424/resourceGroups/bvttest/providers/Microsoft.CognitiveServices/accounts/acc1", "name": "acc1", + "kind": "OpenAI", "type": "Microsoft.CognitiveServices/accounts", "location": "eastus", - "properties": { - "encryption": { - 'keySource': 'Microsoft.Keyvault' - } + "encryption": { + 'keySource': 'Microsoft.Keyvault' } }, { "id": "/subscriptions/12424/resourceGroups/bvttest/providers/Microsoft.CognitiveServices/accounts/acc2", "name": "acc2", + "kind": "OpenAI", "type": "Microsoft.CognitiveServices/accounts", "location": "eastus" }, @@ -56,6 +56,7 @@ describe('accountCMKEncrypted', function() { expect(results[0].region).to.equal('eastus'); done(); }); + }); it('should give unknown result if unable to query for openai accounts', function(done) { diff --git a/plugins/azure/openai/accountDiagnosticLogging.js b/plugins/azure/openai/accountDiagnosticLogging.js index d6667f3d04..d461327cbc 100644 --- a/plugins/azure/openai/accountDiagnosticLogging.js +++ b/plugins/azure/openai/accountDiagnosticLogging.js @@ -37,6 +37,9 @@ module.exports = { for (let account of accounts.data) { if (!account.id) continue; + + if (!account.kind || account.kind.toLowerCase() !== 'openai') continue; + var diagnosticSettings = helpers.addSource(cache, source, ['diagnosticSettings', 'listByOpenAIAccounts', location, account.id]); diff --git a/plugins/azure/openai/accountDiagnosticLogging.spec.js b/plugins/azure/openai/accountDiagnosticLogging.spec.js index e0b826c759..16961e464f 100644 --- a/plugins/azure/openai/accountDiagnosticLogging.spec.js +++ b/plugins/azure/openai/accountDiagnosticLogging.spec.js @@ -5,17 +5,17 @@ const accounts = [ { "id": "/subscriptions/12424/resourceGroups/bvttest/providers/Microsoft.CognitiveServices/accounts/acc1", "name": "acc1", + "kind": "OpenAI", "type": "Microsoft.CognitiveServices/accounts", "location": "eastus", - "properties": { - "encryption": { - 'keySource': 'Microsoft.Keyvault' - } + "encryption": { + 'keySource': 'Microsoft.Keyvault' } }, { "id": "/subscriptions/12424/resourceGroups/bvttest/providers/Microsoft.CognitiveServices/accounts/acc2", "name": "acc2", + "kind": "OpenAI", "type": "Microsoft.CognitiveServices/accounts", "location": "eastus" }, diff --git a/plugins/azure/openai/accountHasTags.js b/plugins/azure/openai/accountHasTags.js index fd989a37da..97a085c0ca 100644 --- a/plugins/azure/openai/accountHasTags.js +++ b/plugins/azure/openai/accountHasTags.js @@ -37,6 +37,10 @@ module.exports = { for (let account of accounts.data) { + if (!account.id) continue; + + if (!account.kind || account.kind.toLowerCase() !== 'openai') continue; + if (account.tags && Object.entries(account.tags).length > 0) { helpers.addResult(results, 0, 'OpenAI Account has tags associated', location, account.id); diff --git a/plugins/azure/openai/accountHasTags.spec.js b/plugins/azure/openai/accountHasTags.spec.js index 5d0327f0d0..31940c80a4 100644 --- a/plugins/azure/openai/accountHasTags.spec.js +++ b/plugins/azure/openai/accountHasTags.spec.js @@ -5,6 +5,7 @@ const accounts = [ { "id": "/subscriptions/12424/resourceGroups/bvttest/providers/Microsoft.CognitiveServices/accounts/acc1", "name": "acc1", + "kind": "OpenAI", "type": "Microsoft.CognitiveServices/accounts", "location": "eastus", "tags": { @@ -14,6 +15,7 @@ const accounts = [ { "id": "/subscriptions/12424/resourceGroups/bvttest/providers/Microsoft.CognitiveServices/accounts/acc2", "name": "acc2", + "kind": "OpenAI", "type": "Microsoft.CognitiveServices/accounts", "location": "eastus" }, diff --git a/plugins/azure/openai/accountManagedIdentity.js b/plugins/azure/openai/accountManagedIdentity.js index a1c4ca4189..32e9799546 100644 --- a/plugins/azure/openai/accountManagedIdentity.js +++ b/plugins/azure/openai/accountManagedIdentity.js @@ -37,6 +37,10 @@ module.exports = { for (let account of accounts.data) { + if (!account.id) continue; + + if (!account.kind || account.kind.toLowerCase() !== 'openai') continue; + if (account.identity && account.identity.type && (account.identity.type.toLowerCase() === 'systemassigned' || account.identity.type.toLowerCase() === 'userassigned')) { helpers.addResult(results, 0, diff --git a/plugins/azure/openai/accountManagedIdentity.spec.js b/plugins/azure/openai/accountManagedIdentity.spec.js index 84640d92a0..7e02196f6d 100644 --- a/plugins/azure/openai/accountManagedIdentity.spec.js +++ b/plugins/azure/openai/accountManagedIdentity.spec.js @@ -5,6 +5,7 @@ const accounts = [ { "id": "/subscriptions/12424/resourceGroups/bvttest/providers/Microsoft.CognitiveServices/accounts/acc1", "name": "acc1", + "kind": "OpenAI", "type": "Microsoft.CognitiveServices/accounts", "location": "eastus", "identity": { @@ -16,6 +17,7 @@ const accounts = [ { "id": "/subscriptions/12424/resourceGroups/bvttest/providers/Microsoft.CognitiveServices/accounts/acc2", "name": "acc2", + "kind": "OpenAI", "type": "Microsoft.CognitiveServices/accounts", "location": "eastus" }, diff --git a/plugins/azure/openai/accountPublicAccessDisabled.js b/plugins/azure/openai/accountPublicAccessDisabled.js index f050f6fca8..b7f66e2352 100644 --- a/plugins/azure/openai/accountPublicAccessDisabled.js +++ b/plugins/azure/openai/accountPublicAccessDisabled.js @@ -39,6 +39,8 @@ module.exports = { if (!account.id) continue; + if (!account.kind || account.kind.toLowerCase() !== 'openai') continue; + const publicAccess = account.publicNetworkAccess && account.publicNetworkAccess.toLowerCase(); if (publicAccess === 'disabled') { diff --git a/plugins/azure/openai/accountPublicAccessDisabled.spec.js b/plugins/azure/openai/accountPublicAccessDisabled.spec.js index 1c580dd606..2629bb485a 100644 --- a/plugins/azure/openai/accountPublicAccessDisabled.spec.js +++ b/plugins/azure/openai/accountPublicAccessDisabled.spec.js @@ -5,6 +5,7 @@ const accounts = [ { "id": "/subscriptions/12424/resourceGroups/bvttest/providers/Microsoft.CognitiveServices/accounts/acc1", "name": "acc1", + "kind": "OpenAI", "type": "Microsoft.CognitiveServices/accounts", "location": "eastus", "publicNetworkAccess": 'Disabled' @@ -12,6 +13,7 @@ const accounts = [ { "id": "/subscriptions/12424/resourceGroups/bvttest/providers/Microsoft.CognitiveServices/accounts/acc2", "name": "acc2", + "kind": "OpenAI", "type": "Microsoft.CognitiveServices/accounts", "location": "eastus", "publicNetworkAccess": 'Enabled' @@ -19,6 +21,7 @@ const accounts = [ { "id": "/subscriptions/12424/resourceGroups/bvttest/providers/Microsoft.CognitiveServices/accounts/acc4", "name": "acc4", + "kind": "OpenAI", "type": "Microsoft.CognitiveServices/accounts", "location": "eastus", "publicNetworkAccess": 'Enabled', @@ -30,6 +33,7 @@ const accounts = [ { "id": "/subscriptions/12424/resourceGroups/bvttest/providers/Microsoft.CognitiveServices/accounts/acc5", "name": "acc5", + "kind": "OpenAI", "type": "Microsoft.CognitiveServices/accounts", "location": "eastus", "publicNetworkAccess": 'Enabled', diff --git a/plugins/azure/storageaccounts/storageAccountPublicNetworkAccess.js b/plugins/azure/storageaccounts/storageAccountPublicNetworkAccess.js index 5770073488..a37da632af 100644 --- a/plugins/azure/storageaccounts/storageAccountPublicNetworkAccess.js +++ b/plugins/azure/storageaccounts/storageAccountPublicNetworkAccess.js @@ -55,9 +55,13 @@ module.exports = { } const restricted = account.networkAcls && account.networkAcls.defaultAction && account.networkAcls.defaultAction.toLowerCase() === 'deny'; + + const hasVirtualNetworks = account.networkAcls && account.networkAcls.virtualNetworkRules && account.networkAcls.virtualNetworkRules.length > 0; if ( restricted && !hasOpenCidr) { helpers.addResult(results, 0, 'Storage account has public network access disabled', location, account.id); + } else if (hasVirtualNetworks) { + helpers.addResult(results, 0, 'Storage account has public network access disabled', location, account.id); } else { helpers.addResult(results, 2, 'Storage account has public network access enabled for all networks', location, account.id); }