cdk-nag
Version:
Check CDK v2 applications for best practices using a combination on available rule packs.
728 lines • 121 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.NIST80053R4Checks = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
const aws_cdk_lib_1 = require("aws-cdk-lib");
const nag_pack_1 = require("../nag-pack");
const nag_rules_1 = require("../nag-rules");
const apigw_1 = require("../rules/apigw");
const autoscaling_1 = require("../rules/autoscaling");
const cloudtrail_1 = require("../rules/cloudtrail");
const cloudwatch_1 = require("../rules/cloudwatch");
const codebuild_1 = require("../rules/codebuild");
const dms_1 = require("../rules/dms");
const dynamodb_1 = require("../rules/dynamodb");
const ec2_1 = require("../rules/ec2");
const efs_1 = require("../rules/efs");
const elasticache_1 = require("../rules/elasticache");
const elb_1 = require("../rules/elb");
const emr_1 = require("../rules/emr");
const iam_1 = require("../rules/iam");
const kms_1 = require("../rules/kms");
const lambda_1 = require("../rules/lambda");
const opensearch_1 = require("../rules/opensearch");
const rds_1 = require("../rules/rds");
const redshift_1 = require("../rules/redshift");
const s3_1 = require("../rules/s3");
const sagemaker_1 = require("../rules/sagemaker");
const sns_1 = require("../rules/sns");
const vpc_1 = require("../rules/vpc");
const waf_1 = require("../rules/waf");
/**
* Check for NIST 800-53 rev 4 compliance.
* Based on the NIST 800-53 rev 4 AWS operational best practices: https://docs.aws.amazon.com/config/latest/developerguide/operational-best-practices-for-nist-800-53_rev_4.html
*/
class NIST80053R4Checks extends nag_pack_1.NagPack {
constructor(props) {
super(props);
this.packName = 'NIST.800.53.R4';
}
visit(node) {
if (node instanceof aws_cdk_lib_1.CfnResource) {
this.checkAPIGW(node);
this.checkAutoScaling(node);
this.checkCloudTrail(node);
this.checkCloudWatch(node);
this.checkCodeBuild(node);
this.checkDMS(node);
this.checkDynamoDB(node);
this.checkEC2(node);
this.checkEFS(node);
this.checkElastiCache(node);
this.checkELB(node);
this.checkEMR(node);
this.checkIAM(node);
this.checkKMS(node);
this.checkLambda(node);
this.checkOpenSearch(node);
this.checkRDS(node);
this.checkRedshift(node);
this.checkS3(node);
this.checkSageMaker(node);
this.checkSNS(node);
this.checkVPC(node);
this.checkWAF(node);
}
}
/**
* Check API Gateway Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkAPIGW(node) {
this.applyRule({
info: 'The API Gateway stage does not have caching enabled and encrypted for all methods - (Control IDs: SC-13, SC-28).',
explanation: "To help protect data at rest, ensure encryption is enabled for your API Gateway stage's cache. Because sensitive data can be captured for the API method, enable encryption at rest to help protect that data.",
level: nag_rules_1.NagMessageLevel.ERROR,
rule: apigw_1.APIGWCacheEnabledAndEncrypted,
node: node,
});
this.applyRule({
info: 'The API Gateway stage does not have execution logging enabled for all methods - (Control IDs: AU-2(a)(d), AU-3, AU-12(a)(c)).',
explanation: 'API Gateway logging displays detailed views of users who accessed the API and the way they accessed the API. This insight enables visibility of user activities.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: apigw_1.APIGWExecutionLoggingEnabled,
node: node,
});
}
/**
* Check Auto Scaling Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkAutoScaling(node) {
this.applyRule({
info: 'The Auto Scaling group utilizes a load balancer and does not have an ELB health check configured - (Control IDs: SC-5).',
explanation: 'The Elastic Load Balancer (ELB) health checks for Amazon Elastic Compute Cloud (Amazon EC2) Auto Scaling groups support maintenance of adequate capacity and availability.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: autoscaling_1.AutoScalingGroupELBHealthCheckRequired,
node: node,
});
}
/**
* Check CloudTrail Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkCloudTrail(node) {
this.applyRule({
info: 'The trail does not have CloudWatch logs enabled - (Control IDs: AC-2(4), AC-2(g), AU-2(a)(d), AU-3, AU-6(1)(3), AU-7(1), AU-12(a)(c), CA-7(a)(b), SI-4(2), SI-4(4), SI-4(5), SI-4(a)(b)(c)).',
explanation: 'Use Amazon CloudWatch to centrally collect and manage log event activity. Inclusion of AWS CloudTrail data provides details of API call activity within your AWS account.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: cloudtrail_1.CloudTrailCloudWatchLogsEnabled,
node: node,
});
this.applyRule({
info: 'The trail does not have a KMS key ID or have encryption enabled - (Control ID: AU-9).',
explanation: 'Because sensitive data may exist and to help protect data at rest, ensure encryption is enabled for your AWS CloudTrail trails.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: cloudtrail_1.CloudTrailEncryptionEnabled,
node: node,
});
this.applyRule({
info: 'The trail does not have log file validation enabled - (Control ID: AC-6).',
explanation: 'Utilize AWS CloudTrail log file validation to check the integrity of CloudTrail logs. Log file validation helps determine if a log file was modified or deleted or unchanged after CloudTrail delivered it. This feature is built using industry standard algorithms: SHA-256 for hashing and SHA-256 with RSA for digital signing. This makes it computationally infeasible to modify, delete or forge CloudTrail log files without detection.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: cloudtrail_1.CloudTrailLogFileValidationEnabled,
node: node,
});
}
/**
* Check CloudWatch Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkCloudWatch(node) {
this.applyRule({
info: 'The CloudWatch alarm does not have at least one alarm action, one INSUFFICIENT_DATA action, or one OK action enabled - (Control IDs: AC-2(4), AU-6(1)(3), AU-7(1), CA-7(a)(b), IR-4(1), SI-4(2), SI-4(4), SI-4(5), SI-4(a)(b)(c)).',
explanation: 'Amazon CloudWatch alarms alert when a metric breaches the threshold for a specified number of evaluation periods. The alarm performs one or more actions based on the value of the metric or expression relative to a threshold over a number of time periods.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: cloudwatch_1.CloudWatchAlarmAction,
node: node,
});
this.applyRule({
info: 'The CloudWatch Log Group is not encrypted with an AWS KMS key - (Control IDs: AU-9, SC-13, SC-28).',
explanation: 'To help protect sensitive data at rest, ensure encryption is enabled for your Amazon CloudWatch Log Groups.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: cloudwatch_1.CloudWatchLogGroupEncrypted,
node: node,
});
this.applyRule({
info: 'The CloudWatch Log Group does not have an explicit retention period configured - (Control IDs: AU-11, SI-12).',
explanation: 'Ensure a minimum duration of event log data is retained for your log groups to help with troubleshooting and forensics investigations. The lack of available past event log data makes it difficult to reconstruct and identify potentially malicious events.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: cloudwatch_1.CloudWatchLogGroupRetentionPeriod,
node: node,
});
}
/**
* Check CodeBuild Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkCodeBuild(node) {
this.applyRule({
info: 'The CodeBuild environment stores sensitive credentials (such as AWS_ACCESS_KEY_ID and/or AWS_SECRET_ACCESS_KEY) as plaintext environment variables - (Control IDs: AC-6, IA-5(7), SA-3(a)).',
explanation: 'Do not store these variables in clear text. Storing these variables in clear text leads to unintended data exposure and unauthorized access.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: codebuild_1.CodeBuildProjectEnvVarAwsCred,
node: node,
});
this.applyRule({
info: 'The CodeBuild project which utilizes either a GitHub or BitBucket source repository does not utilize OAuth - (Control ID: SA-3(a)).',
explanation: 'OAuth is the most secure method of authenticating your CodeBuild application. Use OAuth instead of personal access tokens or a user name and password to grant authorization for accessing GitHub or Bitbucket repositories.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: codebuild_1.CodeBuildProjectSourceRepoUrl,
node: node,
});
}
/**
* Check DMS Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkDMS(node) {
this.applyRule({
info: 'The DMS replication instance is public - (Control IDs: AC-3).',
explanation: 'DMS replication instances can contain sensitive information and access control is required for such accounts.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: dms_1.DMSReplicationNotPublic,
node: node,
});
}
/**
* Check DynamoDB Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkDynamoDB(node) {
this.applyRule({
info: "The provisioned capacity DynamoDB table does not have Auto Scaling enabled on it's indexes - (Control IDs: CP-10, SC-5).",
explanation: 'Amazon DynamoDB auto scaling uses the AWS Application Auto Scaling service to adjust provisioned throughput capacity that automatically responds to actual traffic patterns. This enables a table or a global secondary index to increase its provisioned read/write capacity to handle sudden increases in traffic, without throttling.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: dynamodb_1.DynamoDBAutoScalingEnabled,
node: node,
});
this.applyRule({
info: 'The DynamoDB table is not in an AWS Backup plan - (Control IDs: CP-9(b), CP-10, SI-12).',
explanation: 'To help with data back-up processes, ensure your Amazon DynamoDB tables are a part of an AWS Backup plan. AWS Backup is a fully managed backup service with a policy-based backup solution. This solution simplifies your backup management and enables you to meet your business and regulatory backup compliance requirements.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: dynamodb_1.DynamoDBInBackupPlan,
node: node,
});
this.applyRule({
info: 'The DynamoDB table does not have Point-in-time Recovery enabled - (Control IDs: CP-9(b), CP-10, SI-12).',
explanation: 'The recovery maintains continuous backups of your table for the last 35 days.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: dynamodb_1.DynamoDBPITREnabled,
node: node,
});
}
/**
* Check EC2 Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkEC2(node) {
this.applyRule({
info: 'The EBS volume is not in an AWS Backup plan - (Control IDs: CP-9(b), CP-10, SI-12).',
explanation: 'To help with data back-up processes, ensure your Amazon Elastic Block Store (Amazon EBS) volumes are a part of an AWS Backup plan. AWS Backup is a fully managed backup service with a policy-based backup solution. This solution simplifies your backup management and enables you to meet your business and regulatory backup compliance requirements.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: ec2_1.EC2EBSInBackupPlan,
node: node,
});
this.applyRule({
info: 'The EC2 instance does not have IMDSV2 (Instance Metadata Service Version 2) enabled - (Control ID: AC-6).',
explanation: 'Instance Metadata Service Version 2 (IMDSv2) helps protect access and control of Amazon Elastic Compute Cloud (Amazon EC2) instance metadata. The IMDSv2 method uses session-based controls. With IMDSv2, controls can be implemented to restrict changes to instance metadata.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: ec2_1.EC2IMDSv2Enabled,
node: node,
});
this.applyRule({
info: 'The EC2 instance does not have detailed monitoring enabled - (Control IDs: CA-7(a)(b), SI-4(2), SI-4(a)(b)(c)).',
explanation: 'Detailed monitoring provides additional monitoring information (such as 1-minute period graphs) on the AWS console.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: ec2_1.EC2InstanceDetailedMonitoringEnabled,
node: node,
});
this.applyRule({
info: 'The EC2 instance is not within a VPC - (Control IDs: AC-4, SC-7, SC-7(3)).',
explanation: 'Because of their logical isolation, domains that reside within an Amazon VPC have an extra layer of security when compared to domains that use public endpoints.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: ec2_1.EC2InstancesInVPC,
node: node,
});
this.applyRule({
info: 'The EC2 instance is associated with a public IP address - (Control IDs: AC-4, AC-6, AC-21(b), SC-7, SC-7(3)). ',
explanation: 'Amazon EC2 instances can contain sensitive information and access control is required for such resources.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: ec2_1.EC2InstanceNoPublicIp,
node: node,
});
this.applyRule({
info: 'The EC2 instance allows unrestricted inbound IPv4 TCP traffic on common ports (20, 21, 3389, 3306, 4333) - (Control IDs: AC-4, CM-2, SC-7, SC-7(3)).',
explanation: 'Not restricting access to ports to trusted sources can lead to attacks against the availability, integrity and confidentiality of systems. By default, common ports which should be restricted include port numbers 20, 21, 3389, 3306, and 4333.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: ec2_1.EC2RestrictedCommonPorts,
node: node,
});
this.applyRule({
info: 'The Security Group allows unrestricted SSH access - (Control IDs: AC-4, SC-7, SC-7(3)).',
explanation: 'Not allowing ingress (or remote) traffic from 0.0.0.0/0 or ::/0 to port 22 on your resources helps to restrict remote access.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: ec2_1.EC2RestrictedSSH,
node: node,
});
}
/**
* Check EFS Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkEFS(node) {
this.applyRule({
info: 'The EFS is not in an AWS Backup plan - (Control IDs: CP-9(b), CP-10, SI-12).',
explanation: 'To help with data back-up processes, ensure your Amazon Elastic File System (Amazon EFS) file systems are a part of an AWS Backup plan. AWS Backup is a fully managed backup service with a policy-based backup solution. This solution simplifies your backup management and enables you to meet your business and regulatory backup compliance requirements.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: efs_1.EFSInBackupPlan,
node: node,
});
this.applyRule({
info: 'The EFS does not have encryption at rest enabled - (Control IDs: SC-13, SC-28).',
explanation: 'Because sensitive data can exist and to help protect data at rest, ensure encryption is enabled for your Amazon Elastic File System (EFS).',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: efs_1.EFSEncrypted,
node: node,
});
}
/**
* Check ElastiCache Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkElastiCache(node) {
this.applyRule({
info: 'The ElastiCache Redis cluster does not retain automatic backups for at least 15 days - (Control IDs: CP-9(b), CP-10, SI-12).',
explanation: 'Automatic backups can help guard against data loss. If a failure occurs, you can create a new cluster, which restores your data from the most recent backup.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: elasticache_1.ElastiCacheRedisClusterAutomaticBackup,
node: node,
});
}
/**
* Check Elastic Load Balancer Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkELB(node) {
this.applyRule({
info: 'The ALB does not have invalid HTTP header dropping enabled - (Control ID: AC-17(2)).',
explanation: 'Ensure that your Application Load Balancers (ALB) are configured to drop http headers. Because sensitive data can exist, enable encryption in transit to help protect that data.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: elb_1.ALBHttpDropInvalidHeaderEnabled,
node: node,
});
this.applyRule({
info: "The ALB's HTTP listeners are not configured to redirect to HTTPS - (Control IDs: AC-17(2), SC-7, SC-8, SC-8(1), SC-13, SC-23).",
explanation: 'To help protect data in transit, ensure that your Application Load Balancer automatically redirects unencrypted HTTP requests to HTTPS. Because sensitive data can exist, enable encryption in transit to help protect that data.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: elb_1.ALBHttpToHttpsRedirection,
node: node,
});
this.applyRule({
info: 'The ALB is not associated with AWS WAFv2 web ACL - (Control IDs: SC-7, SI-4(a)(b)(c)).',
explanation: 'A WAF helps to protect your web applications or APIs against common web exploits. These web exploits may affect availability, compromise security, or consume excessive resources within your environment.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: elb_1.ALBWAFEnabled,
node: node,
});
this.applyRule({
info: 'The CLB does not utilize an SSL certificate provided by ACM (Amazon Certificate Manager) - (Control IDs: AC-17(2), SC-7, SC-8, SC-8(1), SC-13).',
explanation: 'Because sensitive data can exist and to help protect data at transit, ensure encryption is enabled for your Elastic Load Balancing. Use AWS Certificate Manager to manage, provision and deploy public and private SSL/TLS certificates with AWS services and internal resources.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: elb_1.ELBACMCertificateRequired,
node: node,
});
this.applyRule({
info: 'The CLB does not balance traffic between at least 2 Availability Zones - (Control IDs: SC-5, CP-10).',
explanation: 'The cross-zone load balancing reduces the need to maintain equivalent numbers of instances in each enabled availability zone.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: elb_1.ELBCrossZoneLoadBalancingEnabled,
node: node,
});
this.applyRule({
info: 'The ALB, NLB, or GLB does not have deletion protection enabled - (Control IDs: CM-2, CP-10).',
explanation: 'Use this feature to prevent your load balancer from being accidentally or maliciously deleted, which can lead to loss of availability for your applications.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: elb_1.ELBDeletionProtectionEnabled,
node: node,
});
this.applyRule({
info: 'The ELB does not have logging enabled - (Control ID: AU-2(a)(d)).',
explanation: "Elastic Load Balancing activity is a central point of communication within an environment. Ensure ELB logging is enabled. The collected data provides detailed information about requests sent to The ELB. Each log contains information such as the time the request was received, the client's IP address, latencies, request paths, and server responses.",
level: nag_rules_1.NagMessageLevel.ERROR,
rule: elb_1.ELBLoggingEnabled,
node: node,
});
this.applyRule({
info: 'The CLB does not restrict its listeners to only the SSL and HTTPS protocols - (Control IDs: AC-17(2), SC-7, SC-8, SC-8(1), SC-23).',
explanation: 'Because sensitive data can exist, enable encryption in transit to help protect that data.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: elb_1.ELBTlsHttpsListenersOnly,
node: node,
});
}
/**
* Check EMR Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkEMR(node) {
this.applyRule({
info: 'The EMR cluster does not have Kerberos enabled - (Control IDs: AC-2(j), AC-3, AC-5c, AC-6).',
explanation: 'The access permissions and authorizations can be managed and incorporated with the principles of least privilege and separation of duties, by enabling Kerberos for Amazon EMR clusters.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: emr_1.EMRKerberosEnabled,
node: node,
});
}
/**
* Check IAM Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkIAM(node) {
this.applyRule({
info: 'The IAM Group does not have at least one IAM User - (Control ID: AC-2(j)).',
explanation: 'AWS Identity and Access Management (IAM) can help you incorporate the principles of least privilege and separation of duties with access permissions and authorizations, by ensuring that IAM groups have at least one IAM user. Placing IAM users in groups based on their associated permissions or job function is one way to incorporate least privilege.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: iam_1.IAMGroupHasUsers,
node: node,
});
this.applyRule({
info: 'The IAM Group, User, or Role contains an inline policy - (Control ID: AC-6).',
explanation: 'AWS recommends to use managed policies instead of inline policies. The managed policies allow reusability, versioning and rolling back, and delegating permissions management.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: iam_1.IAMNoInlinePolicy,
node: node,
});
this.applyRule({
info: 'The IAM policy grants admin access, meaning the policy allows a principal to perform all actions on all resources - (Control IDs: AC-2(1), AC-2(j), AC-3, AC-6).',
explanation: 'AWS Identity and Access Management (IAM) can help you incorporate the principles of least privilege and separation of duties with access permissions and authorizations, restricting policies from containing "Effect": "Allow" with "Action": "*" over "Resource": "*". Allowing users to have more privileges than needed to complete a task may violate the principle of least privilege and separation of duties.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: iam_1.IAMPolicyNoStatementsWithAdminAccess,
node: node,
});
this.applyRule({
info: 'The IAM user does not belong to any group(s) - (Control IDs: AC-2(1), AC-2(j), AC-3, AC-6).',
explanation: 'AWS Identity and Access Management (IAM) can help you restrict access permissions and authorizations, by ensuring IAM users are members of at least one group. Allowing users more privileges than needed to complete a task may violate the principle of least privilege and separation of duties.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: iam_1.IAMUserGroupMembership,
node: node,
});
this.applyRule({
info: 'The IAM policy is attached at the user level - (Control IDs: AC-2(j), AC-3, AC-5c, AC-6).',
explanation: 'Assigning privileges at the group or the role level helps to reduce opportunity for an identity to receive or retain excessive privileges.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: iam_1.IAMUserNoPolicies,
node: node,
});
}
/**
* Check KMS Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkKMS(node) {
this.applyRule({
info: 'The KMS Symmetric key does not have automatic key rotation enabled - (Control ID: SC-12).',
explanation: 'Enable key rotation to ensure that keys are rotated once they have reached the end of their crypto period.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: kms_1.KMSBackingKeyRotationEnabled,
node: node,
});
}
/**
* Check Lambda Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkLambda(node) {
this.applyRule({
info: 'The Lambda function is not VPC enabled - (Control IDs: AC-4, SC-7, SC-7(3)).',
explanation: 'Because of their logical isolation, domains that reside within an Amazon VPC have an extra layer of security when compared to domains that use public endpoints.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: lambda_1.LambdaInsideVPC,
node: node,
});
this.applyRule({
info: 'The Lambda function permission grants public access - (Control IDs: AC-3, AC-4, AC-6, AC-21(b), SC-7, SC-7(3)).',
explanation: 'Public access allows anyone on the internet to perform unauthenticated actions on your function and can potentially lead to degraded availability.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: lambda_1.LambdaFunctionPublicAccessProhibited,
node: node,
});
}
/**
* Check OpenSearch Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkOpenSearch(node) {
this.applyRule({
info: 'The OpenSearch Service domain does not have encryption at rest enabled - (Control IDs: SC-13, SC-28).',
explanation: 'Because sensitive data can exist and to help protect data at rest, ensure encryption is enabled for your Amazon OpenSearch Service (OpenSearch Service) domains.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: opensearch_1.OpenSearchEncryptedAtRest,
node: node,
});
this.applyRule({
info: 'The OpenSearch Service domain is not running within a VPC - (Control IDs: AC-4, SC-7, SC-7(3)).',
explanation: 'VPCs help secure your AWS resources and provide an extra layer of protection.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: opensearch_1.OpenSearchInVPCOnly,
node: node,
});
this.applyRule({
info: 'The OpenSearch Service domain does not have node-to-node encryption enabled - (Control IDs: SC-7, SC-8, SC-8(1)).',
explanation: 'Because sensitive data can exist, enable encryption in transit to help protect that data within your Amazon OpenSearch Service (OpenSearch Service) domains.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: opensearch_1.OpenSearchNodeToNodeEncryption,
node: node,
});
}
/**
* Check Amazon RDS Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkRDS(node) {
this.applyRule({
info: 'The RDS DB instance does not have enhanced monitoring enabled - (Control ID: CA-7(a)(b)).',
explanation: 'Enable enhanced monitoring to help monitor Amazon RDS availability. This provides detailed visibility into the health of your Amazon RDS database instances.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: rds_1.RDSEnhancedMonitoringEnabled,
node: node,
});
this.applyRule({
info: 'The RDS DB instance is not in an AWS Backup plan - (Control IDs: CP-9(b), CP-10, SI-12).',
explanation: 'To help with data back-up processes, ensure your Amazon Relational Database Service (Amazon RDS) instances are a part of an AWS Backup plan. AWS Backup is a fully managed backup service with a policy-based backup solution. This solution simplifies your backup management and enables you to meet your business and regulatory backup compliance requirements.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: rds_1.RDSInBackupPlan,
node: node,
});
this.applyRule({
info: 'The RDS DB instance does not have backups enabled - (Control IDs: CP-9(b), CP-10, SI-12).',
explanation: 'The backup feature of Amazon RDS creates backups of your databases and transaction logs.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: rds_1.RDSInstanceBackupEnabled,
node: node,
});
this.applyRule({
info: 'The RDS DB instance or Aurora DB cluster does not have deletion protection enabled - (Control ID: SC-5).',
explanation: 'Ensure Amazon Relational Database Service (Amazon RDS) instances and clusters have deletion protection enabled. Use deletion protection to prevent your Amazon RDS DB instances and clusters from being accidentally or maliciously deleted, which can lead to loss of availability for your applications.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: rds_1.RDSInstanceDeletionProtectionEnabled,
node: node,
});
this.applyRule({
info: 'The RDS DB instance allows public access - (Control IDs: AC-4, AC-6, AC-21(b), SC-7, SC-7(3)).',
explanation: 'Amazon RDS database instances can contain sensitive information, and principles and access control is required for such accounts.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: rds_1.RDSInstancePublicAccess,
node: node,
});
this.applyRule({
info: 'The non-Aurora RDS DB instance or Aurora cluster does not have all CloudWatch log types exported - (Control IDs: AC-2(4), AC-2(g), AU-2(a)(d), AU-3, AU-12(a)(c)).',
explanation: 'To help with logging and monitoring within your environment, ensure Amazon Relational Database Service (Amazon RDS) logging is enabled. With Amazon RDS logging, you can capture events such as connections, disconnections, queries, or tables queried.' +
"This is a granular rule that returns individual findings that can be suppressed with 'appliesTo'. The findings are in the format 'LogExport::<log>' for exported logs. Example: appliesTo: ['LogExport::audit'].",
level: nag_rules_1.NagMessageLevel.ERROR,
rule: rds_1.RDSLoggingEnabled,
node: node,
});
this.applyRule({
info: 'The non-Aurora RDS DB instance does not have multi-AZ support enabled - (Control IDs: CP-10, SC-5, SC-36).',
explanation: 'Multi-AZ support in Amazon Relational Database Service (Amazon RDS) provides enhanced availability and durability for database instances. When you provision a Multi-AZ database instance, Amazon RDS automatically creates a primary database instance, and synchronously replicates the data to a standby instance in a different Availability Zone. In case of an infrastructure failure, Amazon RDS performs an automatic failover to the standby so that you can resume database operations as soon as the failover is complete.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: rds_1.RDSMultiAZSupport,
node: node,
});
this.applyRule({
info: 'The RDS DB instance or Aurora DB cluster does not have storage encrypted - (Control IDs: SC-13, SC-28).',
explanation: 'Because sensitive data can exist at rest in Amazon RDS DB instances and clusters, enable encryption at rest to help protect that data.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: rds_1.RDSStorageEncrypted,
node: node,
});
}
/**
* Check Redshift Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkRedshift(node) {
this.applyRule({
info: 'The Redshift cluster does not have encryption or audit logging enabled - (Control IDs: AC-2(4), AC-2(g), AU-2(a)(d), AU-3, AU-12(a)(c), SC-13).',
explanation: 'To protect data at rest, ensure that encryption is enabled for your Amazon Redshift clusters. You must also ensure that required configurations are deployed on Amazon Redshift clusters. The audit logging should be enabled to provide information about connections and user activities in the database.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: redshift_1.RedshiftClusterConfiguration,
node: node,
});
this.applyRule({
info: 'The Redshift cluster allows public access - (Control IDs: AC-3, AC-4, AC-6, AC-21(b), SC-7, SC-7(3)).',
explanation: 'Amazon Redshift clusters can contain sensitive information and principles and access control is required for such accounts.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: redshift_1.RedshiftClusterPublicAccess,
node: node,
});
this.applyRule({
info: 'The Redshift cluster does not require TLS/SSL encryption - (Control IDs: AC-17(2), SC-7, SC-8, SC-8(1), SC-13).',
explanation: 'Ensure that your Amazon Redshift clusters require TLS/SSL encryption to connect to SQL clients. Because sensitive data can exist, enable encryption in transit to help protect that data.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: redshift_1.RedshiftRequireTlsSSL,
node: node,
});
}
/**
* Check Amazon S3 Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkS3(node) {
this.applyRule({
info: 'The S3 Bucket does not have object lock enabled - (Control ID: SC-28).',
explanation: 'Because sensitive data can exist at rest in S3 buckets, enforce object locks at rest to help protect that data.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: s3_1.S3BucketDefaultLockEnabled,
node: node,
});
this.applyRule({
info: 'The S3 Bucket does not have server access logs enabled - (Control IDs: AC-2(g), AU-2(a)(d), AU-3, AU-12(a)(c)).',
explanation: 'Amazon Simple Storage Service (Amazon S3) server access logging provides a method to monitor the network for potential cybersecurity events. The events are monitored by capturing detailed records for the requests that are made to an Amazon S3 bucket. Each access log record provides details about a single access request. The details include the requester, bucket name, request time, request action, response status, and an error code, if relevant.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: s3_1.S3BucketLoggingEnabled,
node: node,
});
this.applyRule({
info: 'The S3 Bucket does not prohibit public read access through its Block Public Access configurations and bucket ACLs - (Control IDs: AC-3, AC-4, AC-6, AC-21(b), SC-7, SC-7(3)).',
explanation: 'The management of access should be consistent with the classification of the data.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: s3_1.S3BucketPublicReadProhibited,
node: node,
});
this.applyRule({
info: 'The S3 Bucket does not prohibit public write access through its Block Public Access configurations and bucket ACLs - (Control IDs: AC-3, AC-4, AC-6, AC-21(b), SC-7, SC-7(3)).',
explanation: 'The management of access should be consistent with the classification of the data.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: s3_1.S3BucketPublicWriteProhibited,
node: node,
});
this.applyRule({
info: 'The S3 Bucket does not have replication enabled - (Control IDs: AU-9(2), CP-9(b), CP-10, SC-5, SC-36).',
explanation: 'Amazon Simple Storage Service (Amazon S3) Cross-Region Replication (CRR) supports maintaining adequate capacity and availability. CRR enables automatic, asynchronous copying of objects across Amazon S3 buckets to help ensure that data availability is maintained.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: s3_1.S3BucketReplicationEnabled,
node: node,
});
this.applyRule({
info: 'The S3 Bucket or bucket policy does not require requests to use SSL - (Control IDs: AC-17(2), SC-7, SC-8, SC-8(1), SC-13).',
explanation: 'To help protect data in transit, ensure that your Amazon Simple Storage Service (Amazon S3) buckets require requests to use Secure Socket Layer (SSL). Because sensitive data can exist, enable encryption in transit to help protect that data.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: s3_1.S3BucketSSLRequestsOnly,
node: node,
});
this.applyRule({
info: 'The S3 Bucket does not have versioning enabled - (Control IDs: CP-10, SI-12).',
explanation: 'Use versioning to preserve, retrieve, and restore every version of every object stored in your Amazon S3 bucket. Versioning helps you to easily recover from unintended user actions and application failures.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: s3_1.S3BucketVersioningEnabled,
node: node,
});
}
/**
* Check SageMaker Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkSageMaker(node) {
this.applyRule({
info: 'The SageMaker endpoint is not encrypted with a KMS key - (Control IDs: SC-13, SC-28).',
explanation: 'Because sensitive data can exist at rest in SageMaker endpoint, enable encryption at rest to help protect that data.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: sagemaker_1.SageMakerEndpointConfigurationKMSKeyConfigured,
node: node,
});
this.applyRule({
info: 'The SageMaker notebook is not encrypted with a KMS key - (Control IDs: SC-13, SC-28).',
explanation: 'Because sensitive data can exist at rest in SageMaker notebook, enable encryption at rest to help protect that data.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: sagemaker_1.SageMakerNotebookInstanceKMSKeyConfigured,
node: node,
});
this.applyRule({
info: 'The SageMaker notebook does not disable direct internet access - (Control IDs: AC-3, AC-4, AC-6, AC-21(b), SC-7, SC-7(3)).',
explanation: 'By preventing direct internet access, you can keep sensitive data from being accessed by unauthorized users.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: sagemaker_1.SageMakerNotebookNoDirectInternetAccess,
node: node,
});
}
/**
* Check Amazon SNS Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkSNS(node) {
this.applyRule({
info: 'The SNS topic does not have KMS encryption enabled - (Control IDs: SC-13, SC-28).',
explanation: 'Because sensitive data can exist at rest in published messages, enable encryption at rest to help protect that data.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: sns_1.SNSEncryptedKMS,
node: node,
});
}
/**
* Check VPC Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkVPC(node) {
this.applyRule({
info: "The VPC's default security group allows inbound or outbound traffic - (Control IDs: AC-4, SC-7, SC-7(3)).",
explanation: 'When creating a VPC through CloudFormation, the default security group will always be open. Therefore it is important to always close the default security group after stack creation whenever a VPC is created. Restricting all the traffic on the default security group helps in restricting remote access to your AWS resources.',
level: nag_rules_1.NagMessageLevel.WARN,
rule: vpc_1.VPCDefaultSecurityGroupClosed,
node: node,
});
this.applyRule({
info: 'The VPC does not have an associated Flow Log - (Control IDs: AU-2(a)(d), AU-3, AU-12(a)(c)).',
explanation: 'The VPC flow logs provide detailed records for information about the IP traffic going to and from network interfaces in your Amazon Virtual Private Cloud (Amazon VPC). By default, the flow log record includes values for the different components of the IP flow, including the source, destination, and protocol.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: vpc_1.VPCFlowLogsEnabled,
node: node,
});
}
/**
* Check WAF Resources
* @param node the CfnResource to check
* @param ignores list of ignores for the resource
*/
checkWAF(node) {
this.applyRule({
info: 'The WAFv2 web ACL does not have logging enabled - (Control IDs: AU-2(a)(d), AU-3, AU-12(a)(c), SC-7, SI-4(a)(b)(c)).',
explanation: 'AWS WAF logging provides detailed information about the traffic that is analyzed by your web ACL. The logs record the time that AWS WAF received the request from your AWS resource, information about the request, and an action for the rule that each request matched.',
level: nag_rules_1.NagMessageLevel.ERROR,
rule: waf_1.WAFv2LoggingEnabled,
node: node,
});
}
}
exports.NIST80053R4Checks = NIST80053R4Checks;
_a = JSII_RTTI_SYMBOL_1;
NIST80053R4Checks[_a] = { fqn: "cdk-nag.NIST80053R4Checks", version: "2.36.41" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmlzdC04MDAtNTMtcjQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGFja3MvbmlzdC04MDAtNTMtcjQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQTs7O0VBR0U7QUFFRiw2Q0FBMEM7QUFFMUMsMENBQW9EO0FBQ3BELDRDQUErQztBQUMvQywwQ0FHd0I7QUFDeEIsc0RBQThFO0FBQzlFLG9EQUk2QjtBQUM3QixvREFJNkI7QUFDN0Isa0RBRzRCO0FBQzVCLHNDQUF1RDtBQUN2RCxnREFJMkI7QUFDM0Isc0NBUXNCO0FBQ3RCLHNDQUE2RDtBQUM3RCxzREFBOEU7QUFDOUUsc0NBU3NCO0FBQ3RCLHNDQUFrRDtBQUNsRCxzQ0FNc0I7QUFDdEIsc0NBQTREO0FBQzVELDRDQUd5QjtBQUN6QixvREFJNkI7QUFDN0Isc0NBU3NCO0FBQ3RCLGdEQUkyQjtBQUMzQixvQ0FRcUI7QUFDckIsa0RBSTRCO0FBQzVCLHNDQUErQztBQUMvQyxzQ0FHc0I7QUFDdEIsc0NBQW1EO0FBRW5EOzs7R0FHRztBQUNILE1BQWEsaUJBQWtCLFNBQVEsa0JBQU87SUFDNUMsWUFBWSxLQUFvQjtRQUM5QixLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDYixJQUFJLENBQUMsUUFBUSxHQUFHLGdCQUFnQixDQUFDO0lBQ25DLENBQUM7SUFFTSxLQUFLLENBQUMsSUFBZ0I7UUFDM0IsSUFBSSxJQUFJLFlBQVkseUJBQVcsRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdEIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzVCLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDM0IsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMzQixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzFCLElBQUksQ0FBQyxR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