Skip to content

Commit

Permalink
Added environmentAccessLogs plugin and spec (aquasecurity#1015)
Browse files Browse the repository at this point in the history
* 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
3 people authored Dec 27, 2021
1 parent 8698e25 commit b5ff4a6
Show file tree
Hide file tree
Showing 3 changed files with 298 additions and 0 deletions.
1 change: 1 addition & 0 deletions exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ module.exports = {
'ecrRepositoryTagImmutability' : require(__dirname + '/plugins/aws/ecr/ecrRepositoryTagImmutability.js'),

'managedPlatformUpdates' : require(__dirname + '/plugins/aws/elasticbeanstalk/managedPlatformUpdates.js'),
'environmentAccessLogs' : require(__dirname + '/plugins/aws/elasticbeanstalk/environmentAccessLogs.js'),

'eksKubernetesVersion' : require(__dirname + '/plugins/aws/eks/eksKubernetesVersion.js'),
'eksLoggingEnabled' : require(__dirname + '/plugins/aws/eks/eksLoggingEnabled.js'),
Expand Down
76 changes: 76 additions & 0 deletions plugins/aws/elasticbeanstalk/environmentAccessLogs.js
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 plugins/aws/elasticbeanstalk/environmentAccessLogs.spec.js
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();
});
});
});
});

0 comments on commit b5ff4a6

Please sign in to comment.