forked from aquasecurity/cloudsploit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added environmentAccessLogs plugin and spec (aquasecurity#1015)
* Added environmentAccessLogs plugin and spec * Incorporated feedback changes * Update plugins/aws/elasticbeanstalk/environmentAccessLogs.js * Update plugins/aws/elasticbeanstalk/environmentAccessLogs.js * Update plugins/aws/elasticbeanstalk/environmentAccessLogs.js * Update plugins/aws/elasticbeanstalk/environmentAccessLogs.js * Update plugins/aws/elasticbeanstalk/environmentAccessLogs.js * Update plugins/aws/elasticbeanstalk/environmentAccessLogs.js * Update plugins/aws/elasticbeanstalk/environmentAccessLogs.js * Update plugins/aws/elasticbeanstalk/environmentAccessLogs.js * Update environmentAccessLogs.js Co-authored-by: AkhtarAmir <[email protected]> Co-authored-by: AkhtarAmir <[email protected]>
- Loading branch information
1 parent
8698e25
commit b5ff4a6
Showing
3 changed files
with
298 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
var async = require('async'); | ||
var helpers = require('../../../helpers/aws'); | ||
|
||
module.exports = { | ||
title: 'Environment Access Logs', | ||
category: 'ElasticBeanstalk', | ||
domain: 'Application Integration', | ||
description: 'Ensure that your Amazon Elastic Beanstalk environment is configured to save logs for load balancer associated with the application environment.', | ||
more_info: 'Elastic Load Balancing provides access logs that capture detailed information about requests sent to your load balancer. Each log contains information such as the time the request was received, the client\'s IP address, latencies, request paths, and server responses. You can use these access logs to analyze traffic patterns and troubleshoot issues.', | ||
recommended_action: 'Go to specific environment, select Configuration, edit Load Balancer category, and enable Store logs', | ||
link: 'https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html', | ||
apis: ['ElasticBeanstalk:describeEnvironments', 'ElasticBeanstalk:describeConfigurationSettings'], | ||
|
||
run: function(cache, settings, callback) { | ||
var results = []; | ||
var source = {}; | ||
var regions = helpers.regions(settings); | ||
|
||
async.each(regions.elasticbeanstalk, function(region, rcb){ | ||
var describeEnvironments = helpers.addSource(cache, source, ['elasticbeanstalk', 'describeEnvironments', region]); | ||
|
||
if (!describeEnvironments) return rcb(); | ||
|
||
if (describeEnvironments.err || !describeEnvironments.data) { | ||
helpers.addResult(results, 3, | ||
'Unable to query for ElasticBeanstalk environments: ' + helpers.addError(describeEnvironments), region); | ||
return rcb(); | ||
} | ||
|
||
if (!describeEnvironments.data.length) { | ||
helpers.addResult(results, 0, | ||
'No ElasticBeanstalk environments found', region); | ||
return rcb(); | ||
} | ||
|
||
async.each(describeEnvironments.data, function(environment, ecb){ | ||
var resource = environment.EnvironmentArn; | ||
var describeConfigurationSettings = helpers.addSource(cache, source, ['elasticbeanstalk', 'describeConfigurationSettings', region, environment.EnvironmentArn]); | ||
|
||
if (!describeConfigurationSettings || | ||
describeConfigurationSettings.err || | ||
!describeConfigurationSettings.data || | ||
!describeConfigurationSettings.data.ConfigurationSettings) { | ||
helpers.addResult(results, 3, | ||
'Unable to query for environment configuration settings: ' + helpers.addError(describeConfigurationSettings), | ||
region, resource); | ||
return ecb(); | ||
} | ||
|
||
if (!describeConfigurationSettings.data.ConfigurationSettings.length) { | ||
helpers.addResult(results, 2, 'Environment does not have any log configuration', region, resource); | ||
return ecb(); | ||
} | ||
|
||
let OptionSettings = describeConfigurationSettings.data.ConfigurationSettings.map(({ OptionSettings }) => OptionSettings ); | ||
let accesLogs = OptionSettings.flat().find(option => option.OptionName === 'AccessLogsS3Enabled' ); | ||
|
||
if (accesLogs && accesLogs.Value === 'true') { | ||
helpers.addResult(results, 0, | ||
'Access Logs for environment: ' + environment.EnvironmentName + ' are enabled', | ||
region, resource); | ||
} else { | ||
helpers.addResult(results, 2, | ||
'Access Logs for environment: ' + environment.EnvironmentName + ' are not enabled', | ||
region, resource); | ||
} | ||
|
||
ecb(); | ||
}, function() { | ||
rcb(); | ||
}); | ||
}, function(){ | ||
callback(null, results, source); | ||
}); | ||
} | ||
}; |
221 changes: 221 additions & 0 deletions
221
plugins/aws/elasticbeanstalk/environmentAccessLogs.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
var expect = require('chai').expect; | ||
var environmentAccessLogs = require('./environmentAccessLogs'); | ||
|
||
const environments = [ | ||
{ | ||
"EnvironmentName": "Akhtar681-env-2", | ||
"EnvironmentId": "e-bucuvmfa4a", | ||
"ApplicationName": "akhtar-681", | ||
"VersionLabel": "Sample Application", | ||
"SolutionStackName": "64bit Amazon Linux 2 v3.1.0 running Python 3.7", | ||
"PlatformArn": "arn:aws:elasticbeanstalk:us-east-1::platform/Python 3.7 running on 64bit Amazon Linux 2/3.1.0", | ||
"EndpointURL": "54.167.147.57", | ||
"CNAME": "Akhtar681-env-2.eba-g3c99pdr.us-east-1.elasticbeanstalk.com", | ||
"DateCreated": "2020-08-22T17:02:36.060Z", | ||
"DateUpdated": "2020-08-22T17:05:59.178Z", | ||
"Status": "Ready", | ||
"AbortableOperationInProgress": false, | ||
"Health": "Green", | ||
"HealthStatus": "Ok", | ||
"Tier": { | ||
"Name": "WebServer", | ||
"Type": "Standard", | ||
"Version": "1.0" | ||
}, | ||
"EnvironmentLinks": [], | ||
"EnvironmentArn": "arn:aws:elasticbeanstalk:us-east-1:123456654321:environment/akhtar-681/Akhtar681-env-2" | ||
}, | ||
{ | ||
"EnvironmentName": "Akhtar681-env-1", | ||
"EnvironmentId": "e-3bb85da33w", | ||
"ApplicationName": "akhtar-681", | ||
"VersionLabel": "Sample Application", | ||
"SolutionStackName": "64bit Amazon Linux 2 v3.1.0 running Python 3.7", | ||
"PlatformArn": "arn:aws:elasticbeanstalk:us-east-1::platform/Python 3.7 running on 64bit Amazon Linux 2/3.1.0", | ||
"EndpointURL": "54.92.177.151", | ||
"CNAME": "Akhtar681-env-1.eba-g3c99pdr.us-east-1.elasticbeanstalk.com", | ||
"DateCreated": "2020-08-22T16:08:13.720Z", | ||
"DateUpdated": "2020-08-22T16:52:06.836Z", | ||
"Status": "Ready", | ||
"AbortableOperationInProgress": false, | ||
"Health": "Green", | ||
"HealthStatus": "Ok", | ||
"Tier": { | ||
"Name": "WebServer", | ||
"Type": "Standard", | ||
"Version": "1.0" | ||
}, | ||
"EnvironmentLinks": [], | ||
"EnvironmentArn": "arn:aws:elasticbeanstalk:us-east-1:123456654321:environment/akhtar-681/Akhtar681-env-1" | ||
} | ||
]; | ||
|
||
const configurationSettings = [ | ||
{ | ||
SolutionStackName: '64bit Amazon Linux 2 v3.1.0 running Python 3.7', | ||
PlatformArn: 'arn:aws:elasticbeanstalk:us-east-1::platform/Python 3.7 running on 64bit Amazon Linux 2/3.1.0', | ||
ApplicationName: 'akhtar-681', | ||
EnvironmentName: 'Akhtar681-env-1', | ||
DeploymentStatus: 'deployed', | ||
DateCreated: '2020-08-22T16:08:12.000Z', | ||
DateUpdated: '2020-08-22T16:50:53.000Z', | ||
OptionSettings: [ | ||
{ | ||
Namespace: 'aws:elasticbeanstalk:managedactions', | ||
OptionName: 'ManagedActionsEnabled', | ||
Value: 'false' | ||
}, | ||
{ | ||
Namespace: 'aws:elasticbeanstalk:managedactions', | ||
OptionName: 'PreferredStartTime', | ||
Value: 'Sat:03:00' | ||
}, | ||
{ | ||
Namespace: 'aws:elasticbeanstalk:managedactions', | ||
OptionName: 'ServiceRoleForManagedUpdates', | ||
Value: 'arn:aws:iam::123456654321:role/aws-elasticbeanstalk-service-role' | ||
}, | ||
{ | ||
Namespace: 'aws:elasticbeanstalk:managedactions:platformupdate', | ||
OptionName: 'AccessLogsS3Enabled', | ||
Value: 'true' | ||
} | ||
] | ||
}, | ||
{ | ||
SolutionStackName: '64bit Amazon Linux 2 v3.1.0 running Python 3.7', | ||
PlatformArn: 'arn:aws:elasticbeanstalk:us-east-1::platform/Python 3.7 running on 64bit Amazon Linux 2/3.1.0', | ||
ApplicationName: 'akhtar-681', | ||
EnvironmentName: 'Akhtar681-env-1', | ||
DeploymentStatus: 'deployed', | ||
DateCreated: '2020-08-22T16:08:12.000Z', | ||
DateUpdated: '2020-08-22T16:50:53.000Z', | ||
OptionSettings: [ | ||
{ | ||
Namespace: 'aws:elasticbeanstalk:managedactions', | ||
OptionName: 'ManagedActionsEnabled', | ||
Value: 'true' | ||
}, | ||
{ | ||
Namespace: 'aws:elasticbeanstalk:managedactions', | ||
OptionName: 'PreferredStartTime', | ||
Value: 'Sat:03:00' | ||
}, | ||
{ | ||
Namespace: 'aws:elasticbeanstalk:managedactions', | ||
OptionName: 'ServiceRoleForManagedUpdates', | ||
Value: 'arn:aws:iam::123456654321:role/aws-elasticbeanstalk-service-role' | ||
}, | ||
{ | ||
Namespace: 'aws:elasticbeanstalk:managedactions:platformupdate', | ||
OptionName: 'AccessLogsS3Enabled', | ||
Value: 'false' | ||
} | ||
] | ||
} | ||
]; | ||
|
||
const createCache = (environments, configurationSettings) => { | ||
if (environments.length) var environmentArn = environments[0].EnvironmentArn; | ||
return { | ||
elasticbeanstalk: { | ||
describeEnvironments: { | ||
'us-east-1': { | ||
data: environments | ||
}, | ||
}, | ||
describeConfigurationSettings: { | ||
'us-east-1': { | ||
[environmentArn]: { | ||
data: { | ||
ConfigurationSettings: configurationSettings | ||
} | ||
} | ||
}, | ||
}, | ||
}, | ||
}; | ||
}; | ||
|
||
|
||
const createErrorCache = () => { | ||
return { | ||
elasticbeanstalk: { | ||
describeEnvironments: { | ||
'us-east-1': { | ||
err: { | ||
message: 'error describing environments' | ||
}, | ||
}, | ||
}, | ||
}, | ||
}; | ||
}; | ||
|
||
const createNullCache = () => { | ||
return { | ||
elasticbeanstalk: { | ||
describeEnvironments: { | ||
'us-east-1': null, | ||
}, | ||
}, | ||
}; | ||
}; | ||
|
||
describe('environmentAccessLogs', function () { | ||
describe('run', function () { | ||
|
||
it('should PASS if unable to get application environments', function (done) { | ||
const cache = createCache([]); | ||
environmentAccessLogs.run(cache, {}, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(0); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should FAIL if unable to get configuration settings', function (done) { | ||
const cache = createCache([environments[0]],[]); | ||
environmentAccessLogs.run(cache, {}, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(2); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should FAIL if environment access logs are not enabled for application environment', function (done) { | ||
const cache = createCache([environments[1]], [configurationSettings[1]]); | ||
environmentAccessLogs.run(cache, {}, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(2); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should PASS if environment access logs are enabled for application environment', function (done) { | ||
const cache = createCache([environments[0]], [configurationSettings[0]]); | ||
environmentAccessLogs.run(cache, {}, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(0); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should not return any results if unable to get environments', function (done) { | ||
const cache = createNullCache(); | ||
environmentAccessLogs.run(cache, {}, (err, results) => { | ||
expect(results.length).to.equal(0); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should UNKNOWN if error occurs while fetching environments', function (done) { | ||
const cache = createErrorCache(); | ||
environmentAccessLogs.run(cache, {}, (err, results) => { | ||
expect(results.length).to.equal(1); | ||
expect(results[0].status).to.equal(3); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |