Skip to content

Commit

Permalink
feat(AwsSolutions): Update Aws Solutions rules (#435)
Browse files Browse the repository at this point in the history
* feat(AwsSolutions): Elastic Beanstalk Checks

* feat(AwsSolutions): RDS Check

* feat(AwsSolutions, NagPack): Redshift Check and Intrinsic Function resolving function

* feat(AwsSolutions): Timestream check

* docs: reorder AwsSolutions warnings

* feat(AwsSolutions): VPC check

* feat(AwsSolutions): API Gateway checks

* feat(AwsSolutions): Kinesis Data Stream check

* feat(AwsSolutions): Cognito check

* feat(AwsSolutions): Secrets Manager

* feat(AwsSolutions): AppSync Check

* refactor(AwsSolutions): import names

* docs: service name captilization
  • Loading branch information
dontirun authored Oct 29, 2021
1 parent b4e8c5c commit adeaa03
Show file tree
Hide file tree
Showing 32 changed files with 1,555 additions and 27 deletions.
20 changes: 20 additions & 0 deletions .projen/deps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions .projenrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const project = new AwsCdkConstructLibrary({
'@aws-cdk/aws-apigatewayv2',
'@aws-cdk/aws-apigatewayv2-authorizers',
'@aws-cdk/aws-apigatewayv2-integrations',
'@aws-cdk/aws-appsync',
'@aws-cdk/aws-athena',
'@aws-cdk/aws-autoscaling',
'@aws-cdk/aws-certificatemanager',
Expand Down Expand Up @@ -67,6 +68,7 @@ const project = new AwsCdkConstructLibrary({
'@aws-cdk/aws-sqs',
'@aws-cdk/aws-stepfunctions',
'@aws-cdk/aws-s3',
'@aws-cdk/aws-timestream',
'@aws-cdk/aws-wafv2',
'@aws-cdk/core',
],
Expand Down
43 changes: 28 additions & 15 deletions RULES.md

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

145 changes: 139 additions & 6 deletions src/AwsSolutions/aws-solutions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
awsSolutionsEmr6,
awsSolutionsKda3,
awsSolutionsKds1,
awsSolutionsKds3,
awsSolutionsKdf1,
awsSolutionsMsk2,
awsSolutionsMsk6,
Expand All @@ -30,6 +31,9 @@ import {
awsSolutionsSqs3,
} from './rules/application_integration';
import {
awsSolutionsEb1,
awsSolutionsEb3,
awsSolutionsEb4,
awsSolutionsEc23,
awsSolutionsEc26,
awsSolutionsEc27,
Expand All @@ -44,7 +48,7 @@ import {
awsSolutionsElb3,
awsSolutionsElb4,
awsSolutionsElb5,
} from './rules/compute/index';
} from './rules/compute';
import {
awsSolutionsAec1,
awsSolutionsAec3,
Expand All @@ -67,19 +71,22 @@ import {
awsSolutionsRds11,
awsSolutionsRds13,
awsSolutionsRds14,
awsSolutionsRds15,
awsSolutionsRds16,
awsSolutionsRds2,
awsSolutionsRds6,
awsSolutionsRs1,
awsSolutionsRs10,
awsSolutionsRs11,
awsSolutionsRs2,
awsSolutionsRs3,
awsSolutionsRs4,
awsSolutionsRs5,
awsSolutionsRs6,
awsSolutionsRs8,
awsSolutionsRs9,
} from './rules/databases/index';
awsSolutionsTs3,
} from './rules/databases';
import {
awsSolutionsC91,
awsSolutionsCb3,
Expand All @@ -90,7 +97,7 @@ import {
awsSolutionsSm1,
awsSolutionsSm2,
awsSolutionsSm3,
} from './rules/machine_learning/index';
} from './rules/machine_learning';
import {
awsSolutionsAs1,
awsSolutionsAs2,
Expand All @@ -105,6 +112,8 @@ import {
} from './rules/media_services';
import {
awsSolutionsApig1,
awsSolutionsApig2,
awsSolutionsApig3,
awsSolutionsApig4,
awsSolutionsApig6,
awsSolutionsCfr1,
Expand All @@ -113,23 +122,30 @@ import {
awsSolutionsCfr5,
awsSolutionsCfr6,
awsSolutionsVpc3,
} from './rules/network_and_delivery/index';
awsSolutionsVpc7,
} from './rules/network_and_delivery';
import {
awsSolutionsCog1,
awsSolutionsCog2,
awsSolutionsCog3,
awsSolutionsCog4,
awsSolutionsCog7,
awsSolutionsIam4,
awsSolutionsIam5,
awsSolutionsKms5,
awsSolutionsSmg4,
} from './rules/security_and_compliance';
import { awsSolutionsSf1, awsSolutionsSf2 } from './rules/serverless';
import {
awsSolutionsAsc3,
awsSolutionsSf1,
awsSolutionsSf2,
} from './rules/serverless';
import {
awsSolutionsEfs1,
awsSolutionsS1,
awsSolutionsS2,
awsSolutionsS3,
} from './rules/storage/index';
} from './rules/storage';

/**
* Check Best practices based on AWS Solutions Security Matrix
Expand Down Expand Up @@ -159,6 +175,33 @@ export class AwsSolutionsChecks extends NagPack {
* @param ignores list of ignores for the resource
*/
private checkCompute(node: CfnResource): void {
this.applyRule({
ruleId: 'AwsSolutions-EB1',
info: 'The Elastic Beanstalk environment is not configured to use a specific VPC.',
explanation:
'Use a non-default in order to seperate your environment from default resources.',
level: NagMessageLevel.ERROR,
rule: awsSolutionsEb1,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-EB3',
info: 'The Elastic Beanstalk environment does not have managed updates enabled.',
explanation:
'Enable managed platform updates for beanstalk environments in order to receive bug fixes, software updates and new features. Managed platform updates perform immutable environment updates.',
level: NagMessageLevel.ERROR,
rule: awsSolutionsEb3,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-EB4',
info: 'The Elastic Beanstalk environment does not upload EC2 Instance logs to S3.',
explanation:
'Beanstalk environment logs should be retained and uploaded to Amazon S3 in order to keep the logging data for future audits, historical purposes or to track and analyze the EB application environment behavior for a long period of time.',
level: NagMessageLevel.WARN,
rule: awsSolutionsEb4,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-EC23',
info: 'The Security Group allows for 0.0.0.0/0 or ::/0 inbound access.',
Expand Down Expand Up @@ -390,6 +433,15 @@ export class AwsSolutionsChecks extends NagPack {
rule: awsSolutionsRds14,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-RDS15',
info: 'The RDS Aurora cluster does not have deletion protection enabled.',
explanation:
'Enabling Deletion Protection at the cluster level helps protect Amazon Aurora dtabases from accidental deletion.',
level: NagMessageLevel.ERROR,
rule: awsSolutionsRds15,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-RDS16',
info: 'The RDS Aurora MySQL serverless cluster does not have audit, error, general, and slowquery Log Exports enabled.',
Expand Down Expand Up @@ -587,6 +639,15 @@ export class AwsSolutionsChecks extends NagPack {
rule: awsSolutionsRs10,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-RS11',
info: 'The Redshift cluster does not have user activity logging enabled.',
explanation:
'User activity logging logs each query before it is performed on the clusters databse. To enable this feature associate a Resdhsift Cluster Parameter Group with the "enable_user_activity_logging" parameter set to "true".',
level: NagMessageLevel.ERROR,
rule: awsSolutionsRs11,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-DOC1',
info: 'The Document DB cluster does not have encryption at rest enabled.',
Expand Down Expand Up @@ -632,6 +693,15 @@ export class AwsSolutionsChecks extends NagPack {
rule: awsSolutionsDoc5,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-TS3',
info: 'The Timestream database does not use a Customer Managed KMS Key for at rest encryption.',
explanation:
'All Timestream tables in a database are encrypted at rest by default using AWS Managed Key. These keys are rotated every three years. Data at rest must be encrypted using CMKs if you require more control over the permissions and lifecycle of your keys, including the ability to have them automatically rotated on an annual basis.',
level: NagMessageLevel.WARN,
rule: awsSolutionsTs3,
node: node,
});
}

/**
Expand All @@ -649,6 +719,15 @@ export class AwsSolutionsChecks extends NagPack {
rule: awsSolutionsVpc3,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-VPC7',
info: 'The VPC does not have an associated Flow Log.',
explanation:
'VPC Flow Logs capture network flow information for a VPC, subnet, or network interface and stores it in Amazon CloudWatch Logs. Flow log data can help customers troubleshoot network issues; for example, to diagnose why specific traffic is not reaching an instance, which might be a result of overly restrictive security group rules.',
level: NagMessageLevel.ERROR,
rule: awsSolutionsVpc7,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-CFR1',
info: 'The CloudFront distribution may require Geo restrictions.',
Expand Down Expand Up @@ -703,6 +782,24 @@ export class AwsSolutionsChecks extends NagPack {
rule: awsSolutionsApig1,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-APIG2',
info: 'The Rest API does not have request validation enabled.',
explanation:
'The API should have basic request validation enabled. If the API is integrated with custom source (Lambda, ECS, etc..) in the backend, deeper input validation should be considered for implementation.',
level: NagMessageLevel.ERROR,
rule: awsSolutionsApig2,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-APIG3',
info: 'The Rest API stage is not associated with AWS WAFv2 web ACL.',
explanation:
'AWS WAFv2 is a web application firewall that helps protect web applications and APIs from attacks by allowing configured rules to allow, block, or monitor (count) web requests based on customizable rules and conditions that are defined.',
level: NagMessageLevel.WARN,
rule: awsSolutionsApig3,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-APIG4',
info: 'The API does not implement authorization.',
Expand Down Expand Up @@ -844,6 +941,15 @@ export class AwsSolutionsChecks extends NagPack {
rule: awsSolutionsKds1,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-KDS3',
info: 'The Kinesis Data Stream specifies server-side encryption and does not use the "aws/kinesis" key.',
explanation:
'Customer Managed Keys can incur additional costs that scale with the amount of consumers and producers. Ensure that Customer Managed Keys are required for compliance before using them (https://docs.aws.amazon.com/streams/latest/dev/costs-performance.html).',
level: NagMessageLevel.WARN,
rule: awsSolutionsKds3,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-KDF1',
info: 'The Kinesis Data Firehose delivery stream does have server-side encryption enabled.',
Expand Down Expand Up @@ -1014,6 +1120,15 @@ export class AwsSolutionsChecks extends NagPack {
rule: awsSolutionsCog3,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-COG4',
info: 'The API GW method does not use a Cognito user pool authorizer.',
explanation:
'API Gateway validates the tokens from a successful user pool authentication, and uses them to grant your users access to resources including Lambda functions, or your own API.',
level: NagMessageLevel.ERROR,
rule: awsSolutionsCog4,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-COG7',
info: 'The Cognito identity pool allows for unauthenticated logins and does not have a cdk_nag rule suppression with a reason.',
Expand All @@ -1032,6 +1147,15 @@ export class AwsSolutionsChecks extends NagPack {
rule: awsSolutionsKms5,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-SMG4',
info: 'The Secret does not have automatic rotation scheduled.',
explanation:
'AWS Secrets Manager can be configured to automatically rotate the secret for a secured service or database.',
level: NagMessageLevel.ERROR,
rule: awsSolutionsSmg4,
node: node,
});
}

/**
Expand All @@ -1040,6 +1164,15 @@ export class AwsSolutionsChecks extends NagPack {
* @param ignores list of ignores for the resource
*/
private checkServerless(node: CfnResource): void {
this.applyRule({
ruleId: 'AwsSolutions-ASC3',
info: 'The GraphQL API does not have request leveling logging enabled.',
explanation:
'It is important to use CloudWatch Logs to log metrics such as who has accessed the GraphQL API, how the caller accessed the API, and invalid requests.',
level: NagMessageLevel.ERROR,
rule: awsSolutionsAsc3,
node: node,
});
this.applyRule({
ruleId: 'AwsSolutions-SF1',
info: 'The Step Function does not log "ALL" events to CloudWatch Logs.',
Expand Down
Loading

0 comments on commit adeaa03

Please sign in to comment.