From f755655126a6e433e71748796e65cfb16280fbbf Mon Sep 17 00:00:00 2001 From: Khushboo Date: Mon, 29 Nov 2021 18:07:32 +0530 Subject: [PATCH 1/5] Add new controls in RBI Cyber Security Framework. Closes #330 --- conformance_pack/apigateway.sp | 20 +++++++++ conformance_pack/autoscaling.sp | 10 +++++ conformance_pack/elb.sp | 10 +++++ conformance_pack/es.sp | 10 +++++ conformance_pack/iam.sp | 10 +++++ conformance_pack/rds.sp | 10 +++++ conformance_pack/redshift.sp | 29 ++++++++++-- conformance_pack/s3.sp | 5 ++- conformance_pack/securityhub.sp | 9 ++-- conformance_pack/ssm.sp | 10 +++++ conformance_pack/vpc.sp | 15 ++++++- ...aling_launch_config_public_ip_disabled.sql | 16 +++++++ ...ication_network_lb_use_ssl_certificate.sql | 45 +++++++++++++++++++ query/es/es_domain_logs_to_cloudwatch.sql | 39 ++++++++++++++++ .../iam_all_policy_no_service_wild_card.sql | 31 +++++++++++++ .../redshift/redshift_cluster_kms_enabled.sql | 16 +++++++ ...ift_cluster_maintenance_settings_check.sql | 16 +++++++ .../ssm_document_restrict_public_access.sql | 18 ++++++++ ...te_table_restrict_public_access_to_igw.sql | 32 +++++++++++++ rbi_cyber_security/annex_i_12.sp | 3 +- rbi_cyber_security/annex_i_1_3.sp | 10 ++++- rbi_cyber_security/annex_i_5_1.sp | 5 ++- rbi_cyber_security/annex_i_6.sp | 4 +- rbi_cyber_security/annex_i_7_1.sp | 3 +- rbi_cyber_security/annex_i_7_4.sp | 4 +- 25 files changed, 362 insertions(+), 18 deletions(-) create mode 100644 query/autoscaling/autoscaling_launch_config_public_ip_disabled.sql create mode 100644 query/elb/elb_application_network_lb_use_ssl_certificate.sql create mode 100644 query/es/es_domain_logs_to_cloudwatch.sql create mode 100644 query/iam/iam_all_policy_no_service_wild_card.sql create mode 100644 query/redshift/redshift_cluster_kms_enabled.sql create mode 100644 query/redshift/redshift_cluster_maintenance_settings_check.sql create mode 100644 query/ssm/ssm_document_restrict_public_access.sql create mode 100644 query/vpc/vpc_route_table_restrict_public_access_to_igw.sql diff --git a/conformance_pack/apigateway.sp b/conformance_pack/apigateway.sp index 869955f5..fb9fbcd3 100644 --- a/conformance_pack/apigateway.sp +++ b/conformance_pack/apigateway.sp @@ -30,4 +30,24 @@ control "apigateway_stage_logging_enabled" { rbi_cyber_security = "true" soc_2 = "true" }) +} + +control "apigateway_rest_api_stage_use_ssl_certificate" { + title = "API Gateway stage should uses SSL certificate" + description = "Ensure if a REST API stage uses an Secure Sockets Layer (SSL) certificate. This rule is complaint if the REST API stage does not have an associated SSL certificate." + sql = query.apigateway_rest_api_stage_use_ssl_certificate.sql + + tags = merge(local.conformance_pack_apigateway_common_tags, { + rbi_cyber_security = "true" + }) +} + +control "apigateway_stage_use_waf_web_acl" { + title = "API Gateway stage should be associated with waf" + description = "Ensure if an Amazon API Gateway API stage is using an AWS WAF Web ACL. This rule is non complaint if an AWS WAF Web ACL is not used." + sql = query.apigateway_stage_use_waf_web_acl.sql + + tags = merge(local.conformance_pack_apigateway_common_tags, { + rbi_cyber_security = "true" + }) } \ No newline at end of file diff --git a/conformance_pack/autoscaling.sp b/conformance_pack/autoscaling.sp index f17984fd..379d38f7 100644 --- a/conformance_pack/autoscaling.sp +++ b/conformance_pack/autoscaling.sp @@ -14,4 +14,14 @@ control "autoscaling_group_with_lb_use_health_check" { nist_800_53_rev_4 = "true" nist_csf = "true" }) +} + +control "autoscaling_launch_config_public_ip_disabled" { + title = "Auto Scaling launch config public IP should be disabled" + description = "Ensure if Amazon EC2 Auto Scaling groups have public IP addresses enabled through Launch Configurations. This rule is non complaint if the Launch Configuration for an Auto Scaling group has AssociatePublicIpAddress set to 'true'." + sql = query.autoscaling_launch_config_public_ip_disabled.sql + + tags = merge(local.conformance_pack_autoscaling_common_tags, { + rbi_cyber_security = "true" + }) } \ No newline at end of file diff --git a/conformance_pack/elb.sp b/conformance_pack/elb.sp index 77e50876..2235b106 100644 --- a/conformance_pack/elb.sp +++ b/conformance_pack/elb.sp @@ -106,3 +106,13 @@ control "elb_classic_lb_cross_zone_load_balancing_enabled" { nist_csf = "true" }) } + +control "elb_application_network_lb_use_ssl_certificate" { + title = "ELB application and network load balancers should only use SSL or HTTPS listeners" + description = "Ensure if Application Load Balancers and Network Load Balancers are configured to use certificates from AWS Certificate Manager (ACM). This rule is complaint if at least 1 load balancer is configured without a certificate from ACM." + sql = query.elb_application_network_lb_use_ssl_certificate.sql + + tags = merge(local.conformance_pack_elb_common_tags, { + rbi_cyber_security = "true" + }) +} \ No newline at end of file diff --git a/conformance_pack/es.sp b/conformance_pack/es.sp index ae0204c9..f3283364 100644 --- a/conformance_pack/es.sp +++ b/conformance_pack/es.sp @@ -42,4 +42,14 @@ control "es_domain_node_to_node_encryption_enabled" { nist_800_53_rev_4 = "true" rbi_cyber_security = "true" }) +} + +control "es_domain_logs_to_cloudwatch" { + title = "Elasticsearch domain should send logs to cloudWatch" + description = "Ensure if Amazon OpenSearch Service (OpenSearch Service) domains are configured to send logs to Amazon CloudWatch Logs. The rule is complaint if a log is enabled for an OpenSearch Service domain. This rule is non complain if logging is not configured." + sql = query.es_domain_logs_to_cloudwatch.sql + + tags = merge(local.conformance_pack_es_common_tags, { + rbi_cyber_security = "true" + }) } \ No newline at end of file diff --git a/conformance_pack/iam.sp b/conformance_pack/iam.sp index 04830093..c82ee8c2 100644 --- a/conformance_pack/iam.sp +++ b/conformance_pack/iam.sp @@ -276,3 +276,13 @@ control "iam_account_password_policy_one_symbol" { hipaa = "true" }) } + +control "iam_all_policy_no_service_wild_card" { + title = "Ensure IAM policy should not grant full access to service" + description = "Checks if AWS Identity and Access Management (IAM) policies grant permissions to all actions on individual AWS resources. The rule is non complaint if the managed IAM policy allows full access to at least 1 AWS service." + sql = query.iam_all_policy_no_service_wild_card.sql + + tags = merge(local.conformance_pack_iam_common_tags, { + rbi_cyber_security = "true" + }) +} \ No newline at end of file diff --git a/conformance_pack/rds.sp b/conformance_pack/rds.sp index 244e2f27..85fdf37a 100644 --- a/conformance_pack/rds.sp +++ b/conformance_pack/rds.sp @@ -168,4 +168,14 @@ control "rds_db_instance_protected_by_backup_plan" { nist_csf = "true" soc_2 = "true" }) +} + +control "rds_db_instance_automatic_minor_version_upgrade_enabled" { + title = "RDS DB instance automatic minor version upgrade should be enabled" + description = "Ensure if Amazon Relational Database Service (RDS) database instances are configured for automatic minor version upgrades. The rule is NON_COMPLIANT if the value of 'autoMinorVersionUpgrade' is false." + sql = query.rds_db_instance_automatic_minor_version_upgrade_enabled.sql + + tags = merge(local.conformance_pack_rds_common_tags, { + rbi_cyber_security = "true" + }) } \ No newline at end of file diff --git a/conformance_pack/redshift.sp b/conformance_pack/redshift.sp index b55fdc00..6a52fd3e 100644 --- a/conformance_pack/redshift.sp +++ b/conformance_pack/redshift.sp @@ -52,9 +52,30 @@ control "redshift_cluster_automatic_snapshots_min_7_days" { sql = query.redshift_cluster_automatic_snapshots_min_7_days.sql tags = merge(local.conformance_pack_redshift_common_tags, { - gdpr = "true" - hipaa = "true" - nist_csf = "true" - sco_2 = "true" + gdpr = "true" + hipaa = "true" + nist_csf = "true" + rbi_cyber_security = "true" + sco_2 = "true" + }) +} + +control "redshift_cluster_kms_enabled" { + title = "Amazon Redshift clusters encrypted with KMS" + description = "Ensure if Amazon Redshift clusters are using a specified AWS Key Management Service (AWS KMS) key for encryption. The rule is complaint if encryption is enabled and the cluster is encrypted with the key provided in the kmsKeyArn parameter. The rule is non complaint if the cluster is not encrypted or encrypted with another key." + sql = query.redshift_cluster_kms_enabled.sql + + tags = merge(local.conformance_pack_redshift_common_tags, { + rbi_cyber_security = "true" + }) +} + +control "redshift_cluster_maintenance_settings_check" { + title = "Amazon Redshift should have required maintenance settings" + description = "Ensure whether Amazon Redshift clusters have the specified maintenance settings. Redshift clusters `allowVersionUpgrade` should be set to `true` and `automatedSnapshotRetentionPeriod` should be greater than 7." + sql = query.redshift_cluster_maintenance_settings_check.sql + + tags = merge(local.conformance_pack_redshift_common_tags, { + rbi_cyber_security = "true" }) } \ No newline at end of file diff --git a/conformance_pack/s3.sp b/conformance_pack/s3.sp index 4efc3a5b..66f34898 100644 --- a/conformance_pack/s3.sp +++ b/conformance_pack/s3.sp @@ -146,7 +146,8 @@ control "s3_bucket_default_encryption_enabled_kms" { sql = query.s3_bucket_default_encryption_enabled_kms.sql tags = merge(local.conformance_pack_s3_common_tags, { - gdpr = "true" - hipaa = "true" + gdpr = "true" + hipaa = "true" + rbi_cyber_security = "true" }) } \ No newline at end of file diff --git a/conformance_pack/securityhub.sp b/conformance_pack/securityhub.sp index cd219164..7b6c264c 100644 --- a/conformance_pack/securityhub.sp +++ b/conformance_pack/securityhub.sp @@ -10,9 +10,10 @@ control "securityhub_enabled" { sql = query.securityhub_enabled.sql tags = merge(local.conformance_pack_securityhub_common_tags, { - hipaa = "true" - nist_800_53_rev_4 = "true" - nist_csf = "true" - soc_2 = "true" + hipaa = "true" + nist_800_53_rev_4 = "true" + nist_csf = "true" + rbi_cyber_security = "true" + soc_2 = "true" }) } \ No newline at end of file diff --git a/conformance_pack/ssm.sp b/conformance_pack/ssm.sp index 34413610..2ab3ab61 100644 --- a/conformance_pack/ssm.sp +++ b/conformance_pack/ssm.sp @@ -43,4 +43,14 @@ control "ssm_managed_instance_compliance_patch_compliant" { rbi_cyber_security = "true" soc_2 = "true" }) +} + +control "ssm_document_restrict_public_access" { + title = "SSM document should restrict public access" + description = "Ensure if AWS Systems Manager documents owned by the account are public. This rule is non compliant if SSM documents with owner 'Self' are public." + sql = query.ssm_document_restrict_public_access.sql + + tags = merge(local.conformance_pack_ssm_common_tags, { + rbi_cyber_security = "true" + }) } \ No newline at end of file diff --git a/conformance_pack/vpc.sp b/conformance_pack/vpc.sp index af206f4b..d1e2ed54 100644 --- a/conformance_pack/vpc.sp +++ b/conformance_pack/vpc.sp @@ -123,6 +123,17 @@ control "vpc_subnet_auto_assign_public_ip_disabled" { sql = query.vpc_subnet_auto_assign_public_ip_disabled.sql tags = merge(local.conformance_pack_vpc_common_tags, { - nist_csf = "true" + nist_csf = "true" + rbi_cyber_security = "true" + }) +} + +control "vpc_route_table_restrict_public_access_to_igw" { + title = "VPC route table should restrict public access to IGW" + description = "Ensure if there are public routes in the route table to an Internet Gateway (IGW). The rule is complaint if a route to an IGW has a destination CIDR block of '0.0.0.0/0' or '::/0' or if a destination CIDR block does not match the rule parameter." + sql = query.vpc_route_table_restrict_public_access_to_igw.sql + + tags = merge(local.conformance_pack_vpc_common_tags, { + rbi_cyber_security = "true" }) -} \ No newline at end of file +} diff --git a/query/autoscaling/autoscaling_launch_config_public_ip_disabled.sql b/query/autoscaling/autoscaling_launch_config_public_ip_disabled.sql new file mode 100644 index 00000000..93cd5f8c --- /dev/null +++ b/query/autoscaling/autoscaling_launch_config_public_ip_disabled.sql @@ -0,0 +1,16 @@ +select + -- Required Columns + launch_configuration_arn as resource, + case + when associate_public_ip_address then 'alarm' + else 'ok' + end as status, + case + when associate_public_ip_address then title || ' public IP enabled.' + else title || ' public IP disabled.' + end as reason, + -- Additional Dimensions + region, + account_id +from + aws_ec2_launch_configuration; \ No newline at end of file diff --git a/query/elb/elb_application_network_lb_use_ssl_certificate.sql b/query/elb/elb_application_network_lb_use_ssl_certificate.sql new file mode 100644 index 00000000..fa7183e2 --- /dev/null +++ b/query/elb/elb_application_network_lb_use_ssl_certificate.sql @@ -0,0 +1,45 @@ + with listeners_without_certificate as ( + select + load_balancer_arn, + count(*) as count + from + aws_ec2_load_balancer_listener + where arn not in + ( select arn from aws_ec2_load_balancer_listener, jsonb_array_elements(certificates) as c + where c ->> 'CertificateArn' like 'arn:aws:acm%' ) + group by load_balancer_arn +), +all_application_network_load_balacer as ( + select + arn, + account_id, + region, + title + from + aws_ec2_application_load_balancer + union + select + arn, + account_id, + region, + title + from + aws_ec2_network_load_balancer +) +select + -- Required Columns + a.arn as resource, + case + when b.load_balancer_arn is null then 'ok' + else 'alarm' + end as status, + case + when b.load_balancer_arn is null then a.title || ' uses certificates provided by ACM.' + else a.title || ' ' || b.count || ' listners not uses certificates provided by ACM.' + end as reason, + -- Additional Dimensions + a.region, + a.account_id +from + all_application_network_load_balacer as a + left join listeners_without_certificate as b on a.arn = b.load_balancer_arn; \ No newline at end of file diff --git a/query/es/es_domain_logs_to_cloudwatch.sql b/query/es/es_domain_logs_to_cloudwatch.sql new file mode 100644 index 00000000..52365453 --- /dev/null +++ b/query/es/es_domain_logs_to_cloudwatch.sql @@ -0,0 +1,39 @@ +select + -- Required Columns + arn as resource, + case + when + ( log_publishing_options -> 'ES_APPLICATION_LOGS' -> 'Enabled' = 'true' + and log_publishing_options -> 'ES_APPLICATION_LOGS' -> 'CloudWatchLogsLogGroupArn' is not null + ) + and + ( log_publishing_options -> 'SEARCH_SLOW_LOGS' -> 'Enabled' = 'true' + and log_publishing_options -> 'SEARCH_SLOW_LOGS' -> 'CloudWatchLogsLogGroupArn' is not null + ) + and + ( log_publishing_options -> 'INDEX_SLOW_LOGS' -> 'Enabled' = 'true' + and log_publishing_options -> 'INDEX_SLOW_LOGS' -> 'CloudWatchLogsLogGroupArn' is not null + ) + then 'ok' + else 'alarm' + end as status, + case + when + ( log_publishing_options -> 'ES_APPLICATION_LOGS' -> 'Enabled' = 'true' + and log_publishing_options -> 'ES_APPLICATION_LOGS' -> 'CloudWatchLogsLogGroupArn' is not null + ) + and + ( log_publishing_options -> 'SEARCH_SLOW_LOGS' -> 'Enabled' = 'true' + and log_publishing_options -> 'SEARCH_SLOW_LOGS' -> 'CloudWatchLogsLogGroupArn' is not null + ) + and + ( log_publishing_options -> 'INDEX_SLOW_LOGS' -> 'Enabled' = 'true' + and log_publishing_options -> 'INDEX_SLOW_LOGS' -> 'CloudWatchLogsLogGroupArn' is not null + ) then title || ' logging enabled for search , index and error.' + else title || ' logging not enabled for all search, index and error.' + end as reason, + -- Additional Dimensions + region, + account_id +from + aws_elasticsearch_domain; \ No newline at end of file diff --git a/query/iam/iam_all_policy_no_service_wild_card.sql b/query/iam/iam_all_policy_no_service_wild_card.sql new file mode 100644 index 00000000..bba6b2b3 --- /dev/null +++ b/query/iam/iam_all_policy_no_service_wild_card.sql @@ -0,0 +1,31 @@ +with wildcard_action_policies as ( + select + arn, + count(*) as statements_num + from + aws_iam_policy, + jsonb_array_elements(policy_std -> 'Statement') as s, + jsonb_array_elements_text(s -> 'Resource') as resource, + jsonb_array_elements_text(s -> 'Action') as action + where + is_aws_managed = 'false' + and s ->> 'Effect' = 'Allow' + and resource = '*' + and action like '%:*' + group by + arn +) +select + -- Required Columns + a.arn as resource, + case + when b.arn is null then 'ok' + else 'alarm' + end status, + a.name || ' contains ' || coalesce(b.statements_num,0) || + ' statements that allow action "Service:*" on resource "*".' as reason, + -- Additional Dimensions + a.account_id +from + aws_iam_policy as a + left join wildcard_action_policies as b on a.arn = b.arn; \ No newline at end of file diff --git a/query/redshift/redshift_cluster_kms_enabled.sql b/query/redshift/redshift_cluster_kms_enabled.sql new file mode 100644 index 00000000..ba38b680 --- /dev/null +++ b/query/redshift/redshift_cluster_kms_enabled.sql @@ -0,0 +1,16 @@ +select + -- Required Columns + 'arn:aws:redshift:' || region || ':' || account_id || ':' || 'cluster' || ':' || cluster_identifier as resource, + case + when encrypted and kms_key_id is not null then 'ok' + else 'alarm' + end as status, + case + when encrypted and kms_key_id is not null then title || ' encrypted with KMS.' + else title || ' not encrypted with KMS' + end as reason, + -- Additional Dimensions + region, + account_id +from + aws_redshift_cluster; \ No newline at end of file diff --git a/query/redshift/redshift_cluster_maintenance_settings_check.sql b/query/redshift/redshift_cluster_maintenance_settings_check.sql new file mode 100644 index 00000000..946a7cd5 --- /dev/null +++ b/query/redshift/redshift_cluster_maintenance_settings_check.sql @@ -0,0 +1,16 @@ +select + -- Required Columns + 'arn:aws:redshift:' || region || ':' || account_id || ':' || 'cluster' || ':' || cluster_identifier as resource, + case + when allow_version_upgrade and automated_snapshot_retention_period >= 7 then 'ok' + else 'alarm' + end as status, + case + when allow_version_upgrade and automated_snapshot_retention_period >= 7 then title || ' have required maintenance settings.' + else title || ' does not have required maintenance settings.' + end as reason, + -- Additional Dimensions + region, + account_id +from + aws_redshift_cluster; \ No newline at end of file diff --git a/query/ssm/ssm_document_restrict_public_access.sql b/query/ssm/ssm_document_restrict_public_access.sql new file mode 100644 index 00000000..2895a065 --- /dev/null +++ b/query/ssm/ssm_document_restrict_public_access.sql @@ -0,0 +1,18 @@ +select + -- Required Columns + name as resource, + case + when account_ids @> '["all"]' then 'alarm' + else 'ok' + end as status, + case + when account_ids @> '["all"]' then title || ' publicly accesible.' + else title || ' not publicly accesible.' + end as reason, + -- Additional Dimentions + region, + account_id +from + aws_ssm_document +where + owner = 'self'; \ No newline at end of file diff --git a/query/vpc/vpc_route_table_restrict_public_access_to_igw.sql b/query/vpc/vpc_route_table_restrict_public_access_to_igw.sql new file mode 100644 index 00000000..619bbc89 --- /dev/null +++ b/query/vpc/vpc_route_table_restrict_public_access_to_igw.sql @@ -0,0 +1,32 @@ +with route_with_public_access as ( + select + route_table_id, + count(*) as num + from + aws_vpc_route_table, + jsonb_array_elements(routes) as r + where + ( r ->> 'DestinationCidrBlock' = '0.0.0.0/0' + or r ->> 'DestinationCidrBlock' = '::/0' + ) + and r ->> 'GatewayId' like 'igw%' + group by + route_table_id +) +select + -- Required Columns + a.route_table_id as resource, + case + when b.route_table_id is null then 'ok' + else 'alarm' + end as status, + case + when b.route_table_id is null then a.title || ' does not have public routes to an Internet Gateway (IGW)' + else a.title || ' contains ' || b.num || ' rule(s) have public routes to an Internet Gateway (IGW)' + end as reason, + -- Additional Dimensions + a.region, + a.account_id +from + aws_vpc_route_table as a + left join route_with_public_access as b on b.route_table_id = a.route_table_id diff --git a/rbi_cyber_security/annex_i_12.sp b/rbi_cyber_security/annex_i_12.sp index cfe17a0a..041f106a 100644 --- a/rbi_cyber_security/annex_i_12.sp +++ b/rbi_cyber_security/annex_i_12.sp @@ -10,8 +10,9 @@ benchmark "rbi_cyber_security_annex_i_12" { control.elasticache_redis_cluster_automatic_backup_retention_15_days, control.rds_db_instance_backup_enabled, control.rds_db_instance_in_backup_plan, + control.redshift_cluster_automatic_snapshots_min_7_days, control.s3_bucket_cross_region_replication_enabled, - control.s3_bucket_versioning_enabled + control.s3_bucket_versioning_enabled, ] tags = merge(local.rbi_cyber_security_common_tags, { diff --git a/rbi_cyber_security/annex_i_1_3.sp b/rbi_cyber_security/annex_i_1_3.sp index cdabc78d..238df851 100644 --- a/rbi_cyber_security/annex_i_1_3.sp +++ b/rbi_cyber_security/annex_i_1_3.sp @@ -4,7 +4,9 @@ benchmark "rbi_cyber_security_annex_i_1_3" { children = [ control.acm_certificate_expires_30_days, + control.apigateway_rest_api_stage_use_ssl_certificate, control.apigateway_stage_cache_encryption_at_rest_enabled, + control.autoscaling_launch_config_public_ip_disabled, control.cloudtrail_trail_logs_encrypted_with_kms_cmk, control.dms_replication_instance_not_publicly_accessible, control.dynamodb_table_encrypted_with_kms_cmk, @@ -16,6 +18,7 @@ benchmark "rbi_cyber_security_annex_i_1_3" { control.efs_file_system_encrypt_data_at_rest, control.elb_application_lb_drop_http_headers, control.elb_application_lb_redirect_http_request_to_https, + control.elb_application_network_lb_use_ssl_certificate, control.elb_classic_lb_use_ssl_certificate, control.elb_classic_lb_use_tls_https_listeners, control.emr_cluster_master_nodes_no_public_ip, @@ -33,7 +36,9 @@ benchmark "rbi_cyber_security_annex_i_1_3" { control.rds_db_snapshot_prohibit_public_access, control.redshift_cluster_encryption_in_transit_enabled, control.redshift_cluster_encryption_logging_enabled, + control.redshift_cluster_kms_enabled, control.redshift_cluster_prohibit_public_access, + control.s3_bucket_default_encryption_enabled_kms, control.s3_bucket_default_encryption_enabled, control.s3_bucket_enforces_ssl, control.s3_bucket_restrict_public_read_access, @@ -43,8 +48,11 @@ benchmark "rbi_cyber_security_annex_i_1_3" { control.sagemaker_notebook_instance_direct_internet_access_disabled, control.sagemaker_notebook_instance_encryption_at_rest_enabled, control.sns_topic_encrypted_at_rest, + control.ssm_document_restrict_public_access, control.vpc_igw_attached_to_authorized_vpc, - control.vpc_security_group_restrict_ingress_common_ports_all + control.vpc_route_table_restrict_public_access_to_igw, + control.vpc_security_group_restrict_ingress_common_ports_all, + control.vpc_subnet_auto_assign_public_ip_disabled, ] tags = merge(local.rbi_cyber_security_common_tags, { diff --git a/rbi_cyber_security/annex_i_5_1.sp b/rbi_cyber_security/annex_i_5_1.sp index b1b3a0a1..934b666e 100644 --- a/rbi_cyber_security/annex_i_5_1.sp +++ b/rbi_cyber_security/annex_i_5_1.sp @@ -3,9 +3,12 @@ benchmark "rbi_cyber_security_annex_i_5_1" { description = "The firewall configurations should be set to the highest security level and evaluation of critical device (such as firewall, network switches, security devices, etc.) configurations should be done periodically." children = [ + control.apigateway_stage_use_waf_web_acl, control.elb_application_lb_waf_enabled, control.vpc_default_security_group_restricts_all_traffic, - control.vpc_security_group_restrict_ingress_tcp_udp_all + control.vpc_security_group_restrict_ingress_common_ports_all, + control.vpc_security_group_restrict_ingress_ssh_all, + control.vpc_security_group_restrict_ingress_tcp_udp_all, ] tags = merge(local.rbi_cyber_security_common_tags, { diff --git a/rbi_cyber_security/annex_i_6.sp b/rbi_cyber_security/annex_i_6.sp index d9dcc2db..08e467bc 100644 --- a/rbi_cyber_security/annex_i_6.sp +++ b/rbi_cyber_security/annex_i_6.sp @@ -4,8 +4,10 @@ benchmark "rbi_cyber_security_annex_i_6" { children = [ control.guardduty_finding_archived, + control.rds_db_instance_automatic_minor_version_upgrade_enabled, + control.redshift_cluster_maintenance_settings_check, control.ssm_managed_instance_compliance_association_compliant, - control.ssm_managed_instance_compliance_patch_compliant + control.ssm_managed_instance_compliance_patch_compliant, ] tags = merge(local.rbi_cyber_security_common_tags, { diff --git a/rbi_cyber_security/annex_i_7_1.sp b/rbi_cyber_security/annex_i_7_1.sp index 7e9b7d98..beceb32d 100644 --- a/rbi_cyber_security/annex_i_7_1.sp +++ b/rbi_cyber_security/annex_i_7_1.sp @@ -3,10 +3,11 @@ benchmark "rbi_cyber_security_annex_i_7_1" { description = "Disallow administrative rights on end-user workstations/PCs/laptops and provide access rights on a ‘need to know’ and ‘need to do’ basis." children = [ + control.iam_all_policy_no_service_wild_card, control.iam_group_user_role_no_inline_policies, control.iam_policy_no_star_star, control.iam_root_user_no_access_keys, - control.iam_user_no_inline_attached_policies + control.iam_user_no_inline_attached_policies, ] tags = merge(local.rbi_cyber_security_common_tags, { diff --git a/rbi_cyber_security/annex_i_7_4.sp b/rbi_cyber_security/annex_i_7_4.sp index 1c8857c6..5af87ee4 100644 --- a/rbi_cyber_security/annex_i_7_4.sp +++ b/rbi_cyber_security/annex_i_7_4.sp @@ -10,11 +10,13 @@ benchmark "rbi_cyber_security_annex_i_7_4" { control.cloudtrail_trail_integrated_with_logs, control.cloudwatch_log_group_retention_period_365, control.elb_application_classic_lb_logging_enabled, + control.es_domain_logs_to_cloudwatch, control.rds_db_instance_logging_enabled, control.redshift_cluster_encryption_logging_enabled, control.s3_bucket_logging_enabled, + control.securityhub_enabled, control.vpc_flow_logs_enabled, - control.wafv2_web_acl_logging_enabled + control.wafv2_web_acl_logging_enabled, ] tags = merge(local.rbi_cyber_security_common_tags, { From f89d9e21567070df209112fdb5099e4512668936 Mon Sep 17 00:00:00 2001 From: Khushboo Date: Mon, 29 Nov 2021 18:16:17 +0530 Subject: [PATCH 2/5] update --- conformance_pack/redshift.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conformance_pack/redshift.sp b/conformance_pack/redshift.sp index 6a52fd3e..10aed6a1 100644 --- a/conformance_pack/redshift.sp +++ b/conformance_pack/redshift.sp @@ -61,7 +61,7 @@ control "redshift_cluster_automatic_snapshots_min_7_days" { } control "redshift_cluster_kms_enabled" { - title = "Amazon Redshift clusters encrypted with KMS" + title = "Amazon Redshift clusters should be encrypted with KMS" description = "Ensure if Amazon Redshift clusters are using a specified AWS Key Management Service (AWS KMS) key for encryption. The rule is complaint if encryption is enabled and the cluster is encrypted with the key provided in the kmsKeyArn parameter. The rule is non complaint if the cluster is not encrypted or encrypted with another key." sql = query.redshift_cluster_kms_enabled.sql From 6bd79256a9cc584da418984c688960c813e6a024 Mon Sep 17 00:00:00 2001 From: Khushboo Date: Mon, 29 Nov 2021 19:17:26 +0530 Subject: [PATCH 3/5] removed ssm_document_restrict_public_access control --- conformance_pack/ssm.sp | 10 ---------- .../ssm_document_restrict_public_access.sql | 18 ------------------ rbi_cyber_security/annex_i_1_3.sp | 1 - 3 files changed, 29 deletions(-) delete mode 100644 query/ssm/ssm_document_restrict_public_access.sql diff --git a/conformance_pack/ssm.sp b/conformance_pack/ssm.sp index 2ab3ab61..04af22d8 100644 --- a/conformance_pack/ssm.sp +++ b/conformance_pack/ssm.sp @@ -44,13 +44,3 @@ control "ssm_managed_instance_compliance_patch_compliant" { soc_2 = "true" }) } - -control "ssm_document_restrict_public_access" { - title = "SSM document should restrict public access" - description = "Ensure if AWS Systems Manager documents owned by the account are public. This rule is non compliant if SSM documents with owner 'Self' are public." - sql = query.ssm_document_restrict_public_access.sql - - tags = merge(local.conformance_pack_ssm_common_tags, { - rbi_cyber_security = "true" - }) -} \ No newline at end of file diff --git a/query/ssm/ssm_document_restrict_public_access.sql b/query/ssm/ssm_document_restrict_public_access.sql deleted file mode 100644 index 2895a065..00000000 --- a/query/ssm/ssm_document_restrict_public_access.sql +++ /dev/null @@ -1,18 +0,0 @@ -select - -- Required Columns - name as resource, - case - when account_ids @> '["all"]' then 'alarm' - else 'ok' - end as status, - case - when account_ids @> '["all"]' then title || ' publicly accesible.' - else title || ' not publicly accesible.' - end as reason, - -- Additional Dimentions - region, - account_id -from - aws_ssm_document -where - owner = 'self'; \ No newline at end of file diff --git a/rbi_cyber_security/annex_i_1_3.sp b/rbi_cyber_security/annex_i_1_3.sp index 238df851..09ca40de 100644 --- a/rbi_cyber_security/annex_i_1_3.sp +++ b/rbi_cyber_security/annex_i_1_3.sp @@ -48,7 +48,6 @@ benchmark "rbi_cyber_security_annex_i_1_3" { control.sagemaker_notebook_instance_direct_internet_access_disabled, control.sagemaker_notebook_instance_encryption_at_rest_enabled, control.sns_topic_encrypted_at_rest, - control.ssm_document_restrict_public_access, control.vpc_igw_attached_to_authorized_vpc, control.vpc_route_table_restrict_public_access_to_igw, control.vpc_security_group_restrict_ingress_common_ports_all, From 5062ad9559f5337c432046bf34e55aafee5bc4b2 Mon Sep 17 00:00:00 2001 From: rajmohanty17 Date: Wed, 8 Dec 2021 17:27:19 +0530 Subject: [PATCH 4/5] Updated reasons --- .../apigateway_rest_api_stage_use_ssl_certificate.sql | 2 +- query/elb/elb_application_network_lb_use_ssl_certificate.sql | 2 +- query/elb/elb_classic_lb_use_ssl_certificate.sql | 2 +- query/es/es_domain_logs_to_cloudwatch.sql | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/query/apigateway/apigateway_rest_api_stage_use_ssl_certificate.sql b/query/apigateway/apigateway_rest_api_stage_use_ssl_certificate.sql index 9804ac0f..5c4e4417 100644 --- a/query/apigateway/apigateway_rest_api_stage_use_ssl_certificate.sql +++ b/query/apigateway/apigateway_rest_api_stage_use_ssl_certificate.sql @@ -6,7 +6,7 @@ select else 'ok' end as status, case - when client_certificate_id is null then title || ' not uses SSL certificate.' + when client_certificate_id is null then title || ' does not use SSL certificate.' else title || ' uses SSL certificate.' end as reason, -- Additional Dimensions diff --git a/query/elb/elb_application_network_lb_use_ssl_certificate.sql b/query/elb/elb_application_network_lb_use_ssl_certificate.sql index fa7183e2..473ff7cb 100644 --- a/query/elb/elb_application_network_lb_use_ssl_certificate.sql +++ b/query/elb/elb_application_network_lb_use_ssl_certificate.sql @@ -35,7 +35,7 @@ select end as status, case when b.load_balancer_arn is null then a.title || ' uses certificates provided by ACM.' - else a.title || ' ' || b.count || ' listners not uses certificates provided by ACM.' + else a.title || ' ' || b.count || ' listners does not use certificates provided by ACM.' end as reason, -- Additional Dimensions a.region, diff --git a/query/elb/elb_classic_lb_use_ssl_certificate.sql b/query/elb/elb_classic_lb_use_ssl_certificate.sql index d3f1a4a2..3d15f787 100644 --- a/query/elb/elb_classic_lb_use_ssl_certificate.sql +++ b/query/elb/elb_classic_lb_use_ssl_certificate.sql @@ -18,7 +18,7 @@ select end as status, case when a.listener_descriptions is null then a.title || ' has no listener.' - when b.name is not null then a.title || ' not uses certificates provided by ACM.' + when b.name is not null then a.title || ' does not use certificates provided by ACM.' else a.title || ' uses certificates provided by ACM.' end as reason, -- Additional Dimensions diff --git a/query/es/es_domain_logs_to_cloudwatch.sql b/query/es/es_domain_logs_to_cloudwatch.sql index 52365453..1b7d2e93 100644 --- a/query/es/es_domain_logs_to_cloudwatch.sql +++ b/query/es/es_domain_logs_to_cloudwatch.sql @@ -19,7 +19,7 @@ select end as status, case when - ( log_publishing_options -> 'ES_APPLICATION_LOGS' -> 'Enabled' = 'true' + ( log_publishing_options -> 'ES_APPLICATION_LOGS' -> 'Enabled' = 'true' and log_publishing_options -> 'ES_APPLICATION_LOGS' -> 'CloudWatchLogsLogGroupArn' is not null ) and From 78b90929e5f825e2ebced07115e28741850cd15a Mon Sep 17 00:00:00 2001 From: misraved Date: Wed, 8 Dec 2021 22:07:30 +0530 Subject: [PATCH 5/5] Minor updates to the queries and controls --- conformance_pack/apigateway.sp | 4 ++-- query/elb/elb_application_network_lb_use_ssl_certificate.sql | 2 +- .../redshift/redshift_cluster_maintenance_settings_check.sql | 2 +- query/vpc/vpc_route_table_restrict_public_access_to_igw.sql | 2 +- rbi_cyber_security/annex_i_12.sp | 2 +- rbi_cyber_security/annex_i_1_3.sp | 2 +- rbi_cyber_security/annex_i_5_1.sp | 2 +- rbi_cyber_security/annex_i_6.sp | 2 +- rbi_cyber_security/annex_i_7_1.sp | 2 +- rbi_cyber_security/annex_i_7_4.sp | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/conformance_pack/apigateway.sp b/conformance_pack/apigateway.sp index fb9fbcd3..37d94009 100644 --- a/conformance_pack/apigateway.sp +++ b/conformance_pack/apigateway.sp @@ -34,7 +34,7 @@ control "apigateway_stage_logging_enabled" { control "apigateway_rest_api_stage_use_ssl_certificate" { title = "API Gateway stage should uses SSL certificate" - description = "Ensure if a REST API stage uses an Secure Sockets Layer (SSL) certificate. This rule is complaint if the REST API stage does not have an associated SSL certificate." + description = "Ensure if a REST API stage uses a Secure Sockets Layer (SSL) certificate. This rule is complaint if the REST API stage does not have an associated SSL certificate." sql = query.apigateway_rest_api_stage_use_ssl_certificate.sql tags = merge(local.conformance_pack_apigateway_common_tags, { @@ -44,7 +44,7 @@ control "apigateway_rest_api_stage_use_ssl_certificate" { control "apigateway_stage_use_waf_web_acl" { title = "API Gateway stage should be associated with waf" - description = "Ensure if an Amazon API Gateway API stage is using an AWS WAF Web ACL. This rule is non complaint if an AWS WAF Web ACL is not used." + description = "Ensure if an Amazon API Gateway API stage is using a WAF Web ACL. This rule is non complaint if an AWS WAF Web ACL is not used." sql = query.apigateway_stage_use_waf_web_acl.sql tags = merge(local.conformance_pack_apigateway_common_tags, { diff --git a/query/elb/elb_application_network_lb_use_ssl_certificate.sql b/query/elb/elb_application_network_lb_use_ssl_certificate.sql index 473ff7cb..7170f338 100644 --- a/query/elb/elb_application_network_lb_use_ssl_certificate.sql +++ b/query/elb/elb_application_network_lb_use_ssl_certificate.sql @@ -35,7 +35,7 @@ select end as status, case when b.load_balancer_arn is null then a.title || ' uses certificates provided by ACM.' - else a.title || ' ' || b.count || ' listners does not use certificates provided by ACM.' + else a.title || ' has ' || b.count || ' listeners which do not use certificates provided by ACM.' end as reason, -- Additional Dimensions a.region, diff --git a/query/redshift/redshift_cluster_maintenance_settings_check.sql b/query/redshift/redshift_cluster_maintenance_settings_check.sql index 946a7cd5..155006ff 100644 --- a/query/redshift/redshift_cluster_maintenance_settings_check.sql +++ b/query/redshift/redshift_cluster_maintenance_settings_check.sql @@ -6,7 +6,7 @@ select else 'alarm' end as status, case - when allow_version_upgrade and automated_snapshot_retention_period >= 7 then title || ' have required maintenance settings.' + when allow_version_upgrade and automated_snapshot_retention_period >= 7 then title || ' has the required maintenance settings.' else title || ' does not have required maintenance settings.' end as reason, -- Additional Dimensions diff --git a/query/vpc/vpc_route_table_restrict_public_access_to_igw.sql b/query/vpc/vpc_route_table_restrict_public_access_to_igw.sql index 619bbc89..8b7ab9d8 100644 --- a/query/vpc/vpc_route_table_restrict_public_access_to_igw.sql +++ b/query/vpc/vpc_route_table_restrict_public_access_to_igw.sql @@ -22,7 +22,7 @@ select end as status, case when b.route_table_id is null then a.title || ' does not have public routes to an Internet Gateway (IGW)' - else a.title || ' contains ' || b.num || ' rule(s) have public routes to an Internet Gateway (IGW)' + else a.title || ' contains ' || b.num || ' rule(s) which have public routes to an Internet Gateway (IGW)' end as reason, -- Additional Dimensions a.region, diff --git a/rbi_cyber_security/annex_i_12.sp b/rbi_cyber_security/annex_i_12.sp index 041f106a..ea158fc0 100644 --- a/rbi_cyber_security/annex_i_12.sp +++ b/rbi_cyber_security/annex_i_12.sp @@ -12,7 +12,7 @@ benchmark "rbi_cyber_security_annex_i_12" { control.rds_db_instance_in_backup_plan, control.redshift_cluster_automatic_snapshots_min_7_days, control.s3_bucket_cross_region_replication_enabled, - control.s3_bucket_versioning_enabled, + control.s3_bucket_versioning_enabled ] tags = merge(local.rbi_cyber_security_common_tags, { diff --git a/rbi_cyber_security/annex_i_1_3.sp b/rbi_cyber_security/annex_i_1_3.sp index 09ca40de..7ef0e629 100644 --- a/rbi_cyber_security/annex_i_1_3.sp +++ b/rbi_cyber_security/annex_i_1_3.sp @@ -51,7 +51,7 @@ benchmark "rbi_cyber_security_annex_i_1_3" { control.vpc_igw_attached_to_authorized_vpc, control.vpc_route_table_restrict_public_access_to_igw, control.vpc_security_group_restrict_ingress_common_ports_all, - control.vpc_subnet_auto_assign_public_ip_disabled, + control.vpc_subnet_auto_assign_public_ip_disabled ] tags = merge(local.rbi_cyber_security_common_tags, { diff --git a/rbi_cyber_security/annex_i_5_1.sp b/rbi_cyber_security/annex_i_5_1.sp index 934b666e..cc1404fc 100644 --- a/rbi_cyber_security/annex_i_5_1.sp +++ b/rbi_cyber_security/annex_i_5_1.sp @@ -8,7 +8,7 @@ benchmark "rbi_cyber_security_annex_i_5_1" { control.vpc_default_security_group_restricts_all_traffic, control.vpc_security_group_restrict_ingress_common_ports_all, control.vpc_security_group_restrict_ingress_ssh_all, - control.vpc_security_group_restrict_ingress_tcp_udp_all, + control.vpc_security_group_restrict_ingress_tcp_udp_all ] tags = merge(local.rbi_cyber_security_common_tags, { diff --git a/rbi_cyber_security/annex_i_6.sp b/rbi_cyber_security/annex_i_6.sp index 08e467bc..10160d26 100644 --- a/rbi_cyber_security/annex_i_6.sp +++ b/rbi_cyber_security/annex_i_6.sp @@ -7,7 +7,7 @@ benchmark "rbi_cyber_security_annex_i_6" { control.rds_db_instance_automatic_minor_version_upgrade_enabled, control.redshift_cluster_maintenance_settings_check, control.ssm_managed_instance_compliance_association_compliant, - control.ssm_managed_instance_compliance_patch_compliant, + control.ssm_managed_instance_compliance_patch_compliant ] tags = merge(local.rbi_cyber_security_common_tags, { diff --git a/rbi_cyber_security/annex_i_7_1.sp b/rbi_cyber_security/annex_i_7_1.sp index beceb32d..e9b2587a 100644 --- a/rbi_cyber_security/annex_i_7_1.sp +++ b/rbi_cyber_security/annex_i_7_1.sp @@ -7,7 +7,7 @@ benchmark "rbi_cyber_security_annex_i_7_1" { control.iam_group_user_role_no_inline_policies, control.iam_policy_no_star_star, control.iam_root_user_no_access_keys, - control.iam_user_no_inline_attached_policies, + control.iam_user_no_inline_attached_policies ] tags = merge(local.rbi_cyber_security_common_tags, { diff --git a/rbi_cyber_security/annex_i_7_4.sp b/rbi_cyber_security/annex_i_7_4.sp index 5af87ee4..043bffab 100644 --- a/rbi_cyber_security/annex_i_7_4.sp +++ b/rbi_cyber_security/annex_i_7_4.sp @@ -16,7 +16,7 @@ benchmark "rbi_cyber_security_annex_i_7_4" { control.s3_bucket_logging_enabled, control.securityhub_enabled, control.vpc_flow_logs_enabled, - control.wafv2_web_acl_logging_enabled, + control.wafv2_web_acl_logging_enabled ] tags = merge(local.rbi_cyber_security_common_tags, {