diff --git a/plugins/aws/cloudfront/cloudfrontHttpsOnly.spec.js b/plugins/aws/cloudfront/cloudfrontHttpsOnly.spec.js new file mode 100644 index 0000000000..70f6c1abb4 --- /dev/null +++ b/plugins/aws/cloudfront/cloudfrontHttpsOnly.spec.js @@ -0,0 +1,200 @@ +var expect = require('chai').expect; +const cloudfrontHttpsOnly = require('./cloudfrontHttpsOnly'); + +const listDistributions = [ + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "Origins": { + "Quantity": 1, + "Items": [ + { + "Id": "S3-cdn-oai/data", + "DomainName": "cdn-oai.s3.amazonaws.com", + "OriginPath": "/data", + } + ] + }, + "OriginGroups": { + "Quantity": 0 + }, + "DefaultCacheBehavior": { + "TargetOriginId": "S3-cdn-oai/data", + "TrustedSigners": { + "Enabled": false, + "Quantity": 0 + }, + "TrustedKeyGroups": { + "Enabled": false, + "Quantity": 0 + }, + "ViewerProtocolPolicy": "https-only", + "AllowedMethods": { + "Quantity": 2, + "Items": [ + "HEAD", + "GET" + ], + }, + }, + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "Origins": { + "Quantity": 1, + "Items": [ + { + "Id": "S3-cdn-oai/data", + "DomainName": "cdn-oai.s3.amazonaws.com", + "OriginPath": "/data", + } + ] + }, + "OriginGroups": { + "Quantity": 0 + }, + "DefaultCacheBehavior": { + "TargetOriginId": "S3-cdn-oai/data", + "TrustedSigners": { + "Enabled": false, + "Quantity": 0 + }, + "TrustedKeyGroups": { + "Enabled": false, + "Quantity": 0 + }, + "ViewerProtocolPolicy": "redirect-to-https", + "AllowedMethods": { + "Quantity": 2, + "Items": [ + "HEAD", + "GET" + ], + }, + }, + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "Origins": { + "Quantity": 1, + "Items": [ + { + "Id": "S3-cdn-oai/data", + "DomainName": "cdn-oai.s3.amazonaws.com", + "OriginPath": "/data", + } + ] + }, + "OriginGroups": { + "Quantity": 0 + }, + "DefaultCacheBehavior": { + "TargetOriginId": "S3-cdn-oai/data", + "TrustedSigners": { + "Enabled": false, + "Quantity": 0 + }, + "TrustedKeyGroups": { + "Enabled": false, + "Quantity": 0 + }, + "ViewerProtocolPolicy": "http-and-https", + "AllowedMethods": { + "Quantity": 2, + "Items": [ + "HEAD", + "GET" + ], + }, + } + } +]; + +const createCache = (data, err) => { + return { + cloudfront: { + listDistributions: { + 'us-east-1': { + data: data, + err: err + } + } + } + }; +}; + + +const createNullCache = () => { + return { + cloudfront: { + listDistributions: { + 'us-east-1': null, + }, + }, + }; +}; + +describe('cloudfrontHttpsOnly', function () { + describe('run', function () { + it('should PASS if CloudFront distribution is set to use HTTPS only', function (done) { + const cache = createCache([listDistributions[0]]); + cloudfrontHttpsOnly.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should PASS if CloudFront distribution is configured to redirect non-HTTPS traffic to HTTPS', function (done) { + const cache = createCache([listDistributions[1]]); + cloudfrontHttpsOnly.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should FAIL if CloudFront distribution is not configured to use HTTPS', function (done) { + const cache = createCache([listDistributions[2]]); + cloudfrontHttpsOnly.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should PASS if no CloudFront distributions found', function (done) { + const cache = createCache([]); + cloudfrontHttpsOnly.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should UNKNOWN if unable to list distributions', function (done) { + const cache = createCache([], { message: 'Unable to list distributions' }); + cloudfrontHttpsOnly.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(3); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should not return any results if list distributions response not found', function (done) { + const cache = createNullCache(); + cloudfrontHttpsOnly.run(cache, {}, (err, results) => { + expect(results.length).to.equal(0); + done(); + }); + }); + + }); +}); \ No newline at end of file diff --git a/plugins/aws/cloudfront/cloudfrontLoggingEnabled.js b/plugins/aws/cloudfront/cloudfrontLoggingEnabled.js index 93d96c595f..860543890b 100644 --- a/plugins/aws/cloudfront/cloudfrontLoggingEnabled.js +++ b/plugins/aws/cloudfront/cloudfrontLoggingEnabled.js @@ -60,6 +60,12 @@ module.exports = { var getDistribution = helpers.addSource(cache, source, ['cloudfront', 'getDistribution', region, Distribution.Id]); + if (!getDistribution || getDistribution.err || !getDistribution.data || !getDistribution.data.Distribution) { + helpers.addResult(results, 3, + `Unable to get CloudFront distribution: ${helpers.addError(getDistribution)}`); + return; + } + if (getDistribution.data && getDistribution.data.Distribution && getDistribution.data.Distribution.DistributionConfig && diff --git a/plugins/aws/cloudfront/cloudfrontLoggingEnabled.spec.js b/plugins/aws/cloudfront/cloudfrontLoggingEnabled.spec.js new file mode 100644 index 0000000000..e5b52cffc8 --- /dev/null +++ b/plugins/aws/cloudfront/cloudfrontLoggingEnabled.spec.js @@ -0,0 +1,178 @@ +var expect = require('chai').expect; +const cloudfrontLoggingEnabled = require('./cloudfrontLoggingEnabled'); + +const listDistributions = [ + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "Origins": { + "Quantity": 1, + "Items": [ + { + "Id": "S3-cdn-oai/data", + "DomainName": "cdn-oai.s3.amazonaws.com", + "OriginPath": "/data", + } + ] + }, + "OriginGroups": { + "Quantity": 0 + }, + "DefaultCacheBehavior": { + "TargetOriginId": "S3-cdn-oai/data", + "TrustedSigners": { + "Enabled": false, + "Quantity": 0 + }, + "TrustedKeyGroups": { + "Enabled": false, + "Quantity": 0 + }, + "ViewerProtocolPolicy": "https-only", + "AllowedMethods": { + "Quantity": 2, + "Items": [ + "HEAD", + "GET" + ], + }, + }, + } +]; + +const getDistribution = [ + { + "ETag": "EHQJVBQTCVNEN", + "Distribution": { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "DistributionConfig": { + "DefaultRootObject": "", + "OriginGroups": { + "Quantity": 0 + }, + "Logging": { + "Enabled": true, + "IncludeCookies": false, + "Bucket": "s3://abc", + "Prefix": "logs/" + }, + } + } + }, + { + "ETag": "EHQJVBQTCVNEN", + "Distribution": { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "DistributionConfig": { + "DefaultRootObject": "", + "OriginGroups": { + "Quantity": 0 + }, + "Logging": { + "Enabled": false, + "IncludeCookies": false, + "Bucket": "", + "Prefix": "" + }, + } + } + } +]; + +const createCache = (data, err, getData, getErr) => { + var distributionId = (data && data.length) ? data[0].Id : null; + return { + cloudfront: { + listDistributions: { + 'us-east-1': { + data: data, + err: err + } + }, + getDistribution: { + 'us-east-1': { + [distributionId]: { + data: getData, + err: getErr + } + } + } + } + }; +}; + + +const createNullCache = () => { + return { + cloudfront: { + listDistributions: { + 'us-east-1': null, + }, + }, + }; +}; + +describe('cloudfrontLoggingEnabled', function () { + describe('run', function () { + it('should PASS if Request logging is enabled', function (done) { + const cache = createCache([listDistributions[0]], null, getDistribution[0]); + cloudfrontLoggingEnabled.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should FAIL if Request logging is not enabled', function (done) { + const cache = createCache([listDistributions[0]], null, getDistribution[1]); + cloudfrontLoggingEnabled.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should PASS if no CloudFront distributions found', function (done) { + const cache = createCache([]); + cloudfrontLoggingEnabled.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should UNKNOWN if unable to list distributions', function (done) { + const cache = createCache([], { message: 'Unable to list distributions' }); + cloudfrontLoggingEnabled.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(3); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should UNKNOWN if unable to get distributions', function (done) { + const cache = createCache([listDistributions[0]], null, null, { message: 'Unable to get distribution'}); + cloudfrontLoggingEnabled.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(3); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should not return any results if list distributions response not found', function (done) { + const cache = createNullCache(); + cloudfrontLoggingEnabled.run(cache, {}, (err, results) => { + expect(results.length).to.equal(0); + done(); + }); + }); + + }); +}); \ No newline at end of file diff --git a/plugins/aws/cloudfront/cloudfrontWafEnabled.js b/plugins/aws/cloudfront/cloudfrontWafEnabled.js index e55786f44a..0d5b7f90cb 100644 --- a/plugins/aws/cloudfront/cloudfrontWafEnabled.js +++ b/plugins/aws/cloudfront/cloudfrontWafEnabled.js @@ -7,7 +7,7 @@ module.exports = { more_info: 'Enabling WAF allows control over requests to the Cloudfront Distribution, allowing or denying traffic based off rules in the Web ACL', link: 'https://docs.aws.amazon.com/waf/latest/developerguide/web-acl-associating-cloudfront-distribution.html', recommended_action: '1. Enter the WAF service. 2. Enter Web ACLs and filter by global. 3. If no Web ACL is found, Create a new global Web ACL and in Resource type to associate with web ACL, select the Cloudfront Distribution. ', - apis: ['CloudFront:listDistributions', 'CloudFront:getDistribution'], + apis: ['CloudFront:listDistributions'], run: function(cache, settings, callback) { @@ -37,13 +37,13 @@ module.exports = { if (!distribution.WebACLId || distribution.WebACLId === '') { helpers.addResult(results, 2, - 'The Cloudfront Distribution does not have WAF enabled', ['global'], distribution.ARN); + 'The Cloudfront Distribution does not have WAF enabled', 'global', distribution.ARN); badFlag = true; } }); if (!badFlag) { - helpers.addResult(results, 0, 'All CloudFront distributions have WAF enabled'); + helpers.addResult(results, 0, 'All CloudFront distributions have WAF enabled', 'global'); } return callback(null, results, source); diff --git a/plugins/aws/cloudfront/cloudfrontWafEnabled.spec.js b/plugins/aws/cloudfront/cloudfrontWafEnabled.spec.js new file mode 100644 index 0000000000..aa596fa660 --- /dev/null +++ b/plugins/aws/cloudfront/cloudfrontWafEnabled.spec.js @@ -0,0 +1,92 @@ +var expect = require('chai').expect; +const cloudfrontWafEnabled = require('./cloudfrontWafEnabled'); + +const listDistributions = [ + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "WebACLId": "ca44237b-b1d8-46b2-abad-ada48c7f0894", + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "WebACLId": "", + } +]; + +const createCache = (data, err) => { + return { + cloudfront: { + listDistributions: { + 'us-east-1': { + data: data, + err: err + } + } + } + }; +}; + + +const createNullCache = () => { + return { + cloudfront: { + listDistributions: { + 'us-east-1': null, + }, + }, + }; +}; + +describe('cloudfrontWafEnabled', function () { + describe('run', function () { + it('should PASS if All CloudFront distributions have WAF enabled', function (done) { + const cache = createCache([listDistributions[0]]); + cloudfrontWafEnabled.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should FAIL if The Cloudfront Distribution does not have WAF enabled', function (done) { + const cache = createCache([listDistributions[1]]); + cloudfrontWafEnabled.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should PASS if no CloudFront distributions found', function (done) { + const cache = createCache([]); + cloudfrontWafEnabled.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should UNKNOWN if unable to list distributions', function (done) { + const cache = createCache([], { message: 'Unable to list distributions' }); + cloudfrontWafEnabled.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(3); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should not return any results if list distributions response not found', function (done) { + const cache = createNullCache(); + cloudfrontWafEnabled.run(cache, {}, (err, results) => { + expect(results.length).to.equal(0); + done(); + }); + }); + + }); +}); \ No newline at end of file diff --git a/plugins/aws/cloudfront/insecureProtocols.spec.js b/plugins/aws/cloudfront/insecureProtocols.spec.js new file mode 100644 index 0000000000..ef52472be0 --- /dev/null +++ b/plugins/aws/cloudfront/insecureProtocols.spec.js @@ -0,0 +1,204 @@ +var expect = require('chai').expect; +const insecureProtocols = require('./insecureProtocols'); + +const listDistributions = [ + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "ViewerCertificate": { + "CloudFrontDefaultCertificate": true, + "MinimumProtocolVersion": "TLSv1", + "CertificateSource": "cloudfront" + }, + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "ViewerCertificate": { + "CloudFrontDefaultCertificate": true, + "MinimumProtocolVersion": "TLSv1", + "CertificateSource": "cloudfront" + }, + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "ViewerCertificate": { + "MinimumProtocolVersion": "SSLv3", + "CertificateSource": "cloudfront" + }, + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "ViewerCertificate": { + "MinimumProtocolVersion": "TLSv1", + "CertificateSource": "cloudfront" + }, + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "ViewerCertificate": { + "MinimumProtocolVersion": "TLSv1_2016", + "CertificateSource": "cloudfront" + }, + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "ViewerCertificate": { + "MinimumProtocolVersion": "TLSv1.1_2016", + "CertificateSource": "cloudfront" + }, + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "ViewerCertificate": { + "MinimumProtocolVersion": "TLSv1.2_2018", + "CertificateSource": "cloudfront" + }, + } +]; + +const createCache = (data, err) => { + return { + cloudfront: { + listDistributions: { + 'us-east-1': { + data: data, + err: err + } + } + } + }; +}; + + +const createNullCache = () => { + return { + cloudfront: { + listDistributions: { + 'us-east-1': null, + }, + }, + }; +}; + +describe('insecureProtocols', function () { + describe('run', function () { + it('should PASS if Distribution is not configured for SSL delivery', function (done) { + const cache = createCache([listDistributions[0]]); + insecureProtocols.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should PASS if Distribution is using secure default certificate', function (done) { + const cache = createCache([listDistributions[1]]); + insecureProtocols.run(cache, { insecure_cloudfront_ignore_default: 'true' }, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should FAIL if Distribution is using the insecure default CloudFront TLS certificate', function (done) { + const cache = createCache([listDistributions[2]]); + insecureProtocols.run(cache, { insecure_cloudfront_ignore_default: 'false' }, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should FAIL if Distribution is using insecure SSLv3', function (done) { + const cache = createCache([listDistributions[3]]); + insecureProtocols.run(cache, { insecure_cloudfront_ignore_default: 'false' }, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should FAIL if Distribution is using insecure TLSv1.0', function (done) { + const cache = createCache([listDistributions[4]]); + insecureProtocols.run(cache, { insecure_cloudfront_ignore_default: 'false' }, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should FAIL if Distribution is using insecure TLSv1_2016', function (done) { + const cache = createCache([listDistributions[5]]); + insecureProtocols.run(cache, { insecure_cloudfront_ignore_default: 'false' }, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should PASS if Distribution is using secure TLSv1.1_2016', function (done) { + const cache = createCache([listDistributions[6]]); + insecureProtocols.run(cache, { insecure_cloudfront_ignore_default: 'true' }, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should PASS if Distribution is using secure TLSv1.2_2018', function (done) { + const cache = createCache([listDistributions[7]]); + insecureProtocols.run(cache, { insecure_cloudfront_ignore_default: 'true' }, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should PASS if no CloudFront distributions found', function (done) { + const cache = createCache([]); + insecureProtocols.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should UNKNOWN if unable to list distributions', function (done) { + const cache = createCache([], { message: 'Unable to list distributions' }); + insecureProtocols.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(3); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should not return any results if list distributions response not found', function (done) { + const cache = createNullCache(); + insecureProtocols.run(cache, {}, (err, results) => { + expect(results.length).to.equal(0); + done(); + }); + }); + + }); +}); \ No newline at end of file diff --git a/plugins/aws/cloudfront/publicS3Origin.spec.js b/plugins/aws/cloudfront/publicS3Origin.spec.js new file mode 100644 index 0000000000..5f407484b2 --- /dev/null +++ b/plugins/aws/cloudfront/publicS3Origin.spec.js @@ -0,0 +1,139 @@ +var expect = require('chai').expect; +const publicS3Origin = require('./publicS3Origin'); + +const listDistributions = [ + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "Origins": { + "Quantity": 1, + "Items": [ + { + "Id": "S3-cdn-oai/data", + "DomainName": "cdn-oai.s3.amazonaws.com", + "OriginPath": "/data", + "S3OriginConfig": { + "OriginAccessIdentity": null + }, + } + ] + }, + "OriginGroups": { + "Quantity": 0 + }, + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "Origins": { + "Quantity": 1, + "Items": [ + { + "Id": "S3-cdn-oai/data", + "DomainName": "cdn-oai.s3.amazonaws.com", + "OriginPath": "/data", + "S3OriginConfig": { + "OriginAccessIdentity": "origin-access-identity/cloudfront/E1FNBIV9X9FNYA" + }, + } + ] + }, + "OriginGroups": { + "Quantity": 0 + }, + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "Origins": { + "Quantity": 1, + "Items": [ + { + "Id": "S3-cdn-oai/data", + "DomainName": "cdn-oai.s3.amazonaws.com", + "OriginPath": "/data", + } + ] + }, + "OriginGroups": { + "Quantity": 0 + } + } +]; + +const createCache = (data, err) => { + return { + cloudfront: { + listDistributions: { + 'us-east-1': { + data: data, + err: err + } + } + } + }; +}; + + +const createNullCache = () => { + return { + cloudfront: { + listDistributions: { + 'us-east-1': null, + }, + }, + }; +}; + +describe('publicS3Origin', function () { + describe('run', function () { + it('should PASS if CloudFront distribution origin is not setup without an origin access identity', function (done) { + const cache = createCache([listDistributions[1]]); + publicS3Origin.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should FAIL if CloudFront CloudFront distribution is using an S3 origin without an origin access identity', function (done) { + const cache = createCache([listDistributions[0]]); + publicS3Origin.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should PASS if no CloudFront distributions found', function (done) { + const cache = createCache([]); + publicS3Origin.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should UNKNOWN if unable to list distributions', function (done) { + const cache = createCache([], { message: 'Unable to list distributions' }); + publicS3Origin.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(3); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should not return any results if list distributions response not found', function (done) { + const cache = createNullCache(); + publicS3Origin.run(cache, {}, (err, results) => { + expect(results.length).to.equal(0); + done(); + }); + }); + + }); +}); \ No newline at end of file diff --git a/plugins/aws/cloudfront/secureOrigin.spec.js b/plugins/aws/cloudfront/secureOrigin.spec.js new file mode 100644 index 0000000000..256ba95f17 --- /dev/null +++ b/plugins/aws/cloudfront/secureOrigin.spec.js @@ -0,0 +1,220 @@ +var expect = require('chai').expect; +const secureOrigin = require('./secureOrigin'); + +const listDistributions = [ + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "Origins": { + "Items": [ + { + "CustomOriginConfig": { + "HTTPPort": 80, + "HTTPSPort": 443, + "OriginProtocolPolicy": "http-only", + "OriginSslProtocols": { + "Quantity": 4, + "Items": [ + "SSLv3", + "TLSv1", + "TLSv1.1", + "TLSv1.2" + ] + }, + "OriginReadTimeout": 30, + "OriginKeepaliveTimeout": 5 + }, + } + ] + } + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "Origins": { + "Items": [ + { + "CustomOriginConfig": { + "HTTPPort": 80, + "HTTPSPort": 443, + "OriginProtocolPolicy": "https-only", + "OriginSslProtocols": { + "Quantity": 4, + "Items": [ + "SSLv3", + "TLSv1", + "TLSv1.1", + "TLSv1.2" + ] + }, + "OriginReadTimeout": 30, + "OriginKeepaliveTimeout": 5 + }, + } + ] + } + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "Origins": { + "Items": [ + { + "CustomOriginConfig": { + "HTTPPort": 80, + "HTTPSPort": 443, + "OriginProtocolPolicy": "match-viewer", + "OriginSslProtocols": { + "Quantity": 3, + "Items": [ + "TLSv1", + "TLSv1.1", + "TLSv1.2" + ] + }, + }, + } + ] + }, + }, + { + "Id": "E1JHW5DZR5X4HW", + "ARN": "arn:aws:cloudfront::111122223333:distribution/E1JHW5DZR5X4HW", + "Origins": { + "Items": [ + { + "CustomOriginConfig": { + "HTTPPort": 80, + "HTTPSPort": 443, + "OriginProtocolPolicy": "match-viewer", + "OriginSslProtocols": { + "Quantity": 3, + "Items": [ + "SSLv3", + "TLSv1.1", + "TLSv1.2" + ] + }, + }, + } + ] + } + } +]; + +const createCache = (data, err) => { + return { + cloudfront: { + listDistributions: { + 'us-east-1': { + data: data, + err: err + } + } + } + }; +}; + + +const createNullCache = () => { + return { + cloudfront: { + listDistributions: { + 'us-east-1': null, + }, + }, + }; +}; + +describe('secureOrigin', function () { + describe('run', function () { + it('should PASS if CloudFront origin is using https-only', function (done) { + const cache = createCache([listDistributions[1]]); + secureOrigin.run(cache, {}, (err, results) => { + expect(results.length).to.equal(2); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should WARN if CloudFront origin is using match-viewer', function (done) { + const cache = createCache([listDistributions[2]]); + secureOrigin.run(cache, {}, (err, results) => { + expect(results.length).to.equal(2); + expect(results[0].status).to.equal(1); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should FAIL if CloudFront origin is using http-only', function (done) { + const cache = createCache([listDistributions[0]]); + secureOrigin.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(2); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should FAIL if CloudFront origin is using SSLv3 and TLSv1 protocols', function (done) { + const cache = createCache([listDistributions[1]]); + secureOrigin.run(cache, {}, (err, results) => { + expect(results.length).to.equal(2); + expect(results[1].status).to.equal(2); + expect(results[1].region).to.equal('global'); + done(); + }); + }); + + it('should FAIL if CloudFront origin is using SSLv3 protocols', function (done) { + const cache = createCache([listDistributions[3]]); + secureOrigin.run(cache, {}, (err, results) => { + expect(results.length).to.equal(2); + expect(results[1].status).to.equal(2); + expect(results[1].region).to.equal('global'); + done(); + }); + }); + + it('should WARN if CloudFront origin is using TLSv1 protocol', function (done) { + const cache = createCache([listDistributions[2]]); + secureOrigin.run(cache, {}, (err, results) => { + expect(results.length).to.equal(2); + expect(results[1].status).to.equal(1); + expect(results[1].region).to.equal('global'); + done(); + }); + }); + + it('should PASS if no CloudFront distributions found', function (done) { + const cache = createCache([]); + secureOrigin.run(cache, {}, (err, results) => { + expect(results.length).to.equal(2); + expect(results[0].status).to.equal(0); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should UNKNOWN if unable to list distributions', function (done) { + const cache = createCache([], { message: 'Unable to list distributions' }); + secureOrigin.run(cache, {}, (err, results) => { + expect(results.length).to.equal(1); + expect(results[0].status).to.equal(3); + expect(results[0].region).to.equal('global'); + done(); + }); + }); + + it('should not return any results if list distributions response not found', function (done) { + const cache = createNullCache(); + secureOrigin.run(cache, {}, (err, results) => { + expect(results.length).to.equal(0); + done(); + }); + }); + + }); +}); \ No newline at end of file