UNPKG

cdk-nag

Version:

Check CDK v2 applications for best practices using a combination on available rule packs.

721 lines 125 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.PCIDSS321Checks = 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 ec2_1 = require("../rules/ec2"); const ecs_1 = require("../rules/ecs"); const efs_1 = require("../rules/efs"); 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 secretsmanager_1 = require("../rules/secretsmanager"); const sns_1 = require("../rules/sns"); const vpc_1 = require("../rules/vpc"); const waf_1 = require("../rules/waf"); /** * Check for PCI DSS 3.2.1 compliance. * Based on the PCI DSS 3.2.1 AWS operational best practices: https://docs.aws.amazon.com/config/latest/developerguide/operational-best-practices-for-pci-dss.html */ class PCIDSS321Checks extends nag_pack_1.NagPack { constructor(props) { super(props); this.packName = 'PCI.DSS.321'; } 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.checkEC2(node); this.checkECS(node); this.checkEFS(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.checkSecretsManager(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 REST API stage is not associated with AWS WAFv2 web ACL - (Control ID: 6.6).', explanation: 'AWS WAF enables you to configure a set of rules (called a web access control list (web ACL)) that allow, block, or count web requests based on customizable web security rules and conditions that you define. Ensure your Amazon API Gateway stage is associated with a WAF Web ACL to protect it from malicious attacks.', level: nag_rules_1.NagMessageLevel.ERROR, rule: apigw_1.APIGWAssociatedWithWAF, node: node, }); this.applyRule({ info: 'The API Gateway stage does not have caching enabled and encrypted for all methods - (Control ID: 3.4).', 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: 10.1, 10.3.1, 10.3.2, 10.3.3, 10.3.4, 10.3.5, 10.3.6, 10.5.4).', 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, }); this.applyRule({ info: 'The API Gateway REST API stage is not configured with SSL certificates - (Control IDs: 2.3, 4.1, 8.2.1).', explanation: 'Ensure Amazon API Gateway REST API stages are configured with SSL certificates to allow backend systems to authenticate that requests originate from API Gateway.', level: nag_rules_1.NagMessageLevel.ERROR, rule: apigw_1.APIGWSSLEnabled, 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 (which is associated with a load balancer) does not utilize ELB health checks - (Control ID: 2.2).', 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. The load balancer periodically sends pings, attempts connections, or sends requests to test Amazon EC2 instances health in an auto-scaling group. If an instance is not reporting back, traffic is sent to a new Amazon EC2 instance.', level: nag_rules_1.NagMessageLevel.ERROR, rule: autoscaling_1.AutoScalingGroupELBHealthCheckRequired, node: node, }); this.applyRule({ info: 'The Auto Scaling launch configuration does not have public IP addresses disabled - (Control IDs: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 1.3.4, 1.3.6, 2.2.2).', explanation: 'If you configure your Network Interfaces with a public IP address, then the associated resources to those Network Interfaces are reachable from the internet. EC2 resources should not be publicly accessible, as this may allow unintended access to your applications or servers.', level: nag_rules_1.NagMessageLevel.ERROR, rule: autoscaling_1.AutoScalingLaunchConfigPublicIpDisabled, 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: 2.2, 10.1, 10.2.1, 10.2.2, 10.2.3, 10.2.5, 10.3.1, 10.3.2, 10.3.3, 10.3.4, 10.3.5, 10.3.6, 10.5.3, 10.5.4).', 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 encryption enabled - (Control IDs: 2.2, 3.4, 10.5).', 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 IDs: 2.2, 10.5.2, 10.5, 10.5.5, 11.5).', 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 Log Group is not encrypted with an AWS KMS key - (Control ID: 3.4).', 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: 3.1, 10.7).', 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 ID: 8.2.1).', 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: 8.2.1).', 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: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 1.3.4, 1.3.6, 2.2.2).', 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 EC2 Resources * @param node the CfnResource to check * @param ignores list of ignores for the resource */ checkEC2(node) { this.applyRule({ info: 'The EC2 instance is associated with a public IP address - (Control IDs: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 1.3.4, 1.3.6, 2.2.2).', explanation: 'Manage access to the AWS Cloud by ensuring Amazon Elastic Compute Cloud (Amazon EC2) instances cannot be publicly accessed. Amazon EC2 instances can contain sensitive information and access control is required for such accounts.', level: nag_rules_1.NagMessageLevel.ERROR, rule: ec2_1.EC2InstanceNoPublicIp, node: node, }); this.applyRule({ info: 'The EC2 instance does not have an instance profile attached - (Control IDs: 2.2, 7.1.1, 7.2.1).', explanation: 'EC2 instance profiles pass an IAM role to an EC2 instance. Attaching an instance profile to your instances can assist with least privilege and permissions management.', level: nag_rules_1.NagMessageLevel.ERROR, rule: ec2_1.EC2InstanceProfileAttached, node: node, }); this.applyRule({ info: 'The EC2 instance is not within a VPC - (Control IDs: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 1.3.4, 1.3.6, 2.2.2).', explanation: 'Deploy Amazon Elastic Compute Cloud (Amazon EC2) instances within an Amazon Virtual Private Cloud (Amazon VPC) to enable secure communication between an instance and other services within the amazon VPC, without requiring an internet gateway, NAT device, or VPN connection. All traffic remains securely within the AWS Cloud. Because of their logical isolation, domains that reside within anAmazon VPC have an extra layer of security when compared to domains that use public endpoints. Assign Amazon EC2 instances to an Amazon VPC to properly manage access.', level: nag_rules_1.NagMessageLevel.ERROR, rule: ec2_1.EC2InstancesInVPC, node: node, }); this.applyRule({ info: 'The EC2 instance allows unrestricted inbound IPv4 TCP traffic on one or more common ports (by default these ports include 20, 21, 3389, 3309, 3306, 4333) - (Control IDs: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 2.2, 2.2.2).', 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: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 2.2, 2.2.2).', 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 ECS Resources * @param node the CfnResource to check * @param ignores list of ignores for the resource */ checkECS(node) { this.applyRule({ info: "The ECS task definition is configured for host networking and has at least one container with definitions with 'privileged' set to false or empty or 'user' set to root or empty - (Control ID: 7.2.1).", explanation: 'If a task definition has elevated privileges it is because you have specifically opted-in to those configurations. This rule checks for unexpected privilege escalation when a task definition has host networking enabled but the customer has not opted-in to elevated privileges.', level: nag_rules_1.NagMessageLevel.ERROR, rule: ecs_1.ECSTaskDefinitionUserForHostMode, 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 does not have encryption at rest enabled - (Control IDs: 3.4, 8.2.1).', 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 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 IDs: 4.1, 8.2.1).', 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: 2.3, 4.1, 8.2.1).", 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 ID: 6.6).', 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: 4.1, 8.2.1).', 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 ELB does not have logging enabled - (Control IDs: 10.1, 10.3.1, 10.3.2, 10.3.3, 10.3.4, 10.3.5, 10.3.6, 10.5.4).', 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: 2.3, 4.1, 8.2.1).', explanation: 'Ensure that your Classic Load Balancers (CLBs) are configured with SSL or HTTPS listeners. 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, }); this.applyRule({ info: 'The ALB, NLB, or GLB listener does not utilize an SSL certificate provided by ACM (Amazon Certificate Manager) - (Control ID: 4.1).', 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.ELBv2ACMCertificateRequired, 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 ALB, NLB, or GLB listener does not utilize an SSL certificate provided by ACM (Amazon Certificate Manager) - (Control ID: 7.2.1).', 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: 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 IDs: 7.1.2, 7.1.3, 7.2.1, 7.2.2).', 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 IDs: 2.2, 7.1.2, 7.1.3, 7.2.1, 7.2.2).', 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: 2.2, 7.1.2, 7.1.3, 7.2.1, 7.2.2).', 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.IAMPolicyNoStatementsWithAdminAccess, node: node, }); this.applyRule({ info: 'The IAM policy grants full access, meaning the policy allows a principal to perform all actions on individual resources - (Control IDs: 7.1.2, 7.1.3, 7.2.1, 7.2.2).', explanation: 'Ensure IAM Actions are restricted to only those actions that are needed. 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.IAMPolicyNoStatementsWithFullAccess, node: node, }); this.applyRule({ info: 'The IAM user does not belong to any group(s) - (Control IDs: 2.2, 7.1.2, 7.1.3, 7.2.1, 7.2.2).', 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: 2.2, 7.1.2, 7.1.3, 7.2.1, 7.2.2).', 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 IDs: 2.2, 3.5, 3.6, 3.6.4).', 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 permission grants public access - (Control IDs: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 1.3.4, 2.2.2).', 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, }); this.applyRule({ info: 'The Lambda function is not VPC enabled - (Control IDs: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 1.3.4, 2.2.2).', 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, }); } /** * 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: 3.4, 8.2.1).', 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: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 1.3.4, 1.3.6, 2.2.2).', 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 stream error logs (ES_APPLICATION_LOGS) to CloudWatch Logs - (Control IDs: 10.1, 10.2.1, 10.2.2, 10.2.3, 10.2.4, 10.2.5, 10.3.1, 10.3.2, 10.3.3, 10.3.4, 10.3.5, 10.3.6).', explanation: 'Ensure Amazon OpenSearch Service domains have error logs enabled and streamed to Amazon CloudWatch Logs for retention and response. Domain error logs can assist with security and access audits, and can help to diagnose availability issues.', level: nag_rules_1.NagMessageLevel.ERROR, rule: opensearch_1.OpenSearchErrorLogsToCloudWatch, node: node, }); this.applyRule({ info: 'The OpenSearch Service domain does not have node-to-node encryption enabled - (Control ID: 4.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 RDS Resources * @param node the CfnResource to check * @param ignores list of ignores for the resource */ checkRDS(node) { this.applyRule({ info: "The route table may contain one or more unrestricted route(s) to an IGW ('0.0.0.0/0' or '::/0') - (Control ID: 6.2).", explanation: 'Ensure Amazon EC2 route tables do not have unrestricted routes to an internet gateway. Removing or limiting the access to the internet for workloads within Amazon VPCs can reduce unintended access within your environment.', level: nag_rules_1.NagMessageLevel.ERROR, rule: rds_1.RDSAutomaticMinorVersionUpgradeEnabled, node: node, }); this.applyRule({ info: 'The RDS DB Instance allows public access - (Control IDs: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 1.3.4, 1.3.6, 2.2.2).', 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: 10.1, 10.2.1, 10.2.2, 10.2.3, 10.2.4, 10.2.5, 10.3.1, 10.3.2, 10.3.3, 10.3.4, 10.3.5, 10.3.6).', 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 RDS DB Instance or Aurora Cluster does not have storage encrypted - (Control IDs: 3.4, 8.2.1).', explanation: 'Because sensitive data can exist at rest in Amazon RDS instances, 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: 3.4, 8.2.1, 10.1, 10.2.1, 10.2.2, 10.2.3, 10.2.4, 10.2.5, 10.3.1, 10.3.2, 10.3.3, 10.3.4, 10.3.5, 10.3.6).', 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 does not have version upgrades enabled, automated snapshot retention periods enabled, and an explicit maintenance window configured - (Control ID: 6.2).', explanation: 'Ensure that Amazon Redshift clusters have the preferred settings for your organization. Specifically, that they have preferred maintenance windows and automated snapshot retention periods for the database. ', level: nag_rules_1.NagMessageLevel.ERROR, rule: redshift_1.RedshiftClusterMaintenanceSettings, node: node, }); this.applyRule({ info: 'The Redshift cluster allows public access - (Control IDs: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 1.3.4, 1.3.6, 2.2.2).', 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 have enhanced VPC routing enabled - (Control IDs: 1.2, 1.3, 1.3.1, 1.3.2).', explanation: 'Enhanced VPC routing forces all COPY and UNLOAD traffic between the cluster and data repositories to go through your Amazon VPC. You can then use VPC features such as security groups and network access control lists to secure network traffic. You can also use VPC flow logs to monitor network traffic.', level: nag_rules_1.NagMessageLevel.ERROR, rule: redshift_1.RedshiftEnhancedVPCRoutingEnabled, node: node, }); this.applyRule({ info: 'The Redshift cluster does not require TLS/SSL encryption - (Control IDs: 2.3, 4.1).', 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 prohibit public access through bucket level settings - (Control IDs: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 1.3.4, 1.3.6, 2.2.2).', explanation: 'Keep sensitive data safe from unauthorized remote users by preventing public access at the bucket level.', level: nag_rules_1.NagMessageLevel.ERROR, rule: s3_1.S3BucketLevelPublicAccessProhibited, node: node, }); this.applyRule({ info: 'The S3 Buckets does not have server access logs enabled - (Control IDs: 2.2, 10.1, 10.2.1, 10.2.2, 10.2.3, 10.2.4, 10.2.5, 10.2.7, 10.3.1, 10.3.2, 10.3.3, 10.3.4, 10.3.5, 10.3.6).', 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: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 1.3.4, 1.3.6, 2.2, 2.2.2).', 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: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 1.3.4, 1.3.6, 2.2, 2.2.2).', 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: 2.2, 10.5.3).', 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: 2.2, 4.1, 8.2.1).', 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 ID: 10.5.3).', 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, }); this.applyRule({ info: 'The S3 Bucket is not encrypted with a KMS Key by default - (Control IDs: 3.4, 8.2.1, 10.5).', explanation: 'Ensure that encryption is enabled for your Amazon Simple Storage Service (Amazon S3) buckets. Because sensitive data can exist at rest in an Amazon S3 bucket, enable encryption at rest to help protect that data.', level: nag_rules_1.NagMessageLevel.ERROR, rule: s3_1.S3DefaultEncryptionKMS, 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 resource endpoint is not encrypted with a KMS key - (Control IDs: 3.4, 8.2.1).', 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: 3.4, 8.2.1).', 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: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 1.3.4, 1.3.6, 2.2.2).', 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 Secrets Manager Resources * @param node the CfnResource to check * @param ignores list of ignores for the resource */ checkSecretsManager(node) { this.applyRule({ info: 'The secret is not encrypted with a KMS Customer managed key - (Control IDs: 3.4, 8.2.1).', explanation: 'To help protect data at rest, ensure encryption with AWS Key Management Service (AWS KMS) is enabled for AWS Secrets Manager secrets. Because sensitive data can exist at rest in Secrets Manager secrets, enable encryption at rest to help protect that data.', level: nag_rules_1.NagMessageLevel.ERROR, rule: secretsmanager_1.SecretsManagerUsingKMSKey, 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 ID: 8.2.1).', explanation: 'To help protect data at rest, ensure that your Amazon Simple Notification Service (Amazon SNS) topics require encryption using AWS Key Management Service (AWS KMS) 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: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 2.1, 2.2, 2.2.2).", explanation: 'Amazon Elastic Compute Cloud (Amazon EC2) security groups can help in the management of network access by providing stateful filtering of ingress and egress network traffic to AWS resources. 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: 2.2, 10.1, 10.3.2, 10.3.3, 10.3.4, 10.3.5, 10.3.6).', 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, }); this.applyRule({ info: "The route table may contain one or more unrestricted route(s) to an IGW ('0.0.0.0/0' or '::/0') - (Control IDs: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 2.2.2).", explanation: 'Ensure Amazon EC2 route tables do not have unrestricted routes to an internet gateway. Removing or limiting the access to the internet for workloads within Amazon VPCs can reduce unintended access within your environment.', level: nag_rules_1.NagMessageLevel.ERROR, rule: vpc_1.VPCNoUnrestrictedRouteToIGW, node: node, }); this.applyRule({ info: 'The subnet auto-assigns public IP addresses - (Control IDs: 1.2, 1.2.1, 1.3, 1.3.1, 1.3.2, 1.3.4, 1.3.6, 2.2.2).', explanation: 'Manage access to the AWS Cloud by ensuring Amazon Virtual Private Cloud (VPC) subnets are not automatically assigned a public IP address. Amazon Elastic Compute Cloud (EC2) instances that are launched into subnets that have this attribute enabled have a public IP address assigned to their primary network interface.', level: nag_rules_1.NagMessageLevel.ERROR, rule: vpc_1.VPCSubnetAutoAssignPublicIpDisabled, 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: 10.1, 10.3.1, 10.3.2, 10.3.3, 10.3.4, 10.3.5, 10.3.6, 10.5.4).', 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.PCIDSS321Checks = PCIDSS321Checks; _a = JSII_RTTI_SYMBOL_1; PCIDSS321Checks[_a] = { fqn: "cdk-nag.PCIDSS321Checks", version: "2.28.194" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGNpLWRzcy0zMjEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGFja3MvcGNpLWRzcy0zMjEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQTs7O0VBR0U7QUFFRiw2Q0FBMEM7QUFFMUMsMENBQW9EO0FBQ3BELDRDQUErQztBQUMvQywwQ0FLd0I7QUFDeEIsc0RBRzhCO0FBQzlCLG9EQUk2QjtBQUM3QixvREFHNkI7QUFDN0Isa0RBRzRCO0FBQzVCLHNDQUF1RDtBQUN2RCxzQ0FNc0I7QUFDdEIsc0NBQWdFO0FBQ2hFLHNDQUE0QztBQUM1QyxzQ0FRc0I7QUFDdEIsc0NBQWtEO0FBQ2xELHNDQU9zQjtBQUN0QixzQ0FBNEQ7QUFDNUQsNENBR3lCO0FBQ3pCLG9EQUs2QjtBQUM3QixzQ0FLc0I7QUFDdEIsZ0RBTTJCO0FBQzNCLG9DQVNxQjtBQUNyQixrREFJNEI7QUFDNUIsNERBQW9FO0FBQ3BFLHNDQUErQztBQUMvQyxzQ0FLc0I7QUFDdEIsc0NBQW1EO0FBRW5EOzs7R0FHRztBQUNILE1BQWEsZUFBZ0IsU0FBUSxrQkFBTztJQUMxQyxZQUFZLEtBQW9CO1FBQzlCLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNiLElBQUksQ0FBQyxRQUFRLEdBQUcsYUFBYSxDQUFDO0lBQ2hDLENBQUM7SUFDTSxLQUFLLENBQUMsSUFBZ0I7UUFDM0IsSUFBSSxJQUFJLFlBQVkseUJBQVcsRUFBRTtZQUMvQixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3RCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzNCLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDM0IsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMxQixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUks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