From b822c19d2ccdabd46a2b9dff9cde7f4c8a74c870 Mon Sep 17 00:00:00 2001 From: Sergio Garcia <38561120+sergargar@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:09:27 +0200 Subject: [PATCH] feat(ignore unused services): add `--ignore-unused-services` argument to ignore findings from services not in actual use (#2936) --- docs/tutorials/ignore-unused-services.md | 70 +++ mkdocs.yml | 1 + .../providers/aws/lib/arguments/arguments.py | 10 + .../aws/lib/audit_info/audit_info.py | 1 + .../providers/aws/lib/audit_info/models.py | 1 + .../accessanalyzer_enabled.py | 13 +- ...accessanalyzer_enabled_without_findings.py | 17 +- .../aws/services/athena/athena_service.py | 121 +++-- .../athena_workgroup_encryption.metadata.json | 2 +- .../athena_workgroup_encryption.py | 28 +- .../athena_workgroup_enforce_configuration.py | 28 +- .../backup_plans_exist/backup_plans_exist.py | 20 +- .../backup_reportplans_exist.py | 2 +- .../cloudtrail_s3_dataevents_read_enabled.py | 23 +- .../cloudtrail_s3_dataevents_write_enabled.py | 22 +- .../ec2_ebs_default_encryption.py | 12 +- .../ec2_networkacl_allow_ingress_any_port.py | 35 +- ...c2_networkacl_allow_ingress_tcp_port_22.py | 35 +- ..._networkacl_allow_ingress_tcp_port_3389.py | 35 +- ...allow_ingress_from_internet_to_any_port.py | 31 +- ...om_internet_to_port_mongodb_27017_27018.py | 43 +- ...ess_from_internet_to_tcp_ftp_port_20_21.py | 43 +- ...ow_ingress_from_internet_to_tcp_port_22.py | 43 +- ..._ingress_from_internet_to_tcp_port_3389.py | 43 +- ...et_to_tcp_port_cassandra_7199_9160_8888.py | 43 +- ...ort_elasticsearch_kibana_9200_9300_5601.py | 43 +- ...ss_from_internet_to_tcp_port_kafka_9092.py | 43 +- ...om_internet_to_tcp_port_memcached_11211.py | 43 +- ...ss_from_internet_to_tcp_port_mysql_3306.py | 47 +- ...m_internet_to_tcp_port_oracle_1521_2483.py | 43 +- ...from_internet_to_tcp_port_postgres_5432.py | 43 +- ...ss_from_internet_to_tcp_port_redis_6379.py | 43 +- ...ternet_to_tcp_port_sql_server_1433_1434.py | 43 +- ...ess_from_internet_to_tcp_port_telnet_23.py | 43 +- ...curitygroup_allow_wide_open_public_ipv4.py | 77 +-- .../providers/aws/services/ec2/ec2_service.py | 13 +- ...connection_passwords_encryption_enabled.py | 26 +- ...ta_catalogs_metadata_encryption_enabled.py | 26 +- .../aws/services/glue/glue_service.py | 6 + .../inspector2_findings_exist.py | 26 +- .../macie_is_enabled/macie_is_enabled.py | 21 +- .../networkfirewall_in_all_vpc.py | 27 +- .../s3_account_level_public_access_blocks.py | 19 +- .../providers/aws/services/s3/s3_service.py | 3 +- ...incidents_enabled_with_plans.metadata.json | 2 +- .../vpc_different_regions.metadata.json | 6 +- .../vpc_flow_logs_enabled.py | 27 +- .../providers/aws/services/vpc/vpc_service.py | 241 +++++---- .../vpc_subnet_different_az.metadata.json | 6 +- ...bnet_separate_private_public.metadata.json | 6 +- prowler/providers/common/audit_info.py | 5 + tests/lib/cli/parser_test.py | 7 + ...sanalyzer_enabled_without_findings_test.py | 46 +- .../athena_workgroup_encryption_test.py | 23 + ...na_workgroup_enforce_configuration_test.py | 23 + .../backup_plans_exist_test.py | 24 +- ...udtrail_s3_dataevents_read_enabled_test.py | 377 ++++++++------ ...dtrail_s3_dataevents_write_enabled_test.py | 377 ++++++++------ .../ec2_ebs_default_encryption_test.py | 62 ++- ..._networkacl_allow_ingress_any_port_test.py | 94 ++++ ...tworkacl_allow_ingress_tcp_port_22_test.py | 94 ++++ ...orkacl_allow_ingress_tcp_port_3389_test.py | 94 ++++ ..._ingress_from_internet_to_any_port_test.py | 86 +++- ...ternet_to_port_mongodb_27017_27018_test.py | 87 +++- ...rom_internet_to_tcp_ftp_port_20_21_test.py | 87 +++- ...gress_from_internet_to_tcp_port_22_test.py | 83 ++- ...ess_from_internet_to_tcp_port_3389_test.py | 83 ++- ..._tcp_port_cassandra_7199_9160_8888_test.py | 87 +++- ...lasticsearch_kibana_9200_9300_5601_test.py | 87 +++- ...om_internet_to_tcp_port_kafka_9092_test.py | 87 +++- ...ternet_to_tcp_port_memcached_11211_test.py | 87 +++- ...om_internet_to_tcp_port_mysql_3306_test.py | 87 +++- ...ernet_to_tcp_port_oracle_1521_2483_test.py | 87 +++- ...internet_to_tcp_port_postgres_5432_test.py | 90 +++- ...om_internet_to_tcp_port_redis_6379_test.py | 84 ++- ...t_to_tcp_port_sql_server_1433_1434_test.py | 87 +++- ...rom_internet_to_tcp_port_telnet_23_test.py | 87 +++- ...gistry_scan_images_on_push_enabled_test.py | 59 ++- ...ositories_lifecycle_policy_enabled_test.py | 55 +- ...positories_not_publicly_accessible_test.py | 55 +- ...tories_scan_images_on_push_enabled_test.py | 55 +- ...an_vulnerabilities_in_latest_image_test.py | 96 +++- ...ction_passwords_encryption_enabled_test.py | 127 ++++- ...talogs_metadata_encryption_enabled_test.py | 124 ++++- .../inspector2_findings_exist_test.py | 483 +++++++++++++++--- .../macie_is_enabled/macie_is_enabled_test.py | 186 ++++++- .../networkfirewall_in_all_vpc_test.py | 145 ++++++ ...account_level_public_access_blocks_test.py | 123 +++-- .../vpc_flow_logs_enabled_test.py | 69 ++- 89 files changed, 4587 insertions(+), 1157 deletions(-) create mode 100644 docs/tutorials/ignore-unused-services.md diff --git a/docs/tutorials/ignore-unused-services.md b/docs/tutorials/ignore-unused-services.md new file mode 100644 index 00000000..c6921e55 --- /dev/null +++ b/docs/tutorials/ignore-unused-services.md @@ -0,0 +1,70 @@ +# Ignore Unused Services + +> Currently only available on the AWS provider. + +Prowler allows you to ignore unused services findings, so you can reduce the number of findings in Prowler's reports. + +```console +prowler --ignore-unused-services +``` + +## Services that can be ignored +### AWS +#### Athena +When you create an AWS Account, Athena will create a default primary workgroup for you. +Prowler will check if that workgroup is enabled and if it is being used by checking if there were queries in the last 45 days. +If not, the findings of the following checks will not appear: + + - `athena_workgroup_encryption` + - `athena_workgroup_enforce_configuration` + +#### CloudTrail +AWS CloudTrail should have at least one trail with a data event to record all S3 object-level API operations, Prowler will check first if there are S3 buckets in your account before alerting this issue. + + - `cloudtrail_s3_dataevents_read_enabled` + - `cloudtrail_s3_dataevents_write_enabled` + +#### EC2 +If EBS default encyption is not enabled, sensitive information at rest is not protected in EC2. But Prowler will only create a finding if there are EBS Volumes where this default configuration could be enforced by default. + + - `ec2_ebs_default_encryption` + +If your Security groups are not properly configured the attack surface is increased, nonetheless, Prowler will detect those security groups that are being used (they are attached) to only notify those that are being used. This logic applies to the 15 checks related to open ports in security groups. + + - `ec2_securitygroup_allow_ingress_from_internet_to_port_X` (15 checks) + +Prowler will also check for used Network ACLs to only alerts those with open ports that are being used. + + - `ec2_networkacl_allow_ingress_X_port` (3 checks) + + +#### Glue +It is a best practice to encrypt both metadata and connection passwords in AWS Glue Data Catalogs, however, Prowler will detect if the service is in use by checking if there are any Data Catalog tables. + + - `glue_data_catalogs_connection_passwords_encryption_enabled` + - `glue_data_catalogs_metadata_encryption_enabled` + +#### Inspector +Amazon Inspector is a vulnerability discovery service that automates continuous scanning for security vulnerabilities within your Amazon EC2, Amazon ECR, and AWS Lambda environments. Prowler recommends to enable it and resolve all the Inspector's findings. Ignoring the unused services, Prowler will only notify you if there are any Lambda functions, EC2 instances or ECR repositories in the region where Amazon inspector should be enabled. + + - `inspector2_findings_exist` + +#### Macie +Amazon Macie is a security service that uses machine learning to automatically discover, classify and protect sensitive data in S3 buckets. Prowler will only create a finding when Macie is not enabled if there are S3 buckets in your account. + + - `macie_is_enabled` + +#### Network Firewall +Without a network firewall, it can be difficult to monitor and control traffic within the VPC. However, Prowler will only alert you for those VPCs that are in use, in other words, only the VPCs where you have ENIs (network interfaces). + + - `networkfirewall_in_all_vpc` + +#### S3 +You should enable Public Access Block at the account level to prevent the exposure of your data stored in S3. Prowler though will only check this block configuration if you have S3 buckets in your AWS account. + + - `s3_account_level_public_access_blocks` + +#### VPC +VPC Flow Logs provide visibility into network traffic that traverses the VPC and can be used to detect anomalous traffic or insight during security workflows. Nevertheless, Prowler will only check if the Flow Logs are enabled for those VPCs that are in use, in other words, only the VPCs where you have ENIs (network interfaces). + + - `vpc_flow_logs_enabled` diff --git a/mkdocs.yml b/mkdocs.yml index c38263df..da63b9fb 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -37,6 +37,7 @@ nav: - Configuration File: tutorials/configuration_file.md - Logging: tutorials/logging.md - Allowlist: tutorials/allowlist.md + - Ignore Unused Services: tutorials/ignore-unused-services.md - Pentesting: tutorials/pentesting.md - Developer Guide: developer-guide/introduction.md - AWS: diff --git a/prowler/providers/aws/lib/arguments/arguments.py b/prowler/providers/aws/lib/arguments/arguments.py index d4365398..b9ba388c 100644 --- a/prowler/providers/aws/lib/arguments/arguments.py +++ b/prowler/providers/aws/lib/arguments/arguments.py @@ -153,6 +153,16 @@ def init_parser(self): help="Set the maximum attemps for the Boto3 standard retrier config (Default: 3)", ) + # Ignore Unused Services + ignore_unused_services_subparser = aws_parser.add_argument_group( + "Ignore Unused Services" + ) + ignore_unused_services_subparser.add_argument( + "--ignore-unused-services", + action="store_true", + help="Ignore findings in unused services", + ) + def validate_session_duration(duration): """validate_session_duration validates that the AWS STS Assume Role Session Duration is between 900 and 43200 seconds.""" diff --git a/prowler/providers/aws/lib/audit_info/audit_info.py b/prowler/providers/aws/lib/audit_info/audit_info.py index bc1b0c5f..908936c0 100644 --- a/prowler/providers/aws/lib/audit_info/audit_info.py +++ b/prowler/providers/aws/lib/audit_info/audit_info.py @@ -37,4 +37,5 @@ current_audit_info = AWS_Audit_Info( organizations_metadata=None, audit_metadata=None, audit_config=None, + ignore_unused_services=False, ) diff --git a/prowler/providers/aws/lib/audit_info/models.py b/prowler/providers/aws/lib/audit_info/models.py index e810833b..838982e3 100644 --- a/prowler/providers/aws/lib/audit_info/models.py +++ b/prowler/providers/aws/lib/audit_info/models.py @@ -52,3 +52,4 @@ class AWS_Audit_Info: organizations_metadata: AWS_Organizations_Info audit_metadata: Optional[Any] = None audit_config: Optional[dict] = None + ignore_unused_services: bool = False diff --git a/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled.py b/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled.py index 897d95f4..608cfe18 100644 --- a/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled.py +++ b/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled.py @@ -10,30 +10,27 @@ class accessanalyzer_enabled(Check): for analyzer in accessanalyzer_client.analyzers: report = Check_Report_AWS(self.metadata()) report.region = analyzer.region + report.resource_id = analyzer.name + report.resource_arn = analyzer.arn + report.resource_tags = analyzer.tags if analyzer.status == "ACTIVE": report.status = "PASS" report.status_extended = ( f"IAM Access Analyzer {analyzer.name} is enabled." ) - report.resource_id = analyzer.name - report.resource_arn = analyzer.arn - report.resource_tags = analyzer.tags elif analyzer.status == "NOT_AVAILABLE": report.status = "FAIL" report.status_extended = ( f"IAM Access Analyzer in account {analyzer.name} is not enabled." ) - report.resource_id = analyzer.name - report.resource_arn = analyzer.arn + else: report.status = "FAIL" report.status_extended = ( f"IAM Access Analyzer {analyzer.name} is not active." ) - report.resource_id = analyzer.name - report.resource_arn = analyzer.arn - report.resource_tags = analyzer.tags + findings.append(report) return findings diff --git a/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings.py b/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings.py index b4d58602..07490225 100644 --- a/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings.py +++ b/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings.py @@ -28,21 +28,6 @@ class accessanalyzer_enabled_without_findings(Check): report.resource_id = analyzer.name report.resource_arn = analyzer.arn report.resource_tags = analyzer.tags - elif analyzer.status == "NOT_AVAILABLE": - report.status = "FAIL" - report.status_extended = ( - f"IAM Access Analyzer in account {analyzer.name} is not enabled." - ) - report.resource_id = analyzer.name - report.resource_arn = analyzer.arn - else: - report.status = "FAIL" - report.status_extended = ( - f"IAM Access Analyzer {analyzer.name} is not active." - ) - report.resource_id = analyzer.name - report.resource_arn = analyzer.arn - report.resource_tags = analyzer.tags - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/athena/athena_service.py b/prowler/providers/aws/services/athena/athena_service.py index 1092e0d3..ec91dc1b 100644 --- a/prowler/providers/aws/services/athena/athena_service.py +++ b/prowler/providers/aws/services/athena/athena_service.py @@ -15,6 +15,7 @@ class Athena(AWSService): self.workgroups = {} self.__threading_call__(self.__list_workgroups__) self.__get_workgroups__() + self.__list_query_executions__() self.__list_tags_for_resource__() def __list_workgroups__(self, regional_client): @@ -22,17 +23,22 @@ class Athena(AWSService): try: list_workgroups = regional_client.list_work_groups() for workgroup in list_workgroups["WorkGroups"]: - workgroup_name = workgroup["Name"] - workgroup_arn = f"arn:{self.audited_partition}:athena:{regional_client.region}:{self.audited_account}:workgroup/{workgroup_name}" - if not self.audit_resources or ( - is_resource_filtered(workgroup_arn, self.audit_resources) - ): - self.workgroups[workgroup_arn] = WorkGroup( - arn=workgroup_arn, - name=workgroup_name, - region=regional_client.region, + try: + workgroup_name = workgroup["Name"] + workgroup_arn = f"arn:{self.audited_partition}:athena:{regional_client.region}:{self.audited_account}:workgroup/{workgroup_name}" + if not self.audit_resources or ( + is_resource_filtered(workgroup_arn, self.audit_resources) + ): + self.workgroups[workgroup_arn] = WorkGroup( + arn=workgroup_arn, + name=workgroup_name, + state=workgroup["State"], + region=regional_client.region, + ) + except Exception as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - except Exception as error: logger.error( f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -42,38 +48,64 @@ class Athena(AWSService): logger.info("Athena - Getting WorkGroups...") try: for workgroup in self.workgroups.values(): - wg = self.regional_clients[workgroup.region].get_work_group( - WorkGroup=workgroup.name - ) - - wg_configuration = wg.get("WorkGroup").get("Configuration") - self.workgroups[ - workgroup.arn - ].enforce_workgroup_configuration = wg_configuration.get( - "EnforceWorkGroupConfiguration", False - ) - - # We include an empty EncryptionConfiguration to handle if the workgroup does not have encryption configured - encryption = ( - wg_configuration.get( - "ResultConfiguration", - {"EncryptionConfiguration": {}}, + try: + wg = self.regional_clients[workgroup.region].get_work_group( + WorkGroup=workgroup.name ) - .get( - "EncryptionConfiguration", - {"EncryptionOption": ""}, - ) - .get("EncryptionOption") - ) - if encryption in ["SSE_S3", "SSE_KMS", "CSE_KMS"]: - encryption_configuration = EncryptionConfiguration( - encryption_option=encryption, encrypted=True - ) + wg_configuration = wg.get("WorkGroup").get("Configuration") self.workgroups[ workgroup.arn - ].encryption_configuration = encryption_configuration + ].enforce_workgroup_configuration = wg_configuration.get( + "EnforceWorkGroupConfiguration", False + ) + # We include an empty EncryptionConfiguration to handle if the workgroup does not have encryption configured + encryption = ( + wg_configuration.get( + "ResultConfiguration", + {"EncryptionConfiguration": {}}, + ) + .get( + "EncryptionConfiguration", + {"EncryptionOption": ""}, + ) + .get("EncryptionOption") + ) + + if encryption in ["SSE_S3", "SSE_KMS", "CSE_KMS"]: + encryption_configuration = EncryptionConfiguration( + encryption_option=encryption, encrypted=True + ) + self.workgroups[ + workgroup.arn + ].encryption_configuration = encryption_configuration + except Exception as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + + except Exception as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + + def __list_query_executions__(self): + logger.info("Athena - Listing Queries...") + try: + for workgroup in self.workgroups.values(): + try: + queries = ( + self.regional_clients[workgroup.region] + .list_query_executions(WorkGroup=workgroup.name) + .get("QueryExecutionIds", []) + ) + if queries: + workgroup.queries = True + except Exception as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) except Exception as error: logger.error( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -83,10 +115,15 @@ class Athena(AWSService): logger.info("Athena - Listing Tags...") try: for workgroup in self.workgroups.values(): - regional_client = self.regional_clients[workgroup.region] - workgroup.tags = regional_client.list_tags_for_resource( - ResourceARN=workgroup.arn - )["Tags"] + try: + regional_client = self.regional_clients[workgroup.region] + workgroup.tags = regional_client.list_tags_for_resource( + ResourceARN=workgroup.arn + )["Tags"] + except Exception as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) except Exception as error: logger.error( f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -101,9 +138,11 @@ class EncryptionConfiguration(BaseModel): class WorkGroup(BaseModel): arn: str name: str + state: str encryption_configuration: EncryptionConfiguration = EncryptionConfiguration( encryption_option="", encrypted=False ) enforce_workgroup_configuration: bool = False + queries: bool = False region: str tags: Optional[list] = [] diff --git a/prowler/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption.metadata.json b/prowler/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption.metadata.json index 105a1085..2b1f0703 100644 --- a/prowler/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption.metadata.json +++ b/prowler/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption.metadata.json @@ -8,7 +8,7 @@ "ServiceName": "athena", "SubServiceName": "", "ResourceIdTemplate": "arn:partition:athena:region:account-id:workgroup/resource-id", - "Severity": "high", + "Severity": "medium", "ResourceType": "WorkGroup", "Description": "Ensure that encryption at rest is enabled for Amazon Athena query results stored in Amazon S3 in order to secure data and meet compliance requirements for data-at-rest encryption.", "Risk": "If not enabled sensitive information at rest is not protected.", diff --git a/prowler/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption.py b/prowler/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption.py index 7bf98ced..8b67d2d6 100644 --- a/prowler/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption.py +++ b/prowler/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption.py @@ -9,19 +9,23 @@ class athena_workgroup_encryption(Check): """Execute the athena_workgroup_encryption check""" findings = [] for workgroup in athena_client.workgroups.values(): - report = Check_Report_AWS(self.metadata()) - report.region = workgroup.region - report.resource_id = workgroup.name - report.resource_arn = workgroup.arn - report.resource_tags = workgroup.tags + # Only check for enabled and used workgroups (has recent queries) + if ( + workgroup.state == "ENABLED" and workgroup.queries + ) or not athena_client.audit_info.ignore_unused_services: + report = Check_Report_AWS(self.metadata()) + report.region = workgroup.region + report.resource_id = workgroup.name + report.resource_arn = workgroup.arn + report.resource_tags = workgroup.tags - if workgroup.encryption_configuration.encrypted: - report.status = "PASS" - report.status_extended = f"Athena WorkGroup {workgroup.name} encrypts the query results using {workgroup.encryption_configuration.encryption_option}." - else: - report.status = "FAIL" - report.status_extended = f"Athena WorkGroup {workgroup.name} does not encrypt the query results." + if workgroup.encryption_configuration.encrypted: + report.status = "PASS" + report.status_extended = f"Athena WorkGroup {workgroup.name} encrypts the query results using {workgroup.encryption_configuration.encryption_option}." + else: + report.status = "FAIL" + report.status_extended = f"Athena WorkGroup {workgroup.name} does not encrypt the query results." - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/athena/athena_workgroup_enforce_configuration/athena_workgroup_enforce_configuration.py b/prowler/providers/aws/services/athena/athena_workgroup_enforce_configuration/athena_workgroup_enforce_configuration.py index 42fd7011..3fa94a57 100644 --- a/prowler/providers/aws/services/athena/athena_workgroup_enforce_configuration/athena_workgroup_enforce_configuration.py +++ b/prowler/providers/aws/services/athena/athena_workgroup_enforce_configuration/athena_workgroup_enforce_configuration.py @@ -9,19 +9,23 @@ class athena_workgroup_enforce_configuration(Check): """Execute the athena_workgroup_enforce_configuration check""" findings = [] for workgroup in athena_client.workgroups.values(): - report = Check_Report_AWS(self.metadata()) - report.region = workgroup.region - report.resource_id = workgroup.name - report.resource_arn = workgroup.arn - report.resource_tags = workgroup.tags + # Only check for enabled and used workgroups (has recent queries) + if ( + workgroup.state == "ENABLED" and workgroup.queries + ) or not athena_client.audit_info.ignore_unused_services: + report = Check_Report_AWS(self.metadata()) + report.region = workgroup.region + report.resource_id = workgroup.name + report.resource_arn = workgroup.arn + report.resource_tags = workgroup.tags - if workgroup.enforce_workgroup_configuration: - report.status = "PASS" - report.status_extended = f"Athena WorkGroup {workgroup.name} enforces the workgroup configuration, so it cannot be overridden by the client-side settings." - else: - report.status = "FAIL" - report.status_extended = f"Athena WorkGroup {workgroup.name} does not enforce the workgroup configuration, so it can be overridden by the client-side settings." + if workgroup.enforce_workgroup_configuration: + report.status = "PASS" + report.status_extended = f"Athena WorkGroup {workgroup.name} enforces the workgroup configuration, so it cannot be overridden by the client-side settings." + else: + report.status = "FAIL" + report.status_extended = f"Athena WorkGroup {workgroup.name} does not enforce the workgroup configuration, so it can be overridden by the client-side settings." - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/backup/backup_plans_exist/backup_plans_exist.py b/prowler/providers/aws/services/backup/backup_plans_exist/backup_plans_exist.py index f115a181..e2b6e4f8 100644 --- a/prowler/providers/aws/services/backup/backup_plans_exist/backup_plans_exist.py +++ b/prowler/providers/aws/services/backup/backup_plans_exist/backup_plans_exist.py @@ -5,18 +5,20 @@ from prowler.providers.aws.services.backup.backup_client import backup_client class backup_plans_exist(Check): def execute(self): findings = [] - report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = "No Backup Plan exist." - report.resource_arn = backup_client.audited_account_arn - report.resource_id = backup_client.audited_account - report.region = backup_client.region if backup_client.backup_plans: + report = Check_Report_AWS(self.metadata()) report.status = "PASS" - report.status_extended = f"At least one backup plan exists: {backup_client.backup_plans[0].name}." + report.status_extended = f"At least one Backup Plan exists: {backup_client.backup_plans[0].name}." report.resource_arn = backup_client.backup_plans[0].arn report.resource_id = backup_client.backup_plans[0].name report.region = backup_client.backup_plans[0].region - - findings.append(report) + findings.append(report) + elif backup_client.backup_vaults: + report = Check_Report_AWS(self.metadata()) + report.status = "FAIL" + report.status_extended = "No Backup Plan exist." + report.resource_arn = backup_client.audited_account_arn + report.resource_id = backup_client.audited_account + report.region = backup_client.region + findings.append(report) return findings diff --git a/prowler/providers/aws/services/backup/backup_reportplans_exist/backup_reportplans_exist.py b/prowler/providers/aws/services/backup/backup_reportplans_exist/backup_reportplans_exist.py index 41ffcf3a..9870b90b 100644 --- a/prowler/providers/aws/services/backup/backup_reportplans_exist/backup_reportplans_exist.py +++ b/prowler/providers/aws/services/backup/backup_reportplans_exist/backup_reportplans_exist.py @@ -5,7 +5,7 @@ from prowler.providers.aws.services.backup.backup_client import backup_client class backup_reportplans_exist(Check): def execute(self): findings = [] - # We only check report plans if backup plans exist, reducing noise + # We only check report plans if backup plans exist if backup_client.backup_plans: report = Check_Report_AWS(self.metadata()) report.status = "FAIL" diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled.py index a46a6e7b..6b63bd49 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled.py @@ -2,17 +2,12 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.cloudtrail.cloudtrail_client import ( cloudtrail_client, ) +from prowler.providers.aws.services.s3.s3_client import s3_client class cloudtrail_s3_dataevents_read_enabled(Check): def execute(self): findings = [] - report = Check_Report_AWS(self.metadata()) - report.region = cloudtrail_client.region - report.resource_arn = cloudtrail_client.audited_account_arn - report.resource_id = cloudtrail_client.audited_account - report.status = "FAIL" - report.status_extended = "No CloudTrail trails have a data event to record all S3 object-level API operations." for trail in cloudtrail_client.trails: for data_event in trail.data_events: # classic event selectors @@ -31,12 +26,14 @@ class cloudtrail_s3_dataevents_read_enabled(Check): or f"arn:{cloudtrail_client.audited_partition}:s3:::*/*" in resource["Values"] ): + report = Check_Report_AWS(self.metadata()) report.region = trail.region report.resource_id = trail.name report.resource_arn = trail.arn report.resource_tags = trail.tags report.status = "PASS" report.status_extended = f"Trail {trail.name} from home region {trail.home_region} has a classic data event selector to record all S3 object-level API operations." + findings.append(report) # advanced event selectors elif data_event.is_advanced: for field_selector in data_event.event_selector["FieldSelectors"]: @@ -44,12 +41,22 @@ class cloudtrail_s3_dataevents_read_enabled(Check): field_selector["Field"] == "resources.type" and field_selector["Equals"][0] == "AWS::S3::Object" ): + report = Check_Report_AWS(self.metadata()) report.region = trail.region report.resource_id = trail.name report.resource_arn = trail.arn report.resource_tags = trail.tags report.status = "PASS" report.status_extended = f"Trail {trail.name} from home region {trail.home_region} has an advanced data event selector to record all S3 object-level API operations." - - findings.append(report) + findings.append(report) + if not findings and ( + s3_client.buckets or not cloudtrail_client.audit_info.ignore_unused_services + ): + report = Check_Report_AWS(self.metadata()) + report.region = cloudtrail_client.region + report.resource_arn = cloudtrail_client.audited_account_arn + report.resource_id = cloudtrail_client.audited_account + report.status = "FAIL" + report.status_extended = "No CloudTrail trails have a data event to record all S3 object-level API operations." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled.py index 9a07c1f2..425f78f8 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled.py @@ -2,17 +2,12 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.cloudtrail.cloudtrail_client import ( cloudtrail_client, ) +from prowler.providers.aws.services.s3.s3_client import s3_client class cloudtrail_s3_dataevents_write_enabled(Check): def execute(self): findings = [] - report = Check_Report_AWS(self.metadata()) - report.region = cloudtrail_client.region - report.resource_arn = cloudtrail_client.audited_account_arn - report.resource_id = cloudtrail_client.audited_account - report.status = "FAIL" - report.status_extended = "No CloudTrail trails have a data event to record all S3 object-level API operations." for trail in cloudtrail_client.trails: for data_event in trail.data_events: # Classic event selectors @@ -31,12 +26,14 @@ class cloudtrail_s3_dataevents_write_enabled(Check): or f"arn:{cloudtrail_client.audited_partition}:s3:::*/*" in resource["Values"] ): + report = Check_Report_AWS(self.metadata()) report.region = trail.region report.resource_id = trail.name report.resource_arn = trail.arn report.resource_tags = trail.tags report.status = "PASS" report.status_extended = f"Trail {trail.name} from home region {trail.home_region} has a classic data event selector to record all S3 object-level API operations." + findings.append(report) # Advanced event selectors elif data_event.is_advanced: for field_selector in data_event.event_selector["FieldSelectors"]: @@ -44,11 +41,22 @@ class cloudtrail_s3_dataevents_write_enabled(Check): field_selector["Field"] == "resources.type" and field_selector["Equals"][0] == "AWS::S3::Object" ): + report = Check_Report_AWS(self.metadata()) report.region = trail.region report.resource_id = trail.name report.resource_arn = trail.arn report.resource_tags = trail.tags report.status = "PASS" report.status_extended = f"Trail {trail.name} from home region {trail.home_region} has an advanced data event selector to record all S3 object-level API operations." - findings.append(report) + findings.append(report) + if not findings and ( + s3_client.buckets or not cloudtrail_client.audit_info.ignore_unused_services + ): + report = Check_Report_AWS(self.metadata()) + report.region = cloudtrail_client.region + report.resource_arn = cloudtrail_client.audited_account_arn + report.resource_id = cloudtrail_client.audited_account + report.status = "FAIL" + report.status_extended = "No CloudTrail trails have a data event to record all S3 object-level API operations." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_ebs_default_encryption/ec2_ebs_default_encryption.py b/prowler/providers/aws/services/ec2/ec2_ebs_default_encryption/ec2_ebs_default_encryption.py index 1900853b..a208d1ff 100644 --- a/prowler/providers/aws/services/ec2/ec2_ebs_default_encryption/ec2_ebs_default_encryption.py +++ b/prowler/providers/aws/services/ec2/ec2_ebs_default_encryption/ec2_ebs_default_encryption.py @@ -10,12 +10,16 @@ class ec2_ebs_default_encryption(Check): report.region = ebs_encryption.region report.resource_arn = ec2_client.audited_account_arn report.resource_id = ec2_client.audited_account - report.status = "FAIL" - report.status_extended = "EBS Default Encryption is not activated." if ebs_encryption.status: report.status = "PASS" report.status_extended = "EBS Default Encryption is activated." - - findings.append(report) + findings.append(report) + elif ( + not ec2_client.audit_info.ignore_unused_services + or ebs_encryption.volumes + ): + report.status = "FAIL" + report.status_extended = "EBS Default Encryption is not activated." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_any_port/ec2_networkacl_allow_ingress_any_port.py b/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_any_port/ec2_networkacl_allow_ingress_any_port.py index 4df7961b..224b1e8d 100644 --- a/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_any_port/ec2_networkacl_allow_ingress_any_port.py +++ b/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_any_port/ec2_networkacl_allow_ingress_any_port.py @@ -9,17 +9,28 @@ class ec2_networkacl_allow_ingress_any_port(Check): tcp_protocol = "-1" check_port = 0 for network_acl in ec2_client.network_acls: - report = Check_Report_AWS(self.metadata()) - report.region = network_acl.region - report.resource_id = network_acl.id - report.resource_arn = network_acl.arn - report.resource_tags = network_acl.tags - report.status = "PASS" - report.status_extended = f"Network ACL {network_acl.name if network_acl.name else network_acl.id} does not have every port open to the Internet." - # If some entry allows it, that ACL is not securely configured - if check_network_acl(network_acl.entries, tcp_protocol, check_port): - report.status = "FAIL" - report.status_extended = f"Network ACL {network_acl.name if network_acl.name else network_acl.id} has every port open to the Internet." - findings.append(report) + if ( + not ec2_client.audit_info.ignore_unused_services + or network_acl.region in ec2_client.regions_with_sgs + ): + # If some entry allows it, that ACL is not securely configured + if check_network_acl(network_acl.entries, tcp_protocol, check_port): + report = Check_Report_AWS(self.metadata()) + report.resource_id = network_acl.id + report.region = network_acl.region + report.resource_arn = network_acl.arn + report.resource_tags = network_acl.tags + report.status = "FAIL" + report.status_extended = f"Network ACL {network_acl.name if network_acl.name else network_acl.id} has every port open to the Internet." + findings.append(report) + else: + report = Check_Report_AWS(self.metadata()) + report.resource_id = network_acl.id + report.region = network_acl.region + report.resource_arn = network_acl.arn + report.resource_tags = network_acl.tags + report.status = "PASS" + report.status_extended = f"Network ACL {network_acl.name if network_acl.name else network_acl.id} does not have every port open to the Internet." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_22/ec2_networkacl_allow_ingress_tcp_port_22.py b/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_22/ec2_networkacl_allow_ingress_tcp_port_22.py index 883c348e..272b07de 100644 --- a/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_22/ec2_networkacl_allow_ingress_tcp_port_22.py +++ b/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_22/ec2_networkacl_allow_ingress_tcp_port_22.py @@ -9,17 +9,28 @@ class ec2_networkacl_allow_ingress_tcp_port_22(Check): tcp_protocol = "6" check_port = 22 for network_acl in ec2_client.network_acls: - report = Check_Report_AWS(self.metadata()) - report.region = network_acl.region - report.resource_arn = network_acl.arn - report.resource_tags = network_acl.tags - report.status = "PASS" - report.status_extended = f"Network ACL {network_acl.name if network_acl.name else network_acl.id} does not have SSH port 22 open to the Internet." - report.resource_id = network_acl.id - # If some entry allows it, that ACL is not securely configured - if check_network_acl(network_acl.entries, tcp_protocol, check_port): - report.status = "FAIL" - report.status_extended = f"Network ACL {network_acl.name if network_acl.name else network_acl.id} has SSH port 22 open to the Internet." - findings.append(report) + if ( + not ec2_client.audit_info.ignore_unused_services + or network_acl.region in ec2_client.regions_with_sgs + ): + # If some entry allows it, that ACL is not securely configured + if check_network_acl(network_acl.entries, tcp_protocol, check_port): + report = Check_Report_AWS(self.metadata()) + report.resource_id = network_acl.id + report.region = network_acl.region + report.resource_arn = network_acl.arn + report.resource_tags = network_acl.tags + report.status = "FAIL" + report.status_extended = f"Network ACL {network_acl.name if network_acl.name else network_acl.id} has SSH port 22 open to the Internet." + findings.append(report) + else: + report = Check_Report_AWS(self.metadata()) + report.resource_id = network_acl.id + report.region = network_acl.region + report.resource_arn = network_acl.arn + report.resource_tags = network_acl.tags + report.status = "PASS" + report.status_extended = f"Network ACL {network_acl.name if network_acl.name else network_acl.id} does not have SSH port 22 open to the Internet." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_3389/ec2_networkacl_allow_ingress_tcp_port_3389.py b/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_3389/ec2_networkacl_allow_ingress_tcp_port_3389.py index 9ea10684..148e3c89 100644 --- a/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_3389/ec2_networkacl_allow_ingress_tcp_port_3389.py +++ b/prowler/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_3389/ec2_networkacl_allow_ingress_tcp_port_3389.py @@ -9,17 +9,28 @@ class ec2_networkacl_allow_ingress_tcp_port_3389(Check): tcp_protocol = "6" check_port = 3389 for network_acl in ec2_client.network_acls: - report = Check_Report_AWS(self.metadata()) - report.region = network_acl.region - report.resource_arn = network_acl.arn - report.resource_tags = network_acl.tags - report.status = "PASS" - report.status_extended = f"Network ACL {network_acl.name if network_acl.name else network_acl.id} does not have Microsoft RDP port 3389 open to the Internet." - report.resource_id = network_acl.id - # If some entry allows it, that ACL is not securely configured - if check_network_acl(network_acl.entries, tcp_protocol, check_port): - report.status = "FAIL" - report.status_extended = f"Network ACL {network_acl.name if network_acl.name else network_acl.id} has Microsoft RDP port 3389 open to the Internet." - findings.append(report) + if ( + not ec2_client.audit_info.ignore_unused_services + or network_acl.region in ec2_client.regions_with_sgs + ): + # If some entry allows it, that ACL is not securely configured + if check_network_acl(network_acl.entries, tcp_protocol, check_port): + report = Check_Report_AWS(self.metadata()) + report.resource_id = network_acl.id + report.region = network_acl.region + report.resource_arn = network_acl.arn + report.resource_tags = network_acl.tags + report.status = "FAIL" + report.status_extended = f"Network ACL {network_acl.name if network_acl.name else network_acl.id} has Microsoft RDP port 3389 open to the Internet." + findings.append(report) + else: + report = Check_Report_AWS(self.metadata()) + report.resource_id = network_acl.id + report.region = network_acl.region + report.resource_arn = network_acl.arn + report.resource_tags = network_acl.tags + report.status = "PASS" + report.status_extended = f"Network ACL {network_acl.name if network_acl.name else network_acl.id} does not have Microsoft RDP port 3389 open to the Internet." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_any_port/ec2_securitygroup_allow_ingress_from_internet_to_any_port.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_any_port/ec2_securitygroup_allow_ingress_from_internet_to_any_port.py index be416f1d..309caef3 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_any_port/ec2_securitygroup_allow_ingress_from_internet_to_any_port.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_any_port/ec2_securitygroup_allow_ingress_from_internet_to_any_port.py @@ -1,22 +1,29 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_any_port(Check): def execute(self): findings = [] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have all ports open to the Internet." - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - if security_group.public_ports: - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has all ports open to the Internet." - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have all ports open to the Internet." + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + if security_group.public_ports: + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has all ports open to the Internet." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.py index 145586e9..160a6eaa 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.py @@ -1,6 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018(Check): @@ -8,23 +9,29 @@ class ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018( findings = [] check_ports = [27017, 27018] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have MongoDB ports 27017 and 27018 open to the Internet." - if not security_group.public_ports: - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - if check_security_group( - ingress_rule, "tcp", check_ports, any_address=True - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has MongoDB ports 27017 and 27018 open to the Internet." - break - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have MongoDB ports 27017 and 27018 open to the Internet." + if not security_group.public_ports: + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + if check_security_group( + ingress_rule, "tcp", check_ports, any_address=True + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has MongoDB ports 27017 and 27018 open to the Internet." + break + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.py index 7d0159be..80c2677b 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.py @@ -1,6 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21(Check): @@ -8,23 +9,29 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21(Check) findings = [] check_ports = [20, 21] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have FTP ports 20 and 21 open to the Internet." - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - if not security_group.public_ports: - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - if check_security_group( - ingress_rule, "tcp", check_ports, any_address=True - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has FTP ports 20 and 21 open to the Internet." - break - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have FTP ports 20 and 21 open to the Internet." + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + if not security_group.public_ports: + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + if check_security_group( + ingress_rule, "tcp", check_ports, any_address=True + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has FTP ports 20 and 21 open to the Internet." + break + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.py index c1bec4a8..0a2ecc35 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.py @@ -1,6 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22(Check): @@ -8,23 +9,29 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22(Check): findings = [] check_ports = [22] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have SSH port 22 open to the Internet." - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - if not security_group.public_ports: - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - if check_security_group( - ingress_rule, "tcp", check_ports, any_address=True - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has SSH port 22 open to the Internet." - break - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have SSH port 22 open to the Internet." + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + if not security_group.public_ports: + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + if check_security_group( + ingress_rule, "tcp", check_ports, any_address=True + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has SSH port 22 open to the Internet." + break + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.py index 48ab7cb3..b9ae1fa2 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.py @@ -1,6 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389(Check): @@ -8,23 +9,29 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389(Check): findings = [] check_ports = [3389] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Microsoft RDP port 3389 open to the Internet." - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - if not security_group.public_ports: - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - if check_security_group( - ingress_rule, "tcp", check_ports, any_address=True - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Microsoft RDP port 3389 open to the Internet." - break - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Microsoft RDP port 3389 open to the Internet." + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + if not security_group.public_ports: + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + if check_security_group( + ingress_rule, "tcp", check_ports, any_address=True + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Microsoft RDP port 3389 open to the Internet." + break + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.py index cdc236d2..67b6d10f 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.py @@ -1,6 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888( @@ -10,23 +11,29 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9 findings = [] check_ports = [7199, 9160, 8888] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Casandra ports 7199, 8888 and 9160 open to the Internet." - if not security_group.public_ports: - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - if check_security_group( - ingress_rule, "tcp", check_ports, any_address=True - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Casandra ports 7199, 8888 and 9160 open to the Internet." - break - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Casandra ports 7199, 8888 and 9160 open to the Internet." + if not security_group.public_ports: + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + if check_security_group( + ingress_rule, "tcp", check_ports, any_address=True + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Casandra ports 7199, 8888 and 9160 open to the Internet." + break + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.py index 5527be8d..f726df6a 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.py @@ -1,6 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601( @@ -10,23 +11,29 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_ki findings = [] check_ports = [9200, 9300, 5601] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Elasticsearch/Kibana ports 9200, 9300 and 5601 open to the Internet." - if not security_group.public_ports: - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - if check_security_group( - ingress_rule, "tcp", check_ports, any_address=True - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Elasticsearch/Kibana ports 9200, 9300 and 5601 open to the Internet." - break - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Elasticsearch/Kibana ports 9200, 9300 and 5601 open to the Internet." + if not security_group.public_ports: + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + if check_security_group( + ingress_rule, "tcp", check_ports, any_address=True + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Elasticsearch/Kibana ports 9200, 9300 and 5601 open to the Internet." + break + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.py index 5b8bc7a9..7ce02df9 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.py @@ -1,6 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092(Check): @@ -8,23 +9,29 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092(Check findings = [] check_ports = [9092] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Kafka port 9092 open to the Internet." - if not security_group.public_ports: - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - if check_security_group( - ingress_rule, "tcp", check_ports, any_address=True - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Kafka port 9092 open to the Internet." - break - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Kafka port 9092 open to the Internet." + if not security_group.public_ports: + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + if check_security_group( + ingress_rule, "tcp", check_ports, any_address=True + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Kafka port 9092 open to the Internet." + break + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.py index 23c9ad3a..6266d2d2 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.py @@ -1,6 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211(Check): @@ -8,23 +9,29 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211( findings = [] check_ports = [11211] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Memcached port 11211 open to the Internet." - if not security_group.public_ports: - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - if check_security_group( - ingress_rule, "tcp", check_ports, any_address=True - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Memcached port 11211 open to the Internet." - break - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Memcached port 11211 open to the Internet." + if not security_group.public_ports: + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + if check_security_group( + ingress_rule, "tcp", check_ports, any_address=True + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Memcached port 11211 open to the Internet." + break + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.py index 30092195..eaca5d6a 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.py @@ -1,6 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306(Check): @@ -8,25 +9,31 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306(Check findings = [] check_ports = [3306] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have MySQL port 3306 open to the Internet." - if not security_group.public_ports: - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - if check_security_group( - ingress_rule, "tcp", check_ports, any_address=True - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has MySQL port 3306 open to the Internet." - report.resource_details = security_group.name - report.resource_id = security_group.id - break - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have MySQL port 3306 open to the Internet." + if not security_group.public_ports: + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + if check_security_group( + ingress_rule, "tcp", check_ports, any_address=True + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has MySQL port 3306 open to the Internet." + report.resource_details = security_group.name + report.resource_id = security_group.id + break + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.py index 154575ef..f51709a0 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.py @@ -1,6 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483(Check): @@ -8,23 +9,29 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483 findings = [] check_ports = [1521, 2483] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Oracle ports 1521 and 2483 open to the Internet." - if not security_group.public_ports: - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - if check_security_group( - ingress_rule, "tcp", check_ports, any_address=True - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Oracle ports 1521 and 2483 open to the Internet." - break - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Oracle ports 1521 and 2483 open to the Internet." + if not security_group.public_ports: + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + if check_security_group( + ingress_rule, "tcp", check_ports, any_address=True + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Oracle ports 1521 and 2483 open to the Internet." + break + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.py index d107fc15..b1043d8b 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.py @@ -1,6 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432(Check): @@ -8,23 +9,29 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432(Ch findings = [] check_ports = [5432] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Postgres port 5432 open to the Internet." - if not security_group.public_ports: - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - if check_security_group( - ingress_rule, "tcp", check_ports, any_address=True - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Postgres port 5432 open to the Internet." - break - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Postgres port 5432 open to the Internet." + if not security_group.public_ports: + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + if check_security_group( + ingress_rule, "tcp", check_ports, any_address=True + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Postgres port 5432 open to the Internet." + break + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.py index e574240d..e9c7a3f1 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.py @@ -1,6 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379(Check): @@ -8,23 +9,29 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379(Check findings = [] check_ports = [6379] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Redis port 6379 open to the Internet." - if not security_group.public_ports: - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - if check_security_group( - ingress_rule, "tcp", check_ports, any_address=True - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Redis port 6379 open to the Internet." - break - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Redis port 6379 open to the Internet." + if not security_group.public_ports: + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + if check_security_group( + ingress_rule, "tcp", check_ports, any_address=True + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Redis port 6379 open to the Internet." + break + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.py index 82e45ed3..564af090 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.py @@ -1,6 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434( @@ -10,23 +11,29 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_ findings = [] check_ports = [1433, 1434] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Microsoft SQL Server ports 1433 and 1434 open to the Internet." - if not security_group.public_ports: - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - if check_security_group( - ingress_rule, "tcp", check_ports, any_address=True - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Microsoft SQL Server ports 1433 and 1434 open to the Internet." - break - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Microsoft SQL Server ports 1433 and 1434 open to the Internet." + if not security_group.public_ports: + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + if check_security_group( + ingress_rule, "tcp", check_ports, any_address=True + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Microsoft SQL Server ports 1433 and 1434 open to the Internet." + break + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.py index 2e4d466b..e1fabd45 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.py @@ -1,6 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client from prowler.providers.aws.services.ec2.lib.security_groups import check_security_group +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23(Check): @@ -8,23 +9,29 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23(Check) findings = [] check_ports = [23] for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Telnet port 23 open to the Internet." - if not security_group.public_ports: - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - if check_security_group( - ingress_rule, "tcp", check_ports, any_address=True - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Telnet port 23 open to the Internet." - break - findings.append(report) + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) does not have Telnet port 23 open to the Internet." + if not security_group.public_ports: + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + if check_security_group( + ingress_rule, "tcp", check_ports, any_address=True + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has Telnet port 23 open to the Internet." + break + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_wide_open_public_ipv4/ec2_securitygroup_allow_wide_open_public_ipv4.py b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_wide_open_public_ipv4/ec2_securitygroup_allow_wide_open_public_ipv4.py index 3a799793..625da3a7 100644 --- a/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_wide_open_public_ipv4/ec2_securitygroup_allow_wide_open_public_ipv4.py +++ b/prowler/providers/aws/services/ec2/ec2_securitygroup_allow_wide_open_public_ipv4/ec2_securitygroup_allow_wide_open_public_ipv4.py @@ -2,6 +2,7 @@ import ipaddress from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.ec2.ec2_client import ec2_client +from prowler.providers.aws.services.vpc.vpc_client import vpc_client class ec2_securitygroup_allow_wide_open_public_ipv4(Check): @@ -9,42 +10,48 @@ class ec2_securitygroup_allow_wide_open_public_ipv4(Check): findings = [] cidr_treshold = 24 for security_group in ec2_client.security_groups: - report = Check_Report_AWS(self.metadata()) - report.region = security_group.region - report.resource_details = security_group.name - report.resource_id = security_group.id - report.resource_arn = security_group.arn - report.resource_tags = security_group.tags - report.status = "PASS" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has no potential wide-open non-RFC1918 address." - # Loop through every security group's ingress rule and check it - for ingress_rule in security_group.ingress_rules: - for ipv4 in ingress_rule["IpRanges"]: - ip = ipaddress.ip_network(ipv4["CidrIp"]) - # Check if IP is public according to RFC1918 and if 0 < prefixlen < 24 - if ( - ip.is_global - and ip.prefixlen < cidr_treshold - and ip.prefixlen > 0 - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has potential wide-open non-RFC1918 address {ipv4['CidrIp']} in ingress rule." - break + # Check if ignoring flag is set and if the VPC and the SG is in use + if not ec2_client.audit_info.ignore_unused_services or ( + security_group.vpc_id in vpc_client.vpcs + and vpc_client.vpcs[security_group.vpc_id].in_use + and len(security_group.network_interfaces) > 0 + ): + report = Check_Report_AWS(self.metadata()) + report.region = security_group.region + report.resource_details = security_group.name + report.resource_id = security_group.id + report.resource_arn = security_group.arn + report.resource_tags = security_group.tags + report.status = "PASS" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has no potential wide-open non-RFC1918 address." + # Loop through every security group's ingress rule and check it + for ingress_rule in security_group.ingress_rules: + for ipv4 in ingress_rule["IpRanges"]: + ip = ipaddress.ip_network(ipv4["CidrIp"]) + # Check if IP is public according to RFC1918 and if 0 < prefixlen < 24 + if ( + ip.is_global + and ip.prefixlen < cidr_treshold + and ip.prefixlen > 0 + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has potential wide-open non-RFC1918 address {ipv4['CidrIp']} in ingress rule." + break - # Loop through every security group's egress rule and check it - for egress_rule in security_group.egress_rules: - for ipv4 in egress_rule["IpRanges"]: - ip = ipaddress.ip_network(ipv4["CidrIp"]) - # Check if IP is public according to RFC1918 and if 0 < prefixlen < 24 - if ( - ip.is_global - and ip.prefixlen < cidr_treshold - and ip.prefixlen > 0 - ): - report.status = "FAIL" - report.status_extended = f"Security group {security_group.name} ({security_group.id}) has potential wide-open non-RFC1918 address {ipv4['CidrIp']} in egress rule." - break + # Loop through every security group's egress rule and check it + for egress_rule in security_group.egress_rules: + for ipv4 in egress_rule["IpRanges"]: + ip = ipaddress.ip_network(ipv4["CidrIp"]) + # Check if IP is public according to RFC1918 and if 0 < prefixlen < 24 + if ( + ip.is_global + and ip.prefixlen < cidr_treshold + and ip.prefixlen > 0 + ): + report.status = "FAIL" + report.status_extended = f"Security group {security_group.name} ({security_group.id}) has potential wide-open non-RFC1918 address {ipv4['CidrIp']} in egress rule." + break - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/ec2/ec2_service.py b/prowler/providers/aws/services/ec2/ec2_service.py index 9805b783..b57a90a7 100644 --- a/prowler/providers/aws/services/ec2/ec2_service.py +++ b/prowler/providers/aws/services/ec2/ec2_service.py @@ -19,6 +19,7 @@ class EC2(AWSService): self.__threading_call__(self.__describe_instances__) self.__get_instance_user_data__() self.security_groups = [] + self.regions_with_sgs = [] self.__threading_call__(self.__describe_security_groups__) self.network_acls = [] self.__threading_call__(self.__describe_network_acls__) @@ -116,7 +117,7 @@ class EC2(AWSService): if not self.audit_resources or ( is_resource_filtered(arn, self.audit_resources) ): - # check if sg has public access to all ports to reduce noise + # check if sg has public access to all ports all_public_ports = False for ingress_rule in sg["IpPermissions"]: if ( @@ -137,9 +138,12 @@ class EC2(AWSService): ingress_rules=sg["IpPermissions"], egress_rules=sg["IpPermissionsEgress"], public_ports=all_public_ports, + vpc_id=sg["VpcId"], tags=sg.get("Tags"), ) ) + if sg["GroupName"] != "default": + self.regions_with_sgs.append(regional_client.region) except Exception as error: logger.error( f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -396,11 +400,16 @@ class EC2(AWSService): def __get_ebs_encryption_by_default__(self, regional_client): logger.info("EC2 - Get EBS Encryption By Default...") try: + volumes_in_region = False + for volume in self.volumes: + if volume.region == regional_client.region: + volumes_in_region = True self.ebs_encryption_by_default.append( EbsEncryptionByDefault( status=regional_client.get_ebs_encryption_by_default()[ "EbsEncryptionByDefault" ], + volumes=volumes_in_region, region=regional_client.region, ) ) @@ -453,6 +462,7 @@ class SecurityGroup(BaseModel): arn: str region: str id: str + vpc_id: str public_ports: bool network_interfaces: list[str] = [] ingress_rules: list[dict] @@ -499,4 +509,5 @@ class Image(BaseModel): class EbsEncryptionByDefault(BaseModel): status: bool + volumes: bool region: str diff --git a/prowler/providers/aws/services/glue/glue_data_catalogs_connection_passwords_encryption_enabled/glue_data_catalogs_connection_passwords_encryption_enabled.py b/prowler/providers/aws/services/glue/glue_data_catalogs_connection_passwords_encryption_enabled/glue_data_catalogs_connection_passwords_encryption_enabled.py index f03e0d19..f71b4a0b 100644 --- a/prowler/providers/aws/services/glue/glue_data_catalogs_connection_passwords_encryption_enabled/glue_data_catalogs_connection_passwords_encryption_enabled.py +++ b/prowler/providers/aws/services/glue/glue_data_catalogs_connection_passwords_encryption_enabled/glue_data_catalogs_connection_passwords_encryption_enabled.py @@ -6,16 +6,18 @@ class glue_data_catalogs_connection_passwords_encryption_enabled(Check): def execute(self): findings = [] for encryption in glue_client.catalog_encryption_settings: - report = Check_Report_AWS(self.metadata()) - report.resource_id = glue_client.audited_account - report.resource_arn = glue_client.audited_account_arn - report.region = encryption.region - report.status = "FAIL" - report.status_extended = ( - "Glue data catalog connection password is not encrypted." - ) - if encryption.password_encryption: - report.status = "PASS" - report.status_extended = f"Glue data catalog connection password is encrypted with KMS key {encryption.password_kms_id}." - findings.append(report) + # Check only if there are Glue Tables + if encryption.tables or not glue_client.audit_info.ignore_unused_services: + report = Check_Report_AWS(self.metadata()) + report.resource_id = glue_client.audited_account + report.resource_arn = glue_client.audited_account_arn + report.region = encryption.region + report.status = "FAIL" + report.status_extended = ( + "Glue data catalog connection password is not encrypted." + ) + if encryption.password_encryption: + report.status = "PASS" + report.status_extended = f"Glue data catalog connection password is encrypted with KMS key {encryption.password_kms_id}." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/glue/glue_data_catalogs_metadata_encryption_enabled/glue_data_catalogs_metadata_encryption_enabled.py b/prowler/providers/aws/services/glue/glue_data_catalogs_metadata_encryption_enabled/glue_data_catalogs_metadata_encryption_enabled.py index 73143a72..6ed906cc 100644 --- a/prowler/providers/aws/services/glue/glue_data_catalogs_metadata_encryption_enabled/glue_data_catalogs_metadata_encryption_enabled.py +++ b/prowler/providers/aws/services/glue/glue_data_catalogs_metadata_encryption_enabled/glue_data_catalogs_metadata_encryption_enabled.py @@ -6,16 +6,18 @@ class glue_data_catalogs_metadata_encryption_enabled(Check): def execute(self): findings = [] for encryption in glue_client.catalog_encryption_settings: - report = Check_Report_AWS(self.metadata()) - report.resource_id = glue_client.audited_account - report.resource_arn = glue_client.audited_account_arn - report.region = encryption.region - report.status = "FAIL" - report.status_extended = ( - "Glue data catalog settings have metadata encryption disabled." - ) - if encryption.mode == "SSE-KMS": - report.status = "PASS" - report.status_extended = f"Glue data catalog settings have metadata encryption enabled with KMS key {encryption.kms_id}." - findings.append(report) + # Check only if there are Glue Tables + if encryption.tables or not glue_client.audit_info.ignore_unused_services: + report = Check_Report_AWS(self.metadata()) + report.resource_id = glue_client.audited_account + report.resource_arn = glue_client.audited_account_arn + report.region = encryption.region + report.status = "FAIL" + report.status_extended = ( + "Glue data catalog settings have metadata encryption disabled." + ) + if encryption.mode == "SSE-KMS": + report.status = "PASS" + report.status_extended = f"Glue data catalog settings have metadata encryption enabled with KMS key {encryption.kms_id}." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/glue/glue_service.py b/prowler/providers/aws/services/glue/glue_service.py index 05cd8a53..24be4f59 100644 --- a/prowler/providers/aws/services/glue/glue_service.py +++ b/prowler/providers/aws/services/glue/glue_service.py @@ -166,6 +166,10 @@ class Glue(AWSService): settings = regional_client.get_data_catalog_encryption_settings()[ "DataCatalogEncryptionSettings" ] + tables_in_region = False + for table in self.tables: + if table.region == regional_client.region: + tables_in_region = True self.catalog_encryption_settings.append( CatalogEncryptionSetting( mode=settings["EncryptionAtRest"]["CatalogEncryptionMode"], @@ -177,6 +181,7 @@ class Glue(AWSService): "AwsKmsKeyId" ), region=regional_client.region, + tables=tables_in_region, ) ) except Exception as error: @@ -206,6 +211,7 @@ class CatalogEncryptionSetting(BaseModel): kms_id: Optional[str] password_encryption: bool password_kms_id: Optional[str] + tables: bool region: str diff --git a/prowler/providers/aws/services/inspector2/inspector2_findings_exist/inspector2_findings_exist.py b/prowler/providers/aws/services/inspector2/inspector2_findings_exist/inspector2_findings_exist.py index d1788c8f..e8fd5d2f 100644 --- a/prowler/providers/aws/services/inspector2/inspector2_findings_exist/inspector2_findings_exist.py +++ b/prowler/providers/aws/services/inspector2/inspector2_findings_exist/inspector2_findings_exist.py @@ -1,4 +1,7 @@ from prowler.lib.check.models import Check, Check_Report_AWS +from prowler.providers.aws.services.awslambda.awslambda_client import awslambda_client +from prowler.providers.aws.services.ec2.ec2_client import ec2_client +from prowler.providers.aws.services.ecr.ecr_client import ecr_client from prowler.providers.aws.services.inspector2.inspector2_client import ( inspector2_client, ) @@ -9,8 +12,6 @@ class inspector2_findings_exist(Check): findings = [] for inspector in inspector2_client.inspectors: report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = "Inspector2 is not enabled." report.resource_id = inspector2_client.audited_account report.resource_arn = inspector2_client.audited_account_arn report.region = inspector.region @@ -30,7 +31,24 @@ class inspector2_findings_exist(Check): report.status_extended = ( f"There are {active_findings} ACTIVE Inspector2 findings." ) - - findings.append(report) + findings.append(report) + else: + if inspector2_client.audit_info.ignore_unused_services: + funtions_in_region = False + ec2_in_region = False + for function in awslambda_client.functions.values(): + if function.region == inspector.region: + funtions_in_region = True + for instance in ec2_client.instances: + if instance == inspector.region: + ec2_in_region = True + if not inspector2_client.audit_info.ignore_unused_services or ( + funtions_in_region + or ecr_client.registries[inspector.region].repositories + or ec2_in_region + ): + report.status = "FAIL" + report.status_extended = "Inspector2 is not enabled." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/macie/macie_is_enabled/macie_is_enabled.py b/prowler/providers/aws/services/macie/macie_is_enabled/macie_is_enabled.py index 64126db2..eeb1d134 100644 --- a/prowler/providers/aws/services/macie/macie_is_enabled/macie_is_enabled.py +++ b/prowler/providers/aws/services/macie/macie_is_enabled/macie_is_enabled.py @@ -1,5 +1,6 @@ from prowler.lib.check.models import Check, Check_Report_AWS from prowler.providers.aws.services.macie.macie_client import macie_client +from prowler.providers.aws.services.s3.s3_client import s3_client class macie_is_enabled(Check): @@ -13,12 +14,20 @@ class macie_is_enabled(Check): if session.status == "ENABLED": report.status = "PASS" report.status_extended = "Macie is enabled." - elif session.status == "PAUSED": - report.status = "FAIL" - report.status_extended = "Macie is currently in a SUSPENDED state." + findings.append(report) else: - report.status = "FAIL" - report.status_extended = "Macie is not enabled." - findings.append(report) + if ( + not macie_client.audit_info.ignore_unused_services + or session.region in s3_client.regions_with_buckets + ): + if session.status == "PAUSED": + report.status = "FAIL" + report.status_extended = ( + "Macie is currently in a SUSPENDED state." + ) + else: + report.status = "FAIL" + report.status_extended = "Macie is not enabled." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/networkfirewall/networkfirewall_in_all_vpc/networkfirewall_in_all_vpc.py b/prowler/providers/aws/services/networkfirewall/networkfirewall_in_all_vpc/networkfirewall_in_all_vpc.py index 20b0f507..692a93b2 100644 --- a/prowler/providers/aws/services/networkfirewall/networkfirewall_in_all_vpc/networkfirewall_in_all_vpc.py +++ b/prowler/providers/aws/services/networkfirewall/networkfirewall_in_all_vpc/networkfirewall_in_all_vpc.py @@ -9,19 +9,20 @@ class networkfirewall_in_all_vpc(Check): def execute(self): findings = [] for vpc in vpc_client.vpcs.values(): - report = Check_Report_AWS(self.metadata()) - report.region = vpc.region - report.resource_id = vpc.id - report.resource_arn = vpc.arn - report.resource_tags = vpc.tags - report.status = "FAIL" - report.status_extended = f"VPC {vpc.name if vpc.name else vpc.id} does not have Network Firewall enabled." - for firewall in networkfirewall_client.network_firewalls: - if firewall.vpc_id == vpc.id: - report.status = "PASS" - report.status_extended = f"VPC {vpc.name if vpc.name else vpc.id} has Network Firewall enabled." - break + if not vpc_client.audit_info.ignore_unused_services or vpc.in_use: + report = Check_Report_AWS(self.metadata()) + report.region = vpc.region + report.resource_id = vpc.id + report.resource_arn = vpc.arn + report.resource_tags = vpc.tags + report.status = "FAIL" + report.status_extended = f"VPC {vpc.name if vpc.name else vpc.id} does not have Network Firewall enabled." + for firewall in networkfirewall_client.network_firewalls: + if firewall.vpc_id == vpc.id: + report.status = "PASS" + report.status_extended = f"VPC {vpc.name if vpc.name else vpc.id} has Network Firewall enabled." + break - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks.py b/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks.py index 3bdabb55..1374c727 100644 --- a/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks.py +++ b/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks.py @@ -1,4 +1,5 @@ from prowler.lib.check.models import Check, Check_Report_AWS +from prowler.providers.aws.services.s3.s3_client import s3_client from prowler.providers.aws.services.s3.s3control_client import s3control_client @@ -6,11 +7,6 @@ class s3_account_level_public_access_blocks(Check): def execute(self): findings = [] report = Check_Report_AWS(self.metadata()) - report.status = "FAIL" - report.status_extended = f"Block Public Access is not configured for the account {s3control_client.audited_account}." - report.region = s3control_client.region - report.resource_id = s3control_client.audited_account - report.resource_arn = s3control_client.audited_account_arn if ( s3control_client.account_public_access_block and s3control_client.account_public_access_block.ignore_public_acls @@ -18,7 +14,16 @@ class s3_account_level_public_access_blocks(Check): ): report.status = "PASS" report.status_extended = f"Block Public Access is configured for the account {s3control_client.audited_account}." - - findings.append(report) + report.region = s3control_client.region + report.resource_id = s3control_client.audited_account + report.resource_arn = s3control_client.audited_account_arn + findings.append(report) + elif s3_client.buckets or not s3_client.audit_info.ignore_unused_services: + report.status = "FAIL" + report.status_extended = f"Block Public Access is not configured for the account {s3control_client.audited_account}." + report.region = s3control_client.region + report.resource_id = s3control_client.audited_account + report.resource_arn = s3control_client.audited_account_arn + findings.append(report) return findings diff --git a/prowler/providers/aws/services/s3/s3_service.py b/prowler/providers/aws/services/s3/s3_service.py index a38f611c..4c0e1d91 100644 --- a/prowler/providers/aws/services/s3/s3_service.py +++ b/prowler/providers/aws/services/s3/s3_service.py @@ -15,7 +15,7 @@ class S3(AWSService): def __init__(self, audit_info): # Call AWSService's __init__ super().__init__(__class__.__name__, audit_info) - + self.regions_with_buckets = [] self.buckets = self.__list_buckets__(audit_info) self.__threading_call__(self.__get_bucket_versioning__) self.__threading_call__(self.__get_bucket_logging__) @@ -55,6 +55,7 @@ class S3(AWSService): if not self.audit_resources or ( is_resource_filtered(arn, self.audit_resources) ): + self.regions_with_buckets.append(bucket_region) # Check if there are filter regions if audit_info.audited_regions: if bucket_region in audit_info.audited_regions: diff --git a/prowler/providers/aws/services/ssmincidents/ssmincidents_enabled_with_plans/ssmincidents_enabled_with_plans.metadata.json b/prowler/providers/aws/services/ssmincidents/ssmincidents_enabled_with_plans/ssmincidents_enabled_with_plans.metadata.json index 8393ff6c..f3d8508f 100644 --- a/prowler/providers/aws/services/ssmincidents/ssmincidents_enabled_with_plans/ssmincidents_enabled_with_plans.metadata.json +++ b/prowler/providers/aws/services/ssmincidents/ssmincidents_enabled_with_plans/ssmincidents_enabled_with_plans.metadata.json @@ -6,7 +6,7 @@ "ServiceName": "ssm", "SubServiceName": "", "ResourceIdTemplate": "arn:aws:ssm:region:account-id:document/document-name", - "Severity": "medium", + "Severity": "low", "ResourceType": "Other", "Description": "Ensure SSM Incidents is enabled with response plans.", "Risk": "Not having SSM Incidents enabled can increase the risk of delayed detection and response to security incidents, unauthorized access, limited visibility into incidents and vulnerabilities", diff --git a/prowler/providers/aws/services/vpc/vpc_different_regions/vpc_different_regions.metadata.json b/prowler/providers/aws/services/vpc/vpc_different_regions/vpc_different_regions.metadata.json index 3bb93b00..8ca11d68 100644 --- a/prowler/providers/aws/services/vpc/vpc_different_regions/vpc_different_regions.metadata.json +++ b/prowler/providers/aws/services/vpc/vpc_different_regions/vpc_different_regions.metadata.json @@ -1,7 +1,7 @@ { "Provider": "aws", "CheckID": "vpc_different_regions", - "CheckTitle": "Ensure there are vpcs in more than one region", + "CheckTitle": "Ensure there are VPCs in more than one region", "CheckType": [ "Infrastructure Security" ], @@ -10,7 +10,7 @@ "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", "Severity": "medium", "ResourceType": "AwsEc2Vpc", - "Description": "Ensure there are vpcs in more than one region", + "Description": "Ensure there are VPCs in more than one region", "Risk": "", "RelatedUrl": "https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html", "Remediation": { @@ -21,7 +21,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "Ensure there are vpcs in more than one region", + "Text": "Ensure there are VPCs in more than one region", "Url": "https://docs.aws.amazon.com/vpc/latest/userguide/vpc-example-private-subnets-nat.html" } }, diff --git a/prowler/providers/aws/services/vpc/vpc_flow_logs_enabled/vpc_flow_logs_enabled.py b/prowler/providers/aws/services/vpc/vpc_flow_logs_enabled/vpc_flow_logs_enabled.py index afdf74ec..9821d7f1 100644 --- a/prowler/providers/aws/services/vpc/vpc_flow_logs_enabled/vpc_flow_logs_enabled.py +++ b/prowler/providers/aws/services/vpc/vpc_flow_logs_enabled/vpc_flow_logs_enabled.py @@ -6,21 +6,22 @@ class vpc_flow_logs_enabled(Check): def execute(self): findings = [] for vpc in vpc_client.vpcs.values(): - report = Check_Report_AWS(self.metadata()) - report.region = vpc.region - report.resource_tags = vpc.tags - report.resource_id = vpc.id - report.resource_arn = vpc.arn - report.status = "FAIL" - report.status_extended = ( - f"VPC {vpc.name if vpc.name else vpc.id} Flow logs are disabled." - ) - if vpc.flow_log: - report.status = "PASS" + if not vpc_client.audit_info.ignore_unused_services or vpc.in_use: + report = Check_Report_AWS(self.metadata()) + report.region = vpc.region + report.resource_tags = vpc.tags + report.resource_id = vpc.id + report.resource_arn = vpc.arn + report.status = "FAIL" report.status_extended = ( - f"VPC {vpc.name if vpc.name else vpc.id} Flow logs are enabled." + f"VPC {vpc.name if vpc.name else vpc.id} Flow logs are disabled." ) + if vpc.flow_log: + report.status = "PASS" + report.status_extended = ( + f"VPC {vpc.name if vpc.name else vpc.id} Flow logs are enabled." + ) - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/aws/services/vpc/vpc_service.py b/prowler/providers/aws/services/vpc/vpc_service.py index 9b601b61..7affa7ee 100644 --- a/prowler/providers/aws/services/vpc/vpc_service.py +++ b/prowler/providers/aws/services/vpc/vpc_service.py @@ -25,6 +25,7 @@ class VPC(AWSService): self.__describe_flow_logs__() self.__describe_peering_route_tables__() self.__describe_vpc_endpoint_service_permissions__() + self.__describe_network_interfaces__() self.vpc_subnets = {} self.__threading_call__(self.__describe_vpc_subnets__) @@ -34,22 +35,27 @@ class VPC(AWSService): describe_vpcs_paginator = regional_client.get_paginator("describe_vpcs") for page in describe_vpcs_paginator.paginate(): for vpc in page["Vpcs"]: - arn = f"arn:{self.audited_partition}:ec2:{regional_client.region}:{self.audited_account}:vpc/{vpc['VpcId']}" - if not self.audit_resources or ( - is_resource_filtered(arn, self.audit_resources) - ): - vpc_name = "" - for tag in vpc.get("Tags", []): - if tag["Key"] == "Name": - vpc_name = tag["Value"] - self.vpcs[vpc["VpcId"]] = VPCs( - arn=arn, - id=vpc["VpcId"], - name=vpc_name, - default=vpc["IsDefault"], - cidr_block=vpc["CidrBlock"], - region=regional_client.region, - tags=vpc.get("Tags"), + try: + arn = f"arn:{self.audited_partition}:ec2:{regional_client.region}:{self.audited_account}:vpc/{vpc['VpcId']}" + if not self.audit_resources or ( + is_resource_filtered(arn, self.audit_resources) + ): + vpc_name = "" + for tag in vpc.get("Tags", []): + if tag["Key"] == "Name": + vpc_name = tag["Value"] + self.vpcs[vpc["VpcId"]] = VPCs( + arn=arn, + id=vpc["VpcId"], + name=vpc_name, + default=vpc["IsDefault"], + cidr_block=vpc["CidrBlock"], + region=regional_client.region, + tags=vpc.get("Tags"), + ) + except Exception as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) except Exception as error: logger.error( @@ -68,21 +74,28 @@ class VPC(AWSService): if not self.audit_resources or ( is_resource_filtered(arn, self.audit_resources) ): - conn["AccepterVpcInfo"]["CidrBlock"] = None - self.vpc_peering_connections.append( - VpcPeeringConnection( - arn=arn, - id=conn["VpcPeeringConnectionId"], - accepter_vpc=conn["AccepterVpcInfo"]["VpcId"], - accepter_cidr=conn["AccepterVpcInfo"].get("CidrBlock"), - requester_vpc=conn["RequesterVpcInfo"]["VpcId"], - requester_cidr=conn["RequesterVpcInfo"].get( - "CidrBlock" - ), - region=regional_client.region, - tags=conn.get("Tags"), + try: + conn["AccepterVpcInfo"]["CidrBlock"] = None + self.vpc_peering_connections.append( + VpcPeeringConnection( + arn=arn, + id=conn["VpcPeeringConnectionId"], + accepter_vpc=conn["AccepterVpcInfo"]["VpcId"], + accepter_cidr=conn["AccepterVpcInfo"].get( + "CidrBlock" + ), + requester_vpc=conn["RequesterVpcInfo"]["VpcId"], + requester_cidr=conn["RequesterVpcInfo"].get( + "CidrBlock" + ), + region=regional_client.region, + tags=conn.get("Tags"), + ) + ) + except Exception as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - ) except Exception as error: logger.error( f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -103,23 +116,29 @@ class VPC(AWSService): }, ] )["RouteTables"]: - destination_cidrs = [] - for route in route_table["Routes"]: - if ( - route["Origin"] != "CreateRouteTable" - ): # avoid default route table + try: + destination_cidrs = [] + for route in route_table["Routes"]: if ( - "DestinationCidrBlock" in route - and "VpcPeeringConnectionId" in route - ): - destination_cidrs.append(route["DestinationCidrBlock"]) - conn.route_tables.append( - Route( - id=route_table["RouteTableId"], - destination_cidrs=destination_cidrs, + route["Origin"] != "CreateRouteTable" + ): # avoid default route table + if ( + "DestinationCidrBlock" in route + and "VpcPeeringConnectionId" in route + ): + destination_cidrs.append( + route["DestinationCidrBlock"] + ) + conn.route_tables.append( + Route( + id=route_table["RouteTableId"], + destination_cidrs=destination_cidrs, + ) + ) + except Exception as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - ) - except Exception as error: logger.error( f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}" @@ -129,20 +148,51 @@ class VPC(AWSService): logger.info("VPC - Describing flow logs...") try: for vpc in self.vpcs.values(): - regional_client = self.regional_clients[vpc.region] - flow_logs = regional_client.describe_flow_logs( - Filters=[ - { - "Name": "resource-id", - "Values": [ - vpc.id, - ], - }, - ] - )["FlowLogs"] - if flow_logs: - vpc.flow_log = True + try: + regional_client = self.regional_clients[vpc.region] + flow_logs = regional_client.describe_flow_logs( + Filters=[ + { + "Name": "resource-id", + "Values": [ + vpc.id, + ], + }, + ] + )["FlowLogs"] + if flow_logs: + vpc.flow_log = True + except Exception as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + except Exception as error: + logger.error( + f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}" + ) + def __describe_network_interfaces__(self): + logger.info("VPC - Describing flow logs...") + try: + for vpc in self.vpcs.values(): + try: + regional_client = self.regional_clients[vpc.region] + enis = regional_client.describe_network_interfaces( + Filters=[ + { + "Name": "vpc-id", + "Values": [ + vpc.id, + ], + }, + ] + )["NetworkInterfaces"] + if enis: + vpc.in_use = True + except Exception as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) except Exception as error: logger.error( f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}" @@ -156,25 +206,30 @@ class VPC(AWSService): ) for page in describe_vpc_endpoints_paginator.paginate(): for endpoint in page["VpcEndpoints"]: - arn = f"arn:{self.audited_partition}:ec2:{regional_client.region}:{self.audited_account}:vpc-endpoint/{endpoint['VpcEndpointId']}" - if not self.audit_resources or ( - is_resource_filtered(arn, self.audit_resources) - ): - endpoint_policy = None - if endpoint.get("PolicyDocument"): - endpoint_policy = json.loads(endpoint["PolicyDocument"]) - self.vpc_endpoints.append( - VpcEndpoint( - arn=arn, - id=endpoint["VpcEndpointId"], - vpc_id=endpoint["VpcId"], - service_name=endpoint["ServiceName"], - state=endpoint["State"], - policy_document=endpoint_policy, - owner_id=endpoint["OwnerId"], - region=regional_client.region, - tags=endpoint.get("Tags"), + try: + arn = f"arn:{self.audited_partition}:ec2:{regional_client.region}:{self.audited_account}:vpc-endpoint/{endpoint['VpcEndpointId']}" + if not self.audit_resources or ( + is_resource_filtered(arn, self.audit_resources) + ): + endpoint_policy = None + if endpoint.get("PolicyDocument"): + endpoint_policy = json.loads(endpoint["PolicyDocument"]) + self.vpc_endpoints.append( + VpcEndpoint( + arn=arn, + id=endpoint["VpcEndpointId"], + vpc_id=endpoint["VpcId"], + service_name=endpoint["ServiceName"], + state=endpoint["State"], + policy_document=endpoint_policy, + owner_id=endpoint["OwnerId"], + region=regional_client.region, + tags=endpoint.get("Tags"), + ) ) + except Exception as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) except Exception as error: logger.error( @@ -189,21 +244,26 @@ class VPC(AWSService): ) for page in describe_vpc_endpoint_services_paginator.paginate(): for endpoint in page["ServiceDetails"]: - if endpoint["Owner"] != "amazon": - arn = f"arn:{self.audited_partition}:ec2:{regional_client.region}:{self.audited_account}:vpc-endpoint-service/{endpoint['ServiceId']}" - if not self.audit_resources or ( - is_resource_filtered(arn, self.audit_resources) - ): - self.vpc_endpoint_services.append( - VpcEndpointService( - arn=arn, - id=endpoint["ServiceId"], - service=endpoint["ServiceName"], - owner_id=endpoint["Owner"], - region=regional_client.region, - tags=endpoint.get("Tags"), + try: + if endpoint["Owner"] != "amazon": + arn = f"arn:{self.audited_partition}:ec2:{regional_client.region}:{self.audited_account}:vpc-endpoint-service/{endpoint['ServiceId']}" + if not self.audit_resources or ( + is_resource_filtered(arn, self.audit_resources) + ): + self.vpc_endpoint_services.append( + VpcEndpointService( + arn=arn, + id=endpoint["ServiceId"], + service=endpoint["ServiceName"], + owner_id=endpoint["Owner"], + region=regional_client.region, + tags=endpoint.get("Tags"), + ) ) - ) + except Exception as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) except Exception as error: logger.error( f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -337,6 +397,7 @@ class VPCs(BaseModel): id: str name: str default: bool + in_use: bool = False cidr_block: str flow_log: bool = False region: str diff --git a/prowler/providers/aws/services/vpc/vpc_subnet_different_az/vpc_subnet_different_az.metadata.json b/prowler/providers/aws/services/vpc/vpc_subnet_different_az/vpc_subnet_different_az.metadata.json index 0691a1f8..25a5d938 100644 --- a/prowler/providers/aws/services/vpc/vpc_subnet_different_az/vpc_subnet_different_az.metadata.json +++ b/prowler/providers/aws/services/vpc/vpc_subnet_different_az/vpc_subnet_different_az.metadata.json @@ -1,7 +1,7 @@ { "Provider": "aws", "CheckID": "vpc_subnet_different_az", - "CheckTitle": "Ensure all vpc has subnets in more than one availability zone", + "CheckTitle": "Ensure all VPC has subnets in more than one availability zone", "CheckType": [ "Infrastructure Security" ], @@ -10,7 +10,7 @@ "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", "Severity": "medium", "ResourceType": "AwsEc2Vpc", - "Description": "Ensure all vpc has subnets in more than one availability zone", + "Description": "Ensure all VPC has subnets in more than one availability zone", "Risk": "", "RelatedUrl": "https://docs.aws.amazon.com/vpc/latest/userguide/configure-subnets.html", "Remediation": { @@ -21,7 +21,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "Ensure all vpc has subnets in more than one availability zone", + "Text": "Ensure all VPC has subnets in more than one availability zone", "Url": "https://docs.aws.amazon.com/vpc/latest/userguide/configure-subnets.html" } }, diff --git a/prowler/providers/aws/services/vpc/vpc_subnet_separate_private_public/vpc_subnet_separate_private_public.metadata.json b/prowler/providers/aws/services/vpc/vpc_subnet_separate_private_public/vpc_subnet_separate_private_public.metadata.json index 1a0bc2f3..da7f87fa 100644 --- a/prowler/providers/aws/services/vpc/vpc_subnet_separate_private_public/vpc_subnet_separate_private_public.metadata.json +++ b/prowler/providers/aws/services/vpc/vpc_subnet_separate_private_public/vpc_subnet_separate_private_public.metadata.json @@ -1,7 +1,7 @@ { "Provider": "aws", "CheckID": "vpc_subnet_separate_private_public", - "CheckTitle": "Ensure all vpc has public and private subnets defined", + "CheckTitle": "Ensure all VPC has public and private subnets defined", "CheckType": [ "Infrastructure Security" ], @@ -10,7 +10,7 @@ "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", "Severity": "medium", "ResourceType": "AwsEc2Vpc", - "Description": "Ensure all vpc has public and private subnets defined", + "Description": "Ensure all VPC has public and private subnets defined", "Risk": "", "RelatedUrl": "https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html", "Remediation": { @@ -21,7 +21,7 @@ "Terraform": "" }, "Recommendation": { - "Text": "Ensure all vpc has public and private subnets defined", + "Text": "Ensure all VPC has public and private subnets defined", "Url": "https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html" } }, diff --git a/prowler/providers/common/audit_info.py b/prowler/providers/common/audit_info.py index 0de2b9a3..d2ee1361 100644 --- a/prowler/providers/common/audit_info.py +++ b/prowler/providers/common/audit_info.py @@ -109,6 +109,11 @@ Azure Identity Type: {Fore.YELLOW}[{audit_info.identity.identity_type}]{Style.RE new_boto3_config = current_audit_info.session_config.merge(config) current_audit_info.session_config = new_boto3_config + # Set ignore unused services argument + current_audit_info.ignore_unused_services = arguments.get( + "ignore_unused_services" + ) + # Setting session current_audit_info.profile = input_profile current_audit_info.audited_regions = input_regions diff --git a/tests/lib/cli/parser_test.py b/tests/lib/cli/parser_test.py index e9a305c4..e09f366d 100644 --- a/tests/lib/cli/parser_test.py +++ b/tests/lib/cli/parser_test.py @@ -75,6 +75,7 @@ class Test_Parser: assert not parsed.shodan assert not parsed.allowlist_file assert not parsed.resource_tags + assert not parsed.ignore_unused_services def test_default_parser_no_arguments_azure(self): provider = "azure" @@ -970,6 +971,12 @@ class Test_Parser: parsed = self.parser.parse(command) assert parsed.aws_retries_max_attempts == int(max_retries) + def test_aws_parser_ignore_unused_services(self): + argument = "--ignore-unused-services" + command = [prowler_command, argument] + parsed = self.parser.parse(command) + assert parsed.ignore_unused_services + def test_aws_parser_config_file(self): argument = "--config-file" config_file = "./test-config.yaml" diff --git a/tests/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings_test.py b/tests/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings_test.py index ca7ba779..6d33c840 100644 --- a/tests/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings_test.py +++ b/tests/providers/aws/services/accessanalyzer/accessanalyzer_enabled_without_findings/accessanalyzer_enabled_without_findings_test.py @@ -56,18 +56,9 @@ class Test_accessanalyzer_enabled_without_findings: check = accessanalyzer_enabled_without_findings() result = check.execute() - assert len(result) == 1 - assert result[0].status == "FAIL" - assert ( - result[0].status_extended - == f"IAM Access Analyzer in account {AWS_ACCOUNT_NUMBER} is not enabled." - ) - assert result[0].resource_id == AWS_ACCOUNT_NUMBER - assert result[0].resource_arn == AWS_ACCOUNT_ARN - assert result[0].region == AWS_REGION_1 - assert result[0].resource_tags == [] + assert len(result) == 0 - def test_two_analyzers(self): + def test_two_analyzers_but_one_with_findings(self): accessanalyzer_client = mock.MagicMock accessanalyzer_client.analyzers = [ Analyzer( @@ -112,27 +103,17 @@ class Test_accessanalyzer_enabled_without_findings: check = accessanalyzer_enabled_without_findings() result = check.execute() - assert len(result) == 2 + assert len(result) == 1 assert result[0].status == "FAIL" assert ( result[0].status_extended - == f"IAM Access Analyzer in account {AWS_ACCOUNT_NUMBER} is not enabled." - ) - assert result[0].resource_id == AWS_ACCOUNT_NUMBER - assert result[0].resource_arn == AWS_ACCOUNT_ARN - assert result[0].region == AWS_REGION_1 - assert result[0].resource_tags == [] - - assert result[1].status == "FAIL" - assert ( - result[1].status_extended == f"IAM Access Analyzer {ACCESS_ANALYZER_NAME} has 1 active findings." ) - assert result[1].resource_id == ACCESS_ANALYZER_NAME - assert result[1].resource_arn == ACCESS_ANALYZER_ARN - assert result[1].region == AWS_REGION_2 - assert result[1].resource_tags == [] + assert result[0].resource_id == ACCESS_ANALYZER_NAME + assert result[0].resource_arn == ACCESS_ANALYZER_ARN + assert result[0].region == AWS_REGION_2 + assert result[0].resource_tags == [] def test_one_active_analyzer_without_findings(self): accessanalyzer_client = mock.MagicMock @@ -171,7 +152,7 @@ class Test_accessanalyzer_enabled_without_findings: assert result[0].region == AWS_REGION_2 assert result[0].resource_tags == [] - def test_one_active_analyzer_not_active(self): + def test_one_active_analyzer_not_active_without_findings(self): accessanalyzer_client = mock.MagicMock accessanalyzer_client.analyzers = [ Analyzer( @@ -197,16 +178,7 @@ class Test_accessanalyzer_enabled_without_findings: check = accessanalyzer_enabled_without_findings() result = check.execute() - assert len(result) == 1 - assert result[0].status == "FAIL" - assert ( - result[0].status_extended - == f"IAM Access Analyzer in account {AWS_ACCOUNT_NUMBER} is not enabled." - ) - assert result[0].resource_id == AWS_ACCOUNT_NUMBER - assert result[0].resource_arn == AWS_ACCOUNT_ARN - assert result[0].region == AWS_REGION_1 - assert result[0].resource_tags == [] + assert len(result) == 0 def test_analyzer_finding_without_status(self): accessanalyzer_client = mock.MagicMock diff --git a/tests/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption_test.py b/tests/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption_test.py index 0200f73e..267f1ecb 100644 --- a/tests/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption_test.py +++ b/tests/providers/aws/services/athena/athena_workgroup_encryption/athena_workgroup_encryption_test.py @@ -77,6 +77,29 @@ class Test_athena_workgroup_encryption: assert result[0].region == AWS_REGION assert result[0].resource_tags == [] + @mock_athena + def test_primary_workgroup_not_encrypted_ignoring(self): + from prowler.providers.aws.services.athena.athena_service import Athena + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.athena.athena_workgroup_encryption.athena_workgroup_encryption.athena_client", + new=Athena(current_audit_info), + ): + from prowler.providers.aws.services.athena.athena_workgroup_encryption.athena_workgroup_encryption import ( + athena_workgroup_encryption, + ) + + check = athena_workgroup_encryption() + result = check.execute() + + assert len(result) == 0 + @mock_athena # We mock the get_work_group to return an encrypted workgroup @patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call) diff --git a/tests/providers/aws/services/athena/athena_workgroup_enforce_configuration/athena_workgroup_enforce_configuration_test.py b/tests/providers/aws/services/athena/athena_workgroup_enforce_configuration/athena_workgroup_enforce_configuration_test.py index 5868a5ca..b7c81913 100644 --- a/tests/providers/aws/services/athena/athena_workgroup_enforce_configuration/athena_workgroup_enforce_configuration_test.py +++ b/tests/providers/aws/services/athena/athena_workgroup_enforce_configuration/athena_workgroup_enforce_configuration_test.py @@ -77,6 +77,29 @@ class Test_athena_workgroup_enforce_configuration: assert result[0].region == AWS_REGION assert result[0].resource_tags == [] + @mock_athena + def test_primary_workgroup_configuration_not_enforced_ignoring(self): + from prowler.providers.aws.services.athena.athena_service import Athena + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.athena.athena_workgroup_enforce_configuration.athena_workgroup_enforce_configuration.athena_client", + new=Athena(current_audit_info), + ): + from prowler.providers.aws.services.athena.athena_workgroup_enforce_configuration.athena_workgroup_enforce_configuration import ( + athena_workgroup_enforce_configuration, + ) + + check = athena_workgroup_enforce_configuration() + result = check.execute() + + assert len(result) == 0 + @mock_athena # We mock the get_work_group to return a workgroup not enforcing configuration @patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call) diff --git a/tests/providers/aws/services/backup/backup_plans_exist/backup_plans_exist_test.py b/tests/providers/aws/services/backup/backup_plans_exist/backup_plans_exist_test.py index 2e3607f4..b29497f0 100644 --- a/tests/providers/aws/services/backup/backup_plans_exist/backup_plans_exist_test.py +++ b/tests/providers/aws/services/backup/backup_plans_exist/backup_plans_exist_test.py @@ -15,6 +15,7 @@ class Test_backup_plans_exist: backup_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" backup_client.region = AWS_REGION backup_client.backup_plans = [] + backup_client.backup_vaults = ["vault"] with mock.patch( "prowler.providers.aws.services.backup.backup_service.Backup", new=backup_client, @@ -34,6 +35,27 @@ class Test_backup_plans_exist: assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" assert result[0].region == AWS_REGION + def test_no_backup_plans_not_vaults(self): + backup_client = mock.MagicMock + backup_client.audited_account = AWS_ACCOUNT_NUMBER + backup_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + backup_client.region = AWS_REGION + backup_client.backup_plans = [] + backup_client.backup_vaults = [] + with mock.patch( + "prowler.providers.aws.services.backup.backup_service.Backup", + new=backup_client, + ): + # Test Check + from prowler.providers.aws.services.backup.backup_plans_exist.backup_plans_exist import ( + backup_plans_exist, + ) + + check = backup_plans_exist() + result = check.execute() + + assert len(result) == 0 + def test_one_backup_plan(self): backup_client = mock.MagicMock backup_client.audited_account = AWS_ACCOUNT_NUMBER @@ -70,7 +92,7 @@ class Test_backup_plans_exist: assert result[0].status == "PASS" assert ( result[0].status_extended - == f"At least one backup plan exists: {result[0].resource_id}." + == f"At least one Backup Plan exists: {result[0].resource_id}." ) assert result[0].resource_id == "MyBackupPlan" assert ( diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled_test.py index 40a4d9d1..cc5e6609 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled_test.py @@ -1,52 +1,23 @@ -from re import search from unittest import mock -from boto3 import client, session +from boto3 import client from moto import mock_cloudtrail, mock_s3 -from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info -from prowler.providers.common.models import Audit_Metadata - -AWS_ACCOUNT_NUMBER = "123456789012" -AWS_REGION = "us-east-1" +from tests.providers.aws.audit_info_utils import ( + AWS_ACCOUNT_NUMBER, + AWS_REGION_US_EAST_1, + set_mocked_aws_audit_info, +) class Test_cloudtrail_s3_dataevents_read_enabled: - def set_mocked_audit_info(self): - audit_info = AWS_Audit_Info( - session_config=None, - original_session=None, - audit_session=session.Session( - profile_name=None, - botocore_session=None, - ), - audited_account=AWS_ACCOUNT_NUMBER, - audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root", - audited_user_id=None, - audited_partition="aws", - audited_identity_arn=None, - profile=None, - profile_region=None, - credentials=None, - assumed_role_info=None, - audited_regions=[AWS_REGION], - organizations_metadata=None, - audit_resources=None, - mfa_enabled=False, - audit_metadata=Audit_Metadata( - services_scanned=0, - expected_checks=[], - completed_checks=0, - audit_progress=0, - ), - ) - return audit_info - @mock_cloudtrail @mock_s3 def test_trail_without_data_events(self): - cloudtrail_client_us_east_1 = client("cloudtrail", region_name=AWS_REGION) - s3_client_us_east_1 = client("s3", region_name=AWS_REGION) + cloudtrail_client_us_east_1 = client( + "cloudtrail", region_name=AWS_REGION_US_EAST_1 + ) + s3_client_us_east_1 = client("s3", region_name=AWS_REGION_US_EAST_1) trail_name_us = "trail_test_us" bucket_name_us = "bucket_test_us" s3_client_us_east_1.create_bucket(Bucket=bucket_name_us) @@ -57,43 +28,121 @@ class Test_cloudtrail_s3_dataevents_read_enabled: from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( Cloudtrail, ) + from prowler.providers.aws.services.s3.s3_service import S3 - current_audit_info = self.set_mocked_audit_info() + current_audit_info = set_mocked_aws_audit_info() with mock.patch( "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client", + new=Cloudtrail(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.s3_client", + new=S3(current_audit_info), ): - with mock.patch( - "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client", - new=Cloudtrail(current_audit_info), - ): - # Test Check - from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import ( - cloudtrail_s3_dataevents_read_enabled, - ) + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import ( + cloudtrail_s3_dataevents_read_enabled, + ) - check = cloudtrail_s3_dataevents_read_enabled() - result = check.execute() + check = cloudtrail_s3_dataevents_read_enabled() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "FAIL" - assert search( - "No CloudTrail trails have a data event to record all S3 object-level API operations.", - result[0].status_extended, - ) - assert result[0].resource_id == AWS_ACCOUNT_NUMBER - assert ( - result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" - ) - assert result[0].resource_tags == [] - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "No CloudTrail trails have a data event to record all S3 object-level API operations." + ) + assert result[0].resource_id == AWS_ACCOUNT_NUMBER + assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + assert result[0].resource_tags == [] + assert result[0].region == AWS_REGION_US_EAST_1 + + @mock_cloudtrail + @mock_s3 + def test_trail_without_data_events_ignoring(self): + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + from prowler.providers.aws.services.s3.s3_service import S3 + + current_audit_info = set_mocked_aws_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client", + new=Cloudtrail(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.s3_client", + new=S3(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import ( + cloudtrail_s3_dataevents_read_enabled, + ) + + check = cloudtrail_s3_dataevents_read_enabled() + result = check.execute() + + assert len(result) == 0 + + @mock_cloudtrail + @mock_s3 + def test_trail_without_data_events_ignoring_with_buckets(self): + s3_client_us_east_1 = client("s3", region_name=AWS_REGION_US_EAST_1) + bucket_name_us = "bucket_test_us" + s3_client_us_east_1.create_bucket(Bucket=bucket_name_us) + + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + from prowler.providers.aws.services.s3.s3_service import S3 + + current_audit_info = set_mocked_aws_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client", + new=Cloudtrail(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.s3_client", + new=S3(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import ( + cloudtrail_s3_dataevents_read_enabled, + ) + + check = cloudtrail_s3_dataevents_read_enabled() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "No CloudTrail trails have a data event to record all S3 object-level API operations." + ) + assert result[0].resource_id == AWS_ACCOUNT_NUMBER + assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + assert result[0].resource_tags == [] + assert result[0].region == AWS_REGION_US_EAST_1 @mock_cloudtrail @mock_s3 def test_trail_without_s3_data_events(self): - cloudtrail_client_us_east_1 = client("cloudtrail", region_name=AWS_REGION) - s3_client_us_east_1 = client("s3", region_name=AWS_REGION) + cloudtrail_client_us_east_1 = client( + "cloudtrail", region_name=AWS_REGION_US_EAST_1 + ) + s3_client_us_east_1 = client("s3", region_name=AWS_REGION_US_EAST_1) trail_name_us = "trail_test_us" bucket_name_us = "bucket_test_us" s3_client_us_east_1.create_bucket(Bucket=bucket_name_us) @@ -116,43 +165,46 @@ class Test_cloudtrail_s3_dataevents_read_enabled: from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( Cloudtrail, ) + from prowler.providers.aws.services.s3.s3_service import S3 - current_audit_info = self.set_mocked_audit_info() + current_audit_info = set_mocked_aws_audit_info() with mock.patch( "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client", + new=Cloudtrail(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.s3_client", + new=S3(current_audit_info), ): - with mock.patch( - "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client", - new=Cloudtrail(current_audit_info), - ): - # Test Check - from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import ( - cloudtrail_s3_dataevents_read_enabled, - ) + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import ( + cloudtrail_s3_dataevents_read_enabled, + ) - check = cloudtrail_s3_dataevents_read_enabled() - result = check.execute() + check = cloudtrail_s3_dataevents_read_enabled() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "FAIL" - assert search( - "No CloudTrail trails have a data event to record all S3 object-level API operations.", - result[0].status_extended, - ) - assert result[0].resource_id == AWS_ACCOUNT_NUMBER - assert ( - result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" - ) - assert result[0].resource_tags == [] - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "No CloudTrail trails have a data event to record all S3 object-level API operations." + ) + assert result[0].resource_id == AWS_ACCOUNT_NUMBER + assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + assert result[0].resource_tags == [] + assert result[0].region == AWS_REGION_US_EAST_1 @mock_cloudtrail @mock_s3 def test_trail_with_s3_classic_data_events(self): - cloudtrail_client_us_east_1 = client("cloudtrail", region_name=AWS_REGION) - s3_client_us_east_1 = client("s3", region_name=AWS_REGION) + cloudtrail_client_us_east_1 = client( + "cloudtrail", region_name=AWS_REGION_US_EAST_1 + ) + s3_client_us_east_1 = client("s3", region_name=AWS_REGION_US_EAST_1) trail_name_us = "trail_test_us" bucket_name_us = "bucket_test_us" s3_client_us_east_1.create_bucket(Bucket=bucket_name_us) @@ -175,41 +227,46 @@ class Test_cloudtrail_s3_dataevents_read_enabled: from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( Cloudtrail, ) + from prowler.providers.aws.services.s3.s3_service import S3 - current_audit_info = self.set_mocked_audit_info() + current_audit_info = set_mocked_aws_audit_info() with mock.patch( "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client", + new=Cloudtrail(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.s3_client", + new=S3(current_audit_info), ): - with mock.patch( - "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client", - new=Cloudtrail(current_audit_info), - ): - # Test Check - from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import ( - cloudtrail_s3_dataevents_read_enabled, - ) + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import ( + cloudtrail_s3_dataevents_read_enabled, + ) - check = cloudtrail_s3_dataevents_read_enabled() - result = check.execute() + check = cloudtrail_s3_dataevents_read_enabled() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "PASS" - assert search( - "has a classic data event selector to record all S3 object-level API operations.", - result[0].status_extended, - ) - assert result[0].resource_id == trail_name_us - assert result[0].resource_arn == trail_us["TrailARN"] - assert result[0].resource_tags == [] - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Trail {trail_name_us} from home region {AWS_REGION_US_EAST_1} has a classic data event selector to record all S3 object-level API operations." + ) + assert result[0].resource_id == trail_name_us + assert result[0].resource_arn == trail_us["TrailARN"] + assert result[0].resource_tags == [] + assert result[0].region == AWS_REGION_US_EAST_1 @mock_cloudtrail @mock_s3 def test_trail_with_s3_advanced_data_events(self): - cloudtrail_client_us_east_1 = client("cloudtrail", region_name=AWS_REGION) - s3_client_us_east_1 = client("s3", region_name=AWS_REGION) + cloudtrail_client_us_east_1 = client( + "cloudtrail", region_name=AWS_REGION_US_EAST_1 + ) + s3_client_us_east_1 = client("s3", region_name=AWS_REGION_US_EAST_1) trail_name_us = "trail_test_us" bucket_name_us = "bucket_test_us" s3_client_us_east_1.create_bucket(Bucket=bucket_name_us) @@ -232,41 +289,46 @@ class Test_cloudtrail_s3_dataevents_read_enabled: from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( Cloudtrail, ) + from prowler.providers.aws.services.s3.s3_service import S3 - current_audit_info = self.set_mocked_audit_info() + current_audit_info = set_mocked_aws_audit_info() with mock.patch( "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client", + new=Cloudtrail(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.s3_client", + new=S3(current_audit_info), ): - with mock.patch( - "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client", - new=Cloudtrail(current_audit_info), - ): - # Test Check - from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import ( - cloudtrail_s3_dataevents_read_enabled, - ) + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import ( + cloudtrail_s3_dataevents_read_enabled, + ) - check = cloudtrail_s3_dataevents_read_enabled() - result = check.execute() + check = cloudtrail_s3_dataevents_read_enabled() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "PASS" - assert search( - "has an advanced data event selector to record all S3 object-level API operations.", - result[0].status_extended, - ) - assert result[0].resource_id == trail_name_us - assert result[0].resource_arn == trail_us["TrailARN"] - assert result[0].resource_tags == [] - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Trail {trail_name_us} from home region {AWS_REGION_US_EAST_1} has an advanced data event selector to record all S3 object-level API operations." + ) + assert result[0].resource_id == trail_name_us + assert result[0].resource_arn == trail_us["TrailARN"] + assert result[0].resource_tags == [] + assert result[0].region == AWS_REGION_US_EAST_1 @mock_cloudtrail @mock_s3 def test_trail_with_s3_three_colons(self): - cloudtrail_client_us_east_1 = client("cloudtrail", region_name=AWS_REGION) - s3_client_us_east_1 = client("s3", region_name=AWS_REGION) + cloudtrail_client_us_east_1 = client( + "cloudtrail", region_name=AWS_REGION_US_EAST_1 + ) + s3_client_us_east_1 = client("s3", region_name=AWS_REGION_US_EAST_1) trail_name_us = "trail_test_us" bucket_name_us = "bucket_test_us" s3_client_us_east_1.create_bucket(Bucket=bucket_name_us) @@ -295,32 +357,35 @@ class Test_cloudtrail_s3_dataevents_read_enabled: from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( Cloudtrail, ) + from prowler.providers.aws.services.s3.s3_service import S3 - current_audit_info = self.set_mocked_audit_info() + current_audit_info = set_mocked_aws_audit_info() with mock.patch( "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client", + new=Cloudtrail(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.s3_client", + new=S3(current_audit_info), ): - with mock.patch( - "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled.cloudtrail_client", - new=Cloudtrail(current_audit_info), - ): - # Test Check - from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import ( - cloudtrail_s3_dataevents_read_enabled, - ) + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_read_enabled.cloudtrail_s3_dataevents_read_enabled import ( + cloudtrail_s3_dataevents_read_enabled, + ) - check = cloudtrail_s3_dataevents_read_enabled() - result = check.execute() + check = cloudtrail_s3_dataevents_read_enabled() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "PASS" - assert search( - "has a classic data event selector to record all S3 object-level API operations.", - result[0].status_extended, - ) - assert result[0].resource_id == trail_name_us - assert result[0].resource_arn == trail_us["TrailARN"] - assert result[0].resource_tags == [] - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Trail {trail_name_us} from home region {AWS_REGION_US_EAST_1} has a classic data event selector to record all S3 object-level API operations." + ) + assert result[0].resource_id == trail_name_us + assert result[0].resource_arn == trail_us["TrailARN"] + assert result[0].resource_tags == [] + assert result[0].region == AWS_REGION_US_EAST_1 diff --git a/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled_test.py b/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled_test.py index f811db1b..a7def7b8 100644 --- a/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled_test.py +++ b/tests/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled_test.py @@ -1,52 +1,23 @@ -from re import search from unittest import mock -from boto3 import client, session +from boto3 import client from moto import mock_cloudtrail, mock_s3 -from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info -from prowler.providers.common.models import Audit_Metadata - -AWS_ACCOUNT_NUMBER = "123456789012" -AWS_REGION = "us-east-1" +from tests.providers.aws.audit_info_utils import ( + AWS_ACCOUNT_NUMBER, + AWS_REGION_US_EAST_1, + set_mocked_aws_audit_info, +) class Test_cloudtrail_s3_dataevents_write_enabled: - def set_mocked_audit_info(self): - audit_info = AWS_Audit_Info( - session_config=None, - original_session=None, - audit_session=session.Session( - profile_name=None, - botocore_session=None, - ), - audited_account=AWS_ACCOUNT_NUMBER, - audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root", - audited_user_id=None, - audited_partition="aws", - audited_identity_arn=None, - profile=None, - profile_region=None, - credentials=None, - assumed_role_info=None, - audited_regions=[AWS_REGION], - organizations_metadata=None, - audit_resources=None, - mfa_enabled=False, - audit_metadata=Audit_Metadata( - services_scanned=0, - expected_checks=[], - completed_checks=0, - audit_progress=0, - ), - ) - return audit_info - @mock_cloudtrail @mock_s3 def test_trail_without_data_events(self): - cloudtrail_client_us_east_1 = client("cloudtrail", region_name=AWS_REGION) - s3_client_us_east_1 = client("s3", region_name=AWS_REGION) + cloudtrail_client_us_east_1 = client( + "cloudtrail", region_name=AWS_REGION_US_EAST_1 + ) + s3_client_us_east_1 = client("s3", region_name=AWS_REGION_US_EAST_1) trail_name_us = "trail_test_us" bucket_name_us = "bucket_test_us" s3_client_us_east_1.create_bucket(Bucket=bucket_name_us) @@ -57,43 +28,46 @@ class Test_cloudtrail_s3_dataevents_write_enabled: from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( Cloudtrail, ) + from prowler.providers.aws.services.s3.s3_service import S3 - current_audit_info = self.set_mocked_audit_info() + current_audit_info = set_mocked_aws_audit_info() with mock.patch( "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client", + new=Cloudtrail(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.s3_client", + new=S3(current_audit_info), ): - with mock.patch( - "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client", - new=Cloudtrail(current_audit_info), - ): - # Test Check - from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import ( - cloudtrail_s3_dataevents_write_enabled, - ) + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import ( + cloudtrail_s3_dataevents_write_enabled, + ) - check = cloudtrail_s3_dataevents_write_enabled() - result = check.execute() + check = cloudtrail_s3_dataevents_write_enabled() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "FAIL" - assert search( - "No CloudTrail trails have a data event to record all S3 object-level API operations.", - result[0].status_extended, - ) - assert result[0].resource_id == AWS_ACCOUNT_NUMBER - assert ( - result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" - ) - assert result[0].resource_tags == [] - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "No CloudTrail trails have a data event to record all S3 object-level API operations." + ) + assert result[0].resource_id == AWS_ACCOUNT_NUMBER + assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + assert result[0].resource_tags == [] + assert result[0].region == AWS_REGION_US_EAST_1 @mock_cloudtrail @mock_s3 def test_trail_without_s3_data_events(self): - cloudtrail_client_us_east_1 = client("cloudtrail", region_name=AWS_REGION) - s3_client_us_east_1 = client("s3", region_name=AWS_REGION) + cloudtrail_client_us_east_1 = client( + "cloudtrail", region_name=AWS_REGION_US_EAST_1 + ) + s3_client_us_east_1 = client("s3", region_name=AWS_REGION_US_EAST_1) trail_name_us = "trail_test_us" bucket_name_us = "bucket_test_us" s3_client_us_east_1.create_bucket(Bucket=bucket_name_us) @@ -112,46 +86,124 @@ class Test_cloudtrail_s3_dataevents_write_enabled: } ], )["EventSelectors"] + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( Cloudtrail, ) + from prowler.providers.aws.services.s3.s3_service import S3 - current_audit_info = self.set_mocked_audit_info() + current_audit_info = set_mocked_aws_audit_info() with mock.patch( "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client", + new=Cloudtrail(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.s3_client", + new=S3(current_audit_info), ): - with mock.patch( - "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client", - new=Cloudtrail(current_audit_info), - ): - # Test Check - from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import ( - cloudtrail_s3_dataevents_write_enabled, - ) + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import ( + cloudtrail_s3_dataevents_write_enabled, + ) - check = cloudtrail_s3_dataevents_write_enabled() - result = check.execute() + check = cloudtrail_s3_dataevents_write_enabled() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "FAIL" - assert search( - "No CloudTrail trails have a data event to record all S3 object-level API operations.", - result[0].status_extended, - ) - assert result[0].resource_id == AWS_ACCOUNT_NUMBER - assert ( - result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" - ) - assert result[0].resource_tags == [] - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "No CloudTrail trails have a data event to record all S3 object-level API operations." + ) + assert result[0].resource_id == AWS_ACCOUNT_NUMBER + assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + assert result[0].resource_tags == [] + assert result[0].region == AWS_REGION_US_EAST_1 + + @mock_cloudtrail + @mock_s3 + def test_trail_without_s3_data_events_ignoring(self): + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + from prowler.providers.aws.services.s3.s3_service import S3 + + current_audit_info = set_mocked_aws_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client", + new=Cloudtrail(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.s3_client", + new=S3(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import ( + cloudtrail_s3_dataevents_write_enabled, + ) + + check = cloudtrail_s3_dataevents_write_enabled() + result = check.execute() + + assert len(result) == 0 + + @mock_cloudtrail + @mock_s3 + def test_trail_without_s3_data_events_ignoring_with_buckets(self): + s3_client_us_east_1 = client("s3", region_name=AWS_REGION_US_EAST_1) + bucket_name_us = "bucket_test_us" + s3_client_us_east_1.create_bucket(Bucket=bucket_name_us) + from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( + Cloudtrail, + ) + from prowler.providers.aws.services.s3.s3_service import S3 + + current_audit_info = set_mocked_aws_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client", + new=Cloudtrail(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.s3_client", + new=S3(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import ( + cloudtrail_s3_dataevents_write_enabled, + ) + + check = cloudtrail_s3_dataevents_write_enabled() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "No CloudTrail trails have a data event to record all S3 object-level API operations." + ) + assert result[0].resource_id == AWS_ACCOUNT_NUMBER + assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + assert result[0].resource_tags == [] + assert result[0].region == AWS_REGION_US_EAST_1 @mock_cloudtrail @mock_s3 def test_trail_with_s3_data_events(self): - cloudtrail_client_us_east_1 = client("cloudtrail", region_name=AWS_REGION) - s3_client_us_east_1 = client("s3", region_name=AWS_REGION) + cloudtrail_client_us_east_1 = client( + "cloudtrail", region_name=AWS_REGION_US_EAST_1 + ) + s3_client_us_east_1 = client("s3", region_name=AWS_REGION_US_EAST_1) trail_name_us = "trail_test_us" bucket_name_us = "bucket_test_us" s3_client_us_east_1.create_bucket(Bucket=bucket_name_us) @@ -174,41 +226,46 @@ class Test_cloudtrail_s3_dataevents_write_enabled: from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( Cloudtrail, ) + from prowler.providers.aws.services.s3.s3_service import S3 - current_audit_info = self.set_mocked_audit_info() + current_audit_info = set_mocked_aws_audit_info() with mock.patch( "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client", + new=Cloudtrail(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.s3_client", + new=S3(current_audit_info), ): - with mock.patch( - "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client", - new=Cloudtrail(current_audit_info), - ): - # Test Check - from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import ( - cloudtrail_s3_dataevents_write_enabled, - ) + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import ( + cloudtrail_s3_dataevents_write_enabled, + ) - check = cloudtrail_s3_dataevents_write_enabled() - result = check.execute() + check = cloudtrail_s3_dataevents_write_enabled() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "PASS" - assert search( - "has a classic data event selector to record all S3 object-level API operations.", - result[0].status_extended, - ) - assert result[0].resource_id == trail_name_us - assert result[0].resource_arn == trail_us["TrailARN"] - assert result[0].resource_tags == [] - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Trail {trail_name_us} from home region {AWS_REGION_US_EAST_1} has a classic data event selector to record all S3 object-level API operations." + ) + assert result[0].resource_id == trail_name_us + assert result[0].resource_arn == trail_us["TrailARN"] + assert result[0].resource_tags == [] + assert result[0].region == AWS_REGION_US_EAST_1 @mock_cloudtrail @mock_s3 def test_trail_with_s3_advanced_data_events(self): - cloudtrail_client_us_east_1 = client("cloudtrail", region_name=AWS_REGION) - s3_client_us_east_1 = client("s3", region_name=AWS_REGION) + cloudtrail_client_us_east_1 = client( + "cloudtrail", region_name=AWS_REGION_US_EAST_1 + ) + s3_client_us_east_1 = client("s3", region_name=AWS_REGION_US_EAST_1) trail_name_us = "trail_test_us" bucket_name_us = "bucket_test_us" s3_client_us_east_1.create_bucket(Bucket=bucket_name_us) @@ -230,41 +287,46 @@ class Test_cloudtrail_s3_dataevents_write_enabled: from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( Cloudtrail, ) + from prowler.providers.aws.services.s3.s3_service import S3 - current_audit_info = self.set_mocked_audit_info() + current_audit_info = set_mocked_aws_audit_info() with mock.patch( "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client", + new=Cloudtrail(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.s3_client", + new=S3(current_audit_info), ): - with mock.patch( - "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client", - new=Cloudtrail(current_audit_info), - ): - # Test Check - from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import ( - cloudtrail_s3_dataevents_write_enabled, - ) + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import ( + cloudtrail_s3_dataevents_write_enabled, + ) - check = cloudtrail_s3_dataevents_write_enabled() - result = check.execute() + check = cloudtrail_s3_dataevents_write_enabled() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "PASS" - assert search( - "has an advanced data event selector to record all S3 object-level API operations.", - result[0].status_extended, - ) - assert result[0].resource_id == trail_name_us - assert result[0].resource_arn == trail_us["TrailARN"] - assert result[0].resource_tags == [] - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Trail {trail_name_us} from home region {AWS_REGION_US_EAST_1} has an advanced data event selector to record all S3 object-level API operations." + ) + assert result[0].resource_id == trail_name_us + assert result[0].resource_arn == trail_us["TrailARN"] + assert result[0].resource_tags == [] + assert result[0].region == AWS_REGION_US_EAST_1 @mock_cloudtrail @mock_s3 def test_trail_with_s3_three_colons(self): - cloudtrail_client_us_east_1 = client("cloudtrail", region_name=AWS_REGION) - s3_client_us_east_1 = client("s3", region_name=AWS_REGION) + cloudtrail_client_us_east_1 = client( + "cloudtrail", region_name=AWS_REGION_US_EAST_1 + ) + s3_client_us_east_1 = client("s3", region_name=AWS_REGION_US_EAST_1) trail_name_us = "trail_test_us" bucket_name_us = "bucket_test_us" s3_client_us_east_1.create_bucket(Bucket=bucket_name_us) @@ -293,32 +355,35 @@ class Test_cloudtrail_s3_dataevents_write_enabled: from prowler.providers.aws.services.cloudtrail.cloudtrail_service import ( Cloudtrail, ) + from prowler.providers.aws.services.s3.s3_service import S3 - current_audit_info = self.set_mocked_audit_info() + current_audit_info = set_mocked_aws_audit_info() with mock.patch( "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client", + new=Cloudtrail(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.s3_client", + new=S3(current_audit_info), ): - with mock.patch( - "prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled.cloudtrail_client", - new=Cloudtrail(current_audit_info), - ): - # Test Check - from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import ( - cloudtrail_s3_dataevents_write_enabled, - ) + # Test Check + from prowler.providers.aws.services.cloudtrail.cloudtrail_s3_dataevents_write_enabled.cloudtrail_s3_dataevents_write_enabled import ( + cloudtrail_s3_dataevents_write_enabled, + ) - check = cloudtrail_s3_dataevents_write_enabled() - result = check.execute() + check = cloudtrail_s3_dataevents_write_enabled() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "PASS" - assert search( - "has a classic data event selector to record all S3 object-level API operations.", - result[0].status_extended, - ) - assert result[0].resource_id == trail_name_us - assert result[0].resource_arn == trail_us["TrailARN"] - assert result[0].resource_tags == [] - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Trail {trail_name_us} from home region {AWS_REGION_US_EAST_1} has a classic data event selector to record all S3 object-level API operations." + ) + assert result[0].resource_id == trail_name_us + assert result[0].resource_arn == trail_us["TrailARN"] + assert result[0].resource_tags == [] + assert result[0].region == AWS_REGION_US_EAST_1 diff --git a/tests/providers/aws/services/ec2/ec2_ebs_default_encryption/ec2_ebs_default_encryption_test.py b/tests/providers/aws/services/ec2/ec2_ebs_default_encryption/ec2_ebs_default_encryption_test.py index b3317a36..3e2ef101 100644 --- a/tests/providers/aws/services/ec2/ec2_ebs_default_encryption/ec2_ebs_default_encryption_test.py +++ b/tests/providers/aws/services/ec2/ec2_ebs_default_encryption/ec2_ebs_default_encryption_test.py @@ -1,6 +1,6 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info @@ -110,3 +110,63 @@ class Test_ec2_ebs_default_encryption: ) assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + + @mock_ec2 + def test_ec2_ebs_encryption_disabled_ignored(self): + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_ebs_default_encryption.ec2_ebs_default_encryption.ec2_client", + new=EC2(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_ebs_default_encryption.ec2_ebs_default_encryption import ( + ec2_ebs_default_encryption, + ) + + check = ec2_ebs_default_encryption() + result = check.execute() + + # One result per region + assert len(result) == 0 + + @mock_ec2 + def test_ec2_ebs_encryption_disabled_ignoring_with_volumes(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + ec2.create_volume(Size=36, AvailabilityZone=f"{AWS_REGION}a") + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_ebs_default_encryption.ec2_ebs_default_encryption.ec2_client", + new=EC2(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_ebs_default_encryption.ec2_ebs_default_encryption import ( + ec2_ebs_default_encryption, + ) + + check = ec2_ebs_default_encryption() + result = check.execute() + + # One result per region + assert len(result) == 1 + assert result[0].region == AWS_REGION + assert result[0].status == "FAIL" + assert ( + result[0].status_extended == "EBS Default Encryption is not activated." + ) + assert result[0].resource_id == AWS_ACCOUNT_NUMBER + assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" diff --git a/tests/providers/aws/services/ec2/ec2_networkacl_allow_ingress_any_port/ec2_networkacl_allow_ingress_any_port_test.py b/tests/providers/aws/services/ec2/ec2_networkacl_allow_ingress_any_port/ec2_networkacl_allow_ingress_any_port_test.py index e63c4534..829495b9 100644 --- a/tests/providers/aws/services/ec2/ec2_networkacl_allow_ingress_any_port/ec2_networkacl_allow_ingress_any_port_test.py +++ b/tests/providers/aws/services/ec2/ec2_networkacl_allow_ingress_any_port/ec2_networkacl_allow_ingress_any_port_test.py @@ -204,3 +204,97 @@ class Test_ec2_networkacl_allow_ingress_any_port: nacl.resource_arn == f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}" ) + + @mock_ec2 + def test_ec2_non_compliant_nacl_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + vpc_id = ec2_client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"] + nacl_id = ec2_client.create_network_acl(VpcId=vpc_id)["NetworkAcl"][ + "NetworkAclId" + ] + ec2_client.create_network_acl_entry( + NetworkAclId=nacl_id, + RuleNumber=100, + Protocol="-1", + RuleAction="allow", + Egress=False, + CidrBlock="0.0.0.0/0", + ) + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_networkacl_allow_ingress_any_port.ec2_networkacl_allow_ingress_any_port.ec2_client", + new=EC2(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_networkacl_allow_ingress_any_port.ec2_networkacl_allow_ingress_any_port import ( + ec2_networkacl_allow_ingress_any_port, + ) + + check = ec2_networkacl_allow_ingress_any_port() + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_non_compliant_nacl_ignoring_with_sgs(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + vpc_id = ec2_client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"] + nacl_id = ec2_client.create_network_acl(VpcId=vpc_id)["NetworkAcl"][ + "NetworkAclId" + ] + ec2_client.create_network_acl_entry( + NetworkAclId=nacl_id, + RuleNumber=100, + Protocol="-1", + RuleAction="allow", + Egress=False, + CidrBlock="0.0.0.0/0", + ) + ec2_client.create_security_group(GroupName="sg", Description="test") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_networkacl_allow_ingress_any_port.ec2_networkacl_allow_ingress_any_port.ec2_client", + new=EC2(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_networkacl_allow_ingress_any_port.ec2_networkacl_allow_ingress_any_port import ( + ec2_networkacl_allow_ingress_any_port, + ) + + check = ec2_networkacl_allow_ingress_any_port() + result = check.execute() + + # One default sg per region + default of new VPC + new NACL + assert len(result) == 3 + # Search changed sg + for nacl in result: + if nacl.resource_id == nacl_id: + assert nacl.status == "FAIL" + assert result[0].region in (AWS_REGION, "eu-west-1") + assert result[0].resource_tags == [] + assert ( + nacl.status_extended + == f"Network ACL {nacl_id} has every port open to the Internet." + ) + assert ( + nacl.resource_arn + == f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}" + ) diff --git a/tests/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_22/ec2_networkacl_allow_ingress_tcp_port_22_test.py b/tests/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_22/ec2_networkacl_allow_ingress_tcp_port_22_test.py index 4837385d..3428a526 100644 --- a/tests/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_22/ec2_networkacl_allow_ingress_tcp_port_22_test.py +++ b/tests/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_22/ec2_networkacl_allow_ingress_tcp_port_22_test.py @@ -206,3 +206,97 @@ class Test_ec2_networkacl_allow_ingress_tcp_port_22: nacl.resource_arn == f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}" ) + + @mock_ec2 + def test_ec2_non_compliant_nacl_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + vpc_id = ec2_client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"] + nacl_id = ec2_client.create_network_acl(VpcId=vpc_id)["NetworkAcl"][ + "NetworkAclId" + ] + ec2_client.create_network_acl_entry( + NetworkAclId=nacl_id, + RuleNumber=100, + Protocol="-1", + RuleAction="allow", + Egress=False, + CidrBlock="0.0.0.0/0", + ) + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_networkacl_allow_ingress_tcp_port_22.ec2_networkacl_allow_ingress_tcp_port_22.ec2_client", + new=EC2(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_networkacl_allow_ingress_tcp_port_22.ec2_networkacl_allow_ingress_tcp_port_22 import ( + ec2_networkacl_allow_ingress_tcp_port_22, + ) + + check = ec2_networkacl_allow_ingress_tcp_port_22() + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_non_compliant_nacl_ignoring_with_sgs(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + vpc_id = ec2_client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"] + nacl_id = ec2_client.create_network_acl(VpcId=vpc_id)["NetworkAcl"][ + "NetworkAclId" + ] + ec2_client.create_network_acl_entry( + NetworkAclId=nacl_id, + RuleNumber=100, + Protocol="-1", + RuleAction="allow", + Egress=False, + CidrBlock="0.0.0.0/0", + ) + ec2_client.create_security_group(GroupName="sg", Description="test") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_networkacl_allow_ingress_tcp_port_22.ec2_networkacl_allow_ingress_tcp_port_22.ec2_client", + new=EC2(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_networkacl_allow_ingress_tcp_port_22.ec2_networkacl_allow_ingress_tcp_port_22 import ( + ec2_networkacl_allow_ingress_tcp_port_22, + ) + + check = ec2_networkacl_allow_ingress_tcp_port_22() + result = check.execute() + + # One default sg per region + default of new VPC + new NACL + assert len(result) == 3 + # Search changed sg + for nacl in result: + if nacl.resource_id == nacl_id: + assert nacl.status == "FAIL" + assert result[0].region in (AWS_REGION, "eu-west-1") + assert result[0].resource_tags == [] + assert ( + nacl.status_extended + == f"Network ACL {nacl_id} has SSH port 22 open to the Internet." + ) + assert ( + nacl.resource_arn + == f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}" + ) diff --git a/tests/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_3389/ec2_networkacl_allow_ingress_tcp_port_3389_test.py b/tests/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_3389/ec2_networkacl_allow_ingress_tcp_port_3389_test.py index a53eeeaa..d7f76c7c 100644 --- a/tests/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_3389/ec2_networkacl_allow_ingress_tcp_port_3389_test.py +++ b/tests/providers/aws/services/ec2/ec2_networkacl_allow_ingress_tcp_port_3389/ec2_networkacl_allow_ingress_tcp_port_3389_test.py @@ -206,3 +206,97 @@ class Test_ec2_networkacl_allow_ingress_tcp_port_3389: nacl.resource_arn == f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}" ) + + @mock_ec2 + def test_ec2_non_compliant_nacl_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + vpc_id = ec2_client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"] + nacl_id = ec2_client.create_network_acl(VpcId=vpc_id)["NetworkAcl"][ + "NetworkAclId" + ] + ec2_client.create_network_acl_entry( + NetworkAclId=nacl_id, + RuleNumber=100, + Protocol="-1", + RuleAction="allow", + Egress=False, + CidrBlock="0.0.0.0/0", + ) + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_networkacl_allow_ingress_tcp_port_3389.ec2_networkacl_allow_ingress_tcp_port_3389.ec2_client", + new=EC2(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_networkacl_allow_ingress_tcp_port_3389.ec2_networkacl_allow_ingress_tcp_port_3389 import ( + ec2_networkacl_allow_ingress_tcp_port_3389, + ) + + check = ec2_networkacl_allow_ingress_tcp_port_3389() + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_non_compliant_nacl_ignoring_with_sgs(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + vpc_id = ec2_client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"] + nacl_id = ec2_client.create_network_acl(VpcId=vpc_id)["NetworkAcl"][ + "NetworkAclId" + ] + ec2_client.create_network_acl_entry( + NetworkAclId=nacl_id, + RuleNumber=100, + Protocol="-1", + RuleAction="allow", + Egress=False, + CidrBlock="0.0.0.0/0", + ) + ec2_client.create_security_group(GroupName="sg", Description="test") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_networkacl_allow_ingress_tcp_port_3389.ec2_networkacl_allow_ingress_tcp_port_3389.ec2_client", + new=EC2(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_networkacl_allow_ingress_tcp_port_3389.ec2_networkacl_allow_ingress_tcp_port_3389 import ( + ec2_networkacl_allow_ingress_tcp_port_3389, + ) + + check = ec2_networkacl_allow_ingress_tcp_port_3389() + result = check.execute() + + # One default sg per region + default of new VPC + new NACL + assert len(result) == 3 + # Search changed sg + for nacl in result: + if nacl.resource_id == nacl_id: + assert nacl.status == "FAIL" + assert result[0].region in (AWS_REGION, "eu-west-1") + assert result[0].resource_tags == [] + assert ( + nacl.status_extended + == f"Network ACL {nacl_id} has Microsoft RDP port 3389 open to the Internet." + ) + assert ( + nacl.resource_arn + == f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}" + ) diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_any_port/ec2_securitygroup_allow_ingress_from_internet_to_any_port_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_any_port/ec2_securitygroup_allow_ingress_from_internet_to_any_port_test.py index 6aa6ab68..9a53db14 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_any_port/ec2_securitygroup_allow_ingress_from_internet_to_any_port_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_any_port/ec2_securitygroup_allow_ingress_from_internet_to_any_port_test.py @@ -1,9 +1,10 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -60,6 +61,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_any_port: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port import ( @@ -106,6 +110,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_any_port: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port import ( @@ -163,6 +170,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_any_port: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port import ( @@ -225,6 +235,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_any_port: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port import ( @@ -251,3 +264,74 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_any_port: ) assert sg.resource_details == default_sg_name assert sg.resource_tags == [] + + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port import ( + ec2_securitygroup_allow_ingress_from_internet_to_any_port, + ) + + check = ec2_securitygroup_allow_ingress_from_internet_to_any_port() + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_any_port.ec2_securitygroup_allow_ingress_from_internet_to_any_port import ( + ec2_securitygroup_allow_ingress_from_internet_to_any_port, + ) + + check = ec2_securitygroup_allow_ingress_from_internet_to_any_port() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018_test.py index 23ef0392..a61c8f75 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018/ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018_test.py @@ -1,9 +1,10 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -58,6 +59,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_2 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018 import ( @@ -108,6 +112,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_2 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018 import ( @@ -169,6 +176,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_2 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018 import ( @@ -197,3 +207,78 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_2 ) assert sg.resource_details == default_sg_name assert sg.resource_tags == [] + + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018 import ( + ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018() + ) + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018.ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018 import ( + ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018() + ) + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21_test.py index 667ac4e8..2a199b8e 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21/ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21_test.py @@ -1,9 +1,10 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -58,6 +59,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21 import ( @@ -108,6 +112,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21 import ( @@ -169,6 +176,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21 import ( @@ -197,3 +207,78 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21: ) assert sg.resource_details == default_sg_name assert sg.resource_tags == [] + + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21() + ) + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21.ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21() + ) + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22_test.py index e15cab31..74ea0d6f 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22_test.py @@ -1,10 +1,11 @@ from re import search from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -59,6 +60,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22 import ( @@ -107,6 +111,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22 import ( @@ -170,6 +177,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22 import ( @@ -196,3 +206,74 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22: ) assert sg.resource_details == default_sg_name assert sg.resource_tags == [] + + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22, + ) + + check = ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22() + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22, + ) + + check = ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389_test.py index 3a083993..6240e45a 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389_test.py @@ -1,9 +1,10 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -58,6 +59,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389 import ( @@ -74,6 +78,77 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389: assert result[1].status == "PASS" assert result[2].status == "PASS" + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389, + ) + + check = ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389() + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389, + ) + + check = ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION + @mock_ec2 def test_ec2_non_compliant_default_sg(self): # Create EC2 Mocked Resources @@ -106,6 +181,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389 import ( @@ -165,6 +243,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389 import ( diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888_test.py index 6c0dd067..a2a5c0f2 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888_test.py @@ -1,9 +1,10 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -58,6 +59,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888 import ( @@ -108,6 +112,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888 import ( @@ -169,6 +176,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888 import ( @@ -197,3 +207,78 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7 ) assert sg.resource_details == default_sg_name assert sg.resource_tags == [] + + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888() + ) + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9160_8888() + ) + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601_test.py index b35a85bd..e30e7e76 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601_test.py @@ -1,9 +1,10 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -58,6 +59,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsear ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601 import ( @@ -108,6 +112,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsear ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601 import ( @@ -169,6 +176,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsear ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601 import ( @@ -197,3 +207,78 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsear ) assert sg.resource_details == default_sg_name assert sg.resource_tags == [] + + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601() + ) + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601() + ) + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092_test.py index 0702fbaf..355f8e72 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092_test.py @@ -1,9 +1,10 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -58,6 +59,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092 import ( @@ -108,6 +112,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092 import ( @@ -169,6 +176,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092 import ( @@ -197,3 +207,78 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092: ) assert sg.resource_details == default_sg_name assert sg.resource_tags == [] + + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092() + ) + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092() + ) + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211_test.py index 5ff87d75..dbd12a22 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211_test.py @@ -1,9 +1,10 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -58,6 +59,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_1 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211 import ( @@ -108,6 +112,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_1 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211 import ( @@ -169,6 +176,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_1 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211 import ( @@ -197,3 +207,78 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_1 ) assert sg.resource_details == default_sg_name assert sg.resource_tags == [] + + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211() + ) + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211() + ) + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306_test.py index 67d9abf7..b2b0ea65 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306_test.py @@ -1,9 +1,10 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -58,6 +59,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306 import ( @@ -108,6 +112,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306 import ( @@ -169,6 +176,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306 import ( @@ -197,3 +207,78 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306: ) assert sg.resource_details == default_sg_name assert sg.resource_tags == [] + + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306() + ) + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306() + ) + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483_test.py index 6e131681..5872d3dd 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483_test.py @@ -1,9 +1,10 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -58,6 +59,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483 import ( @@ -108,6 +112,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483 import ( @@ -169,6 +176,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483 import ( @@ -197,3 +207,78 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521 ) assert sg.resource_details == default_sg_name assert sg.resource_tags == [] + + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483() + ) + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483() + ) + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432_test.py index 2e984b96..0cf89295 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432_test.py @@ -1,9 +1,10 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -58,6 +59,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_54 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432 import ( @@ -108,6 +112,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_54 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432 import ( @@ -169,6 +176,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_54 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432 import ( @@ -235,6 +245,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_54 ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432 import ( @@ -263,3 +276,78 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_54 ) assert sg.resource_details == default_sg_name assert sg.resource_tags == [] + + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432() + ) + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432() + ) + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379_test.py index 97f87c56..561046a4 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379_test.py @@ -1,9 +1,10 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -58,6 +59,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379 import ( @@ -108,6 +112,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379 import ( @@ -169,6 +176,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379 import ( @@ -197,3 +207,75 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379: ) assert sg.resource_details == default_sg_name assert sg.resource_tags == [] + + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_client", + new=EC2(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379() + ) + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379() + ) + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434_test.py index b8a7439c..9cfc1495 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434_test.py @@ -1,9 +1,10 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -58,6 +59,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_ ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434 import ( @@ -108,6 +112,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_ ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434 import ( @@ -169,6 +176,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_ ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434 import ( @@ -197,3 +207,78 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_ ) assert sg.resource_details == default_sg_name assert sg.resource_tags == [] + + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434() + ) + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_1434() + ) + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23_test.py index 8852b206..d7094ce0 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23/ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23_test.py @@ -1,9 +1,10 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.vpc.vpc_service import VPC from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" @@ -58,6 +59,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23 import ( @@ -108,6 +112,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23 import ( @@ -169,6 +176,9 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23: ), mock.patch( "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_client", new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.vpc_client", + new=VPC(current_audit_info), ): # Test Check from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23 import ( @@ -197,3 +207,78 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23: ) assert sg.resource_details == default_sg_name assert sg.resource_tags == [] + + @mock_ec2 + def test_ec2_default_sgs_ignoring(self): + # Create EC2 Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + ec2_client.create_vpc(CidrBlock="10.0.0.0/16") + + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23() + ) + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_ec2_default_sgs_ignoring_vpc_in_use(self): + # Create EC2 Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + ec2_client = client("ec2", region_name=AWS_REGION) + default_sg = ec2_client.describe_security_groups(GroupNames=["default"])[ + "SecurityGroups" + ][0] + default_sg["GroupId"] + default_sg["GroupName"] + from prowler.providers.aws.services.ec2.ec2_service import EC2 + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_client", + new=EC2(current_audit_info), + ), mock.patch( + "prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.ec2.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23.ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23 import ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23, + ) + + check = ( + ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23() + ) + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/ecr/ecr_registry_scan_images_on_push_enabled/ecr_registry_scan_images_on_push_enabled_test.py b/tests/providers/aws/services/ecr/ecr_registry_scan_images_on_push_enabled/ecr_registry_scan_images_on_push_enabled_test.py index 10d9de36..a04412b7 100644 --- a/tests/providers/aws/services/ecr/ecr_registry_scan_images_on_push_enabled/ecr_registry_scan_images_on_push_enabled_test.py +++ b/tests/providers/aws/services/ecr/ecr_registry_scan_images_on_push_enabled/ecr_registry_scan_images_on_push_enabled_test.py @@ -1,11 +1,15 @@ from re import search from unittest import mock +from boto3 import session + +from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info from prowler.providers.aws.services.ecr.ecr_service import ( Registry, Repository, ScanningRule, ) +from prowler.providers.common.models import Audit_Metadata # Mock Test Region AWS_REGION = "eu-west-1" @@ -17,12 +21,45 @@ repository_arn = ( class Test_ecr_registry_scan_images_on_push_enabled: + def set_mocked_audit_info(self): + audit_info = AWS_Audit_Info( + session_config=None, + original_session=None, + audit_session=session.Session( + profile_name=None, + botocore_session=None, + ), + audited_account=None, + audited_account_arn=None, + audited_user_id=None, + audited_partition="aws", + audited_identity_arn=None, + profile=None, + profile_region=None, + credentials=None, + assumed_role_info=None, + audited_regions=None, + organizations_metadata=None, + audit_resources=None, + mfa_enabled=False, + audit_metadata=Audit_Metadata( + services_scanned=0, + expected_checks=[], + completed_checks=0, + audit_progress=0, + ), + ) + return audit_info + def test_no_registries(self): ecr_client = mock.MagicMock ecr_client.registries = {} with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_registry_scan_images_on_push_enabled.ecr_registry_scan_images_on_push_enabled.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_registry_scan_images_on_push_enabled.ecr_registry_scan_images_on_push_enabled import ( @@ -45,7 +82,10 @@ class Test_ecr_registry_scan_images_on_push_enabled: ) with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_registry_scan_images_on_push_enabled.ecr_registry_scan_images_on_push_enabled.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_registry_scan_images_on_push_enabled.ecr_registry_scan_images_on_push_enabled import ( @@ -83,7 +123,10 @@ class Test_ecr_registry_scan_images_on_push_enabled: ) with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_registry_scan_images_on_push_enabled.ecr_registry_scan_images_on_push_enabled.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_registry_scan_images_on_push_enabled.ecr_registry_scan_images_on_push_enabled import ( @@ -125,7 +168,10 @@ class Test_ecr_registry_scan_images_on_push_enabled: ) with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_registry_scan_images_on_push_enabled.ecr_registry_scan_images_on_push_enabled.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_registry_scan_images_on_push_enabled.ecr_registry_scan_images_on_push_enabled import ( @@ -165,7 +211,10 @@ class Test_ecr_registry_scan_images_on_push_enabled: ) with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_registry_scan_images_on_push_enabled.ecr_registry_scan_images_on_push_enabled.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_registry_scan_images_on_push_enabled.ecr_registry_scan_images_on_push_enabled import ( diff --git a/tests/providers/aws/services/ecr/ecr_repositories_lifecycle_policy_enabled/ecr_repositories_lifecycle_policy_enabled_test.py b/tests/providers/aws/services/ecr/ecr_repositories_lifecycle_policy_enabled/ecr_repositories_lifecycle_policy_enabled_test.py index 11692d4e..15270784 100644 --- a/tests/providers/aws/services/ecr/ecr_repositories_lifecycle_policy_enabled/ecr_repositories_lifecycle_policy_enabled_test.py +++ b/tests/providers/aws/services/ecr/ecr_repositories_lifecycle_policy_enabled/ecr_repositories_lifecycle_policy_enabled_test.py @@ -1,6 +1,10 @@ from unittest import mock +from boto3 import session + +from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info from prowler.providers.aws.services.ecr.ecr_service import Registry, Repository +from prowler.providers.common.models import Audit_Metadata # Mock Test Region AWS_REGION = "eu-west-1" @@ -23,12 +27,46 @@ repo_policy_public = { class Test_ecr_repositories_lifecycle_policy_enabled: + # Mocked Audit Info + def set_mocked_audit_info(self): + audit_info = AWS_Audit_Info( + session_config=None, + original_session=None, + audit_session=session.Session( + profile_name=None, + botocore_session=None, + ), + audited_account=None, + audited_account_arn=None, + audited_user_id=None, + audited_partition="aws", + audited_identity_arn=None, + profile=None, + profile_region=None, + credentials=None, + assumed_role_info=None, + audited_regions=None, + organizations_metadata=None, + audit_resources=None, + mfa_enabled=False, + audit_metadata=Audit_Metadata( + services_scanned=0, + expected_checks=[], + completed_checks=0, + audit_progress=0, + ), + ) + return audit_info + def test_no_registries(self): ecr_client = mock.MagicMock ecr_client.registries = {} with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_lifecycle_policy_enabled.ecr_repositories_lifecycle_policy_enabled.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_lifecycle_policy_enabled.ecr_repositories_lifecycle_policy_enabled import ( @@ -51,7 +89,10 @@ class Test_ecr_repositories_lifecycle_policy_enabled: ) with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_lifecycle_policy_enabled.ecr_repositories_lifecycle_policy_enabled.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_lifecycle_policy_enabled.ecr_repositories_lifecycle_policy_enabled import ( @@ -84,7 +125,10 @@ class Test_ecr_repositories_lifecycle_policy_enabled: ) with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_lifecycle_policy_enabled.ecr_repositories_lifecycle_policy_enabled.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_lifecycle_policy_enabled.ecr_repositories_lifecycle_policy_enabled import ( @@ -125,7 +169,10 @@ class Test_ecr_repositories_lifecycle_policy_enabled: ) with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_lifecycle_policy_enabled.ecr_repositories_lifecycle_policy_enabled.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_lifecycle_policy_enabled.ecr_repositories_lifecycle_policy_enabled import ( diff --git a/tests/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_test.py b/tests/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_test.py index 4377f2cf..d6e0310e 100644 --- a/tests/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_test.py +++ b/tests/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_test.py @@ -1,6 +1,10 @@ from unittest import mock +from boto3 import session + +from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info from prowler.providers.aws.services.ecr.ecr_service import Registry, Repository +from prowler.providers.common.models import Audit_Metadata # Mock Test Region AWS_REGION = "eu-west-1" @@ -35,12 +39,46 @@ repo_policy_public = { class Test_ecr_repositories_not_publicly_accessible: + # Mocked Audit Info + def set_mocked_audit_info(self): + audit_info = AWS_Audit_Info( + session_config=None, + original_session=None, + audit_session=session.Session( + profile_name=None, + botocore_session=None, + ), + audited_account=None, + audited_account_arn=None, + audited_user_id=None, + audited_partition="aws", + audited_identity_arn=None, + profile=None, + profile_region=None, + credentials=None, + assumed_role_info=None, + audited_regions=None, + organizations_metadata=None, + audit_resources=None, + mfa_enabled=False, + audit_metadata=Audit_Metadata( + services_scanned=0, + expected_checks=[], + completed_checks=0, + audit_progress=0, + ), + ) + return audit_info + def test_no_registries(self): ecr_client = mock.MagicMock ecr_client.registries = {} with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible import ( @@ -63,7 +101,10 @@ class Test_ecr_repositories_not_publicly_accessible: ) with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible import ( @@ -96,7 +137,10 @@ class Test_ecr_repositories_not_publicly_accessible: ) with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible import ( @@ -136,7 +180,10 @@ class Test_ecr_repositories_not_publicly_accessible: ) with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible import ( diff --git a/tests/providers/aws/services/ecr/ecr_repositories_scan_images_on_push_enabled/ecr_repositories_scan_images_on_push_enabled_test.py b/tests/providers/aws/services/ecr/ecr_repositories_scan_images_on_push_enabled/ecr_repositories_scan_images_on_push_enabled_test.py index 7bf073c6..16a7cb2a 100644 --- a/tests/providers/aws/services/ecr/ecr_repositories_scan_images_on_push_enabled/ecr_repositories_scan_images_on_push_enabled_test.py +++ b/tests/providers/aws/services/ecr/ecr_repositories_scan_images_on_push_enabled/ecr_repositories_scan_images_on_push_enabled_test.py @@ -1,6 +1,10 @@ from unittest import mock +from boto3 import session + +from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info from prowler.providers.aws.services.ecr.ecr_service import Registry, Repository +from prowler.providers.common.models import Audit_Metadata # Mock Test Region AWS_REGION = "eu-west-1" @@ -23,12 +27,46 @@ repo_policy_public = { class Test_ecr_repositories_scan_images_on_push_enabled: + # Mocked Audit Info + def set_mocked_audit_info(self): + audit_info = AWS_Audit_Info( + session_config=None, + original_session=None, + audit_session=session.Session( + profile_name=None, + botocore_session=None, + ), + audited_account=None, + audited_account_arn=None, + audited_user_id=None, + audited_partition="aws", + audited_identity_arn=None, + profile=None, + profile_region=None, + credentials=None, + assumed_role_info=None, + audited_regions=None, + organizations_metadata=None, + audit_resources=None, + mfa_enabled=False, + audit_metadata=Audit_Metadata( + services_scanned=0, + expected_checks=[], + completed_checks=0, + audit_progress=0, + ), + ) + return audit_info + def test_no_registries(self): ecr_client = mock.MagicMock ecr_client.registries = {} with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_images_on_push_enabled.ecr_repositories_scan_images_on_push_enabled.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_images_on_push_enabled.ecr_repositories_scan_images_on_push_enabled import ( @@ -51,7 +89,10 @@ class Test_ecr_repositories_scan_images_on_push_enabled: ) with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_images_on_push_enabled.ecr_repositories_scan_images_on_push_enabled.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_images_on_push_enabled.ecr_repositories_scan_images_on_push_enabled import ( @@ -84,7 +125,10 @@ class Test_ecr_repositories_scan_images_on_push_enabled: ) with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_images_on_push_enabled.ecr_repositories_scan_images_on_push_enabled.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_images_on_push_enabled.ecr_repositories_scan_images_on_push_enabled import ( @@ -124,7 +168,10 @@ class Test_ecr_repositories_scan_images_on_push_enabled: ) with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_images_on_push_enabled.ecr_repositories_scan_images_on_push_enabled.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_images_on_push_enabled.ecr_repositories_scan_images_on_push_enabled import ( diff --git a/tests/providers/aws/services/ecr/ecr_repositories_scan_vulnerabilities_in_latest_image/ecr_repositories_scan_vulnerabilities_in_latest_image_test.py b/tests/providers/aws/services/ecr/ecr_repositories_scan_vulnerabilities_in_latest_image/ecr_repositories_scan_vulnerabilities_in_latest_image_test.py index a089ab9f..5fc62683 100644 --- a/tests/providers/aws/services/ecr/ecr_repositories_scan_vulnerabilities_in_latest_image/ecr_repositories_scan_vulnerabilities_in_latest_image_test.py +++ b/tests/providers/aws/services/ecr/ecr_repositories_scan_vulnerabilities_in_latest_image/ecr_repositories_scan_vulnerabilities_in_latest_image_test.py @@ -1,12 +1,16 @@ from datetime import datetime from unittest import mock +from boto3 import session + +from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info from prowler.providers.aws.services.ecr.ecr_service import ( FindingSeverityCounts, ImageDetails, Registry, Repository, ) +from prowler.providers.common.models import Audit_Metadata # Mock Test Region AWS_REGION = "eu-west-1" @@ -30,12 +34,47 @@ repo_policy_public = { class Test_ecr_repositories_scan_vulnerabilities_in_latest_image: + # Mocked Audit Info + def set_mocked_audit_info(self): + audit_info = AWS_Audit_Info( + session_config=None, + original_session=None, + audit_session=session.Session( + profile_name=None, + botocore_session=None, + ), + audited_account=None, + audited_account_arn=None, + audited_user_id=None, + audited_partition="aws", + audited_identity_arn=None, + profile=None, + profile_region=None, + credentials=None, + assumed_role_info=None, + audited_regions=None, + organizations_metadata=None, + audit_resources=None, + mfa_enabled=False, + audit_metadata=Audit_Metadata( + services_scanned=0, + expected_checks=[], + completed_checks=0, + audit_progress=0, + ), + ) + return audit_info + def test_no_registries(self): ecr_client = mock.MagicMock ecr_client.registries = {} + ecr_client.audit_config = {} with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image import ( @@ -56,9 +95,13 @@ class Test_ecr_repositories_scan_vulnerabilities_in_latest_image: repositories=[], rules=[], ) + ecr_client.audit_config = {} with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image import ( @@ -89,9 +132,13 @@ class Test_ecr_repositories_scan_vulnerabilities_in_latest_image: ], rules=[], ) + ecr_client.audit_config = {} with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image import ( @@ -132,9 +179,13 @@ class Test_ecr_repositories_scan_vulnerabilities_in_latest_image: ], rules=[], ) + ecr_client.audit_config = {} with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image import ( @@ -189,7 +240,10 @@ class Test_ecr_repositories_scan_vulnerabilities_in_latest_image: } with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image import ( @@ -244,7 +298,10 @@ class Test_ecr_repositories_scan_vulnerabilities_in_latest_image: } with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image import ( @@ -299,7 +356,10 @@ class Test_ecr_repositories_scan_vulnerabilities_in_latest_image: } with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image import ( @@ -354,7 +414,10 @@ class Test_ecr_repositories_scan_vulnerabilities_in_latest_image: } with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image import ( @@ -411,7 +474,10 @@ class Test_ecr_repositories_scan_vulnerabilities_in_latest_image: } with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image import ( @@ -459,9 +525,13 @@ class Test_ecr_repositories_scan_vulnerabilities_in_latest_image: ], rules=[], ) + ecr_client.audit_config = {} with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image import ( @@ -509,9 +579,13 @@ class Test_ecr_repositories_scan_vulnerabilities_in_latest_image: ], rules=[], ) + ecr_client.audit_config = {} with mock.patch( - "prowler.providers.aws.services.ecr.ecr_service.ECR", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + self.set_mocked_audit_info(), + ), mock.patch( + "prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_client", ecr_client, ): from prowler.providers.aws.services.ecr.ecr_repositories_scan_vulnerabilities_in_latest_image.ecr_repositories_scan_vulnerabilities_in_latest_image import ( diff --git a/tests/providers/aws/services/glue/glue_data_catalogs_connection_passwords_encryption_enabled/glue_data_catalogs_connection_passwords_encryption_enabled_test.py b/tests/providers/aws/services/glue/glue_data_catalogs_connection_passwords_encryption_enabled/glue_data_catalogs_connection_passwords_encryption_enabled_test.py index a620debd..f1750d05 100644 --- a/tests/providers/aws/services/glue/glue_data_catalogs_connection_passwords_encryption_enabled/glue_data_catalogs_connection_passwords_encryption_enabled_test.py +++ b/tests/providers/aws/services/glue/glue_data_catalogs_connection_passwords_encryption_enabled/glue_data_catalogs_connection_passwords_encryption_enabled_test.py @@ -1,14 +1,52 @@ -from re import search from unittest import mock -from prowler.providers.aws.services.glue.glue_service import CatalogEncryptionSetting +from boto3 import session +from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.glue.glue_service import CatalogEncryptionSetting +from prowler.providers.common.models import Audit_Metadata + +AWS_ACCOUNT_NUMBER = "123456789012" AWS_REGION = "us-east-1" class Test_glue_data_catalogs_connection_passwords_encryption_enabled: + # Mocked Audit Info + def set_mocked_audit_info(self): + audit_info = AWS_Audit_Info( + session_config=None, + original_session=None, + audit_session=session.Session( + profile_name=None, + botocore_session=None, + region_name=AWS_REGION, + ), + audited_account=AWS_ACCOUNT_NUMBER, + audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root", + audited_user_id=None, + audited_partition="aws", + audited_identity_arn=None, + profile=None, + profile_region=AWS_REGION, + credentials=None, + assumed_role_info=None, + audited_regions=None, + organizations_metadata=None, + audit_resources=None, + mfa_enabled=False, + audit_metadata=Audit_Metadata( + services_scanned=0, + expected_checks=[], + completed_checks=0, + audit_progress=0, + ), + ignore_unused_services=False, + ) + return audit_info + def test_glue_no_settings(self): glue_client = mock.MagicMock + glue_client.audit_info = self.set_mocked_audit_info() glue_client.catalog_encryption_settings = [] with mock.patch( @@ -27,9 +65,11 @@ class Test_glue_data_catalogs_connection_passwords_encryption_enabled: def test_glue_catalog_password_unencrypted(self): glue_client = mock.MagicMock + glue_client.audit_info = self.set_mocked_audit_info() glue_client.catalog_encryption_settings = [ CatalogEncryptionSetting( mode="DISABLED", + tables=False, kms_id=None, region=AWS_REGION, password_encryption=False, @@ -52,17 +92,85 @@ class Test_glue_data_catalogs_connection_passwords_encryption_enabled: assert len(result) == 1 assert result[0].status == "FAIL" - assert search( - "Glue data catalog connection password is not encrypted", - result[0].status_extended, + assert ( + result[0].status_extended + == "Glue data catalog connection password is not encrypted." ) assert result[0].resource_id == "12345678912" + assert result[0].region == AWS_REGION - def test_glue_catalog_encrypted(self): + def test_glue_catalog_password_unencrypted_ignoring(self): glue_client = mock.MagicMock + glue_client.audit_info = self.set_mocked_audit_info() glue_client.catalog_encryption_settings = [ CatalogEncryptionSetting( mode="DISABLED", + tables=False, + kms_id=None, + region=AWS_REGION, + password_encryption=False, + password_kms_id=None, + ) + ] + glue_client.audited_account = "12345678912" + glue_client.audit_info.ignore_unused_services = True + with mock.patch( + "prowler.providers.aws.services.glue.glue_service.Glue", + glue_client, + ): + # Test Check + from prowler.providers.aws.services.glue.glue_data_catalogs_connection_passwords_encryption_enabled.glue_data_catalogs_connection_passwords_encryption_enabled import ( + glue_data_catalogs_connection_passwords_encryption_enabled, + ) + + check = glue_data_catalogs_connection_passwords_encryption_enabled() + result = check.execute() + + assert len(result) == 0 + + def test_glue_catalog_password_unencrypted_ignoring_with_tables(self): + glue_client = mock.MagicMock + glue_client.audit_info = self.set_mocked_audit_info() + glue_client.catalog_encryption_settings = [ + CatalogEncryptionSetting( + mode="DISABLED", + tables=True, + kms_id=None, + region=AWS_REGION, + password_encryption=False, + password_kms_id=None, + ) + ] + glue_client.audited_account = "12345678912" + glue_client.audit_info.ignore_unused_services = True + with mock.patch( + "prowler.providers.aws.services.glue.glue_service.Glue", + glue_client, + ): + # Test Check + from prowler.providers.aws.services.glue.glue_data_catalogs_connection_passwords_encryption_enabled.glue_data_catalogs_connection_passwords_encryption_enabled import ( + glue_data_catalogs_connection_passwords_encryption_enabled, + ) + + check = glue_data_catalogs_connection_passwords_encryption_enabled() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "Glue data catalog connection password is not encrypted." + ) + assert result[0].resource_id == "12345678912" + assert result[0].region == AWS_REGION + + def test_glue_catalog_encrypted(self): + glue_client = mock.MagicMock + glue_client.audit_info = self.set_mocked_audit_info() + glue_client.catalog_encryption_settings = [ + CatalogEncryptionSetting( + mode="DISABLED", + tables=False, region=AWS_REGION, password_encryption=True, password_kms_id="kms-key", @@ -84,8 +192,9 @@ class Test_glue_data_catalogs_connection_passwords_encryption_enabled: assert len(result) == 1 assert result[0].status == "PASS" - assert search( - "Glue data catalog connection password is encrypted", - result[0].status_extended, + assert ( + result[0].status_extended + == "Glue data catalog connection password is encrypted with KMS key kms-key." ) assert result[0].resource_id == "12345678912" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/glue/glue_data_catalogs_metadata_encryption_enabled/glue_data_catalogs_metadata_encryption_enabled_test.py b/tests/providers/aws/services/glue/glue_data_catalogs_metadata_encryption_enabled/glue_data_catalogs_metadata_encryption_enabled_test.py index a27b7871..6adddca8 100644 --- a/tests/providers/aws/services/glue/glue_data_catalogs_metadata_encryption_enabled/glue_data_catalogs_metadata_encryption_enabled_test.py +++ b/tests/providers/aws/services/glue/glue_data_catalogs_metadata_encryption_enabled/glue_data_catalogs_metadata_encryption_enabled_test.py @@ -1,14 +1,53 @@ from re import search from unittest import mock -from prowler.providers.aws.services.glue.glue_service import CatalogEncryptionSetting +from boto3 import session +from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.glue.glue_service import CatalogEncryptionSetting +from prowler.providers.common.models import Audit_Metadata + +AWS_ACCOUNT_NUMBER = "123456789012" AWS_REGION = "us-east-1" class Test_glue_data_catalogs_metadata_encryption_enabled: + # Mocked Audit Info + def set_mocked_audit_info(self): + audit_info = AWS_Audit_Info( + session_config=None, + original_session=None, + audit_session=session.Session( + profile_name=None, + botocore_session=None, + region_name=AWS_REGION, + ), + audited_account=AWS_ACCOUNT_NUMBER, + audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root", + audited_user_id=None, + audited_partition="aws", + audited_identity_arn=None, + profile=None, + profile_region=AWS_REGION, + credentials=None, + assumed_role_info=None, + audited_regions=None, + organizations_metadata=None, + audit_resources=None, + mfa_enabled=False, + audit_metadata=Audit_Metadata( + services_scanned=0, + expected_checks=[], + completed_checks=0, + audit_progress=0, + ), + ignore_unused_services=False, + ) + return audit_info + def test_glue_no_settings(self): glue_client = mock.MagicMock + glue_client.audit_info = self.set_mocked_audit_info() glue_client.catalog_encryption_settings = [] with mock.patch( @@ -27,9 +66,11 @@ class Test_glue_data_catalogs_metadata_encryption_enabled: def test_glue_catalog_unencrypted(self): glue_client = mock.MagicMock + glue_client.audit_info = self.set_mocked_audit_info() glue_client.catalog_encryption_settings = [ CatalogEncryptionSetting( - mode="DISABLED", + mode="disabled.", + tables=False, kms_id=None, region=AWS_REGION, password_encryption=False, @@ -38,6 +79,73 @@ class Test_glue_data_catalogs_metadata_encryption_enabled: ] glue_client.audited_account = "12345678912" + with mock.patch( + "prowler.providers.aws.services.glue.glue_service.Glue", + glue_client, + ): + # Test Check + from prowler.providers.aws.services.glue.glue_data_catalogs_metadata_encryption_enabled.glue_data_catalogs_metadata_encryption_enabled import ( + glue_data_catalogs_metadata_encryption_enabled, + ) + + check = glue_data_catalogs_metadata_encryption_enabled() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "Glue data catalog settings have metadata encryption disabled." + ) + assert result[0].resource_id == "12345678912" + assert result[0].region == AWS_REGION + + def test_glue_catalog_unencrypted_ignoring(self): + glue_client = mock.MagicMock + glue_client.audit_info = self.set_mocked_audit_info() + glue_client.catalog_encryption_settings = [ + CatalogEncryptionSetting( + mode="disabled.", + tables=False, + kms_id=None, + region=AWS_REGION, + password_encryption=False, + password_kms_id=None, + ) + ] + glue_client.audited_account = "12345678912" + glue_client.audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.services.glue.glue_service.Glue", + glue_client, + ): + # Test Check + from prowler.providers.aws.services.glue.glue_data_catalogs_metadata_encryption_enabled.glue_data_catalogs_metadata_encryption_enabled import ( + glue_data_catalogs_metadata_encryption_enabled, + ) + + check = glue_data_catalogs_metadata_encryption_enabled() + result = check.execute() + + assert len(result) == 0 + + def test_glue_catalog_unencrypted_ignoring_with_tables(self): + glue_client = mock.MagicMock + glue_client.audit_info = self.set_mocked_audit_info() + glue_client.catalog_encryption_settings = [ + CatalogEncryptionSetting( + mode="disabled.", + tables=True, + kms_id=None, + region=AWS_REGION, + password_encryption=False, + password_kms_id=None, + ) + ] + glue_client.audited_account = "12345678912" + glue_client.audit_info.ignore_unused_services = True + with mock.patch( "prowler.providers.aws.services.glue.glue_service.Glue", glue_client, @@ -53,17 +161,20 @@ class Test_glue_data_catalogs_metadata_encryption_enabled: assert len(result) == 1 assert result[0].status == "FAIL" assert search( - "Glue data catalog settings have metadata encryption disabled", + "Glue data catalog settings have metadata encryption disabled.", result[0].status_extended, ) assert result[0].resource_id == "12345678912" + assert result[0].region == AWS_REGION def test_glue_catalog_encrypted(self): glue_client = mock.MagicMock + glue_client.audit_info = self.set_mocked_audit_info() glue_client.catalog_encryption_settings = [ CatalogEncryptionSetting( mode="SSE-KMS", kms_id="kms-key", + tables=False, region=AWS_REGION, password_encryption=False, password_kms_id=None, @@ -85,8 +196,9 @@ class Test_glue_data_catalogs_metadata_encryption_enabled: assert len(result) == 1 assert result[0].status == "PASS" - assert search( - "Glue data catalog settings have metadata encryption enabled", - result[0].status_extended, + assert ( + result[0].status_extended + == "Glue data catalog settings have metadata encryption enabled with KMS key kms-key." ) assert result[0].resource_id == "12345678912" + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/inspector2/inspector2_findings_exist/inspector2_findings_exist_test.py b/tests/providers/aws/services/inspector2/inspector2_findings_exist/inspector2_findings_exist_test.py index 099fe29d..c0adeefc 100644 --- a/tests/providers/aws/services/inspector2/inspector2_findings_exist/inspector2_findings_exist_test.py +++ b/tests/providers/aws/services/inspector2/inspector2_findings_exist/inspector2_findings_exist_test.py @@ -1,9 +1,14 @@ from unittest import mock +from boto3 import session + +from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.aws.services.ecr.ecr_service import Repository from prowler.providers.aws.services.inspector2.inspector2_service import ( Inspector, InspectorFinding, ) +from prowler.providers.common.models import Audit_Metadata AWS_REGION = "us-east-1" AWS_ACCOUNT_ID = "123456789012" @@ -13,9 +18,46 @@ FINDING_ARN = ( class Test_inspector2_findings_exist: + def set_mocked_audit_info(self): + audit_info = AWS_Audit_Info( + session_config=None, + original_session=None, + audit_session=session.Session( + profile_name=None, + botocore_session=None, + ), + audited_account=AWS_ACCOUNT_ID, + audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_ID}:root", + audited_user_id=None, + audited_partition="aws", + audited_identity_arn=None, + profile=None, + profile_region=None, + credentials=None, + assumed_role_info=None, + audited_regions=[AWS_REGION], + organizations_metadata=None, + audit_resources=None, + mfa_enabled=False, + audit_metadata=Audit_Metadata( + services_scanned=0, + expected_checks=[], + completed_checks=0, + audit_progress=0, + ), + ) + return audit_info + def test_inspector2_disabled(self): # Mock the inspector2 client inspector2_client = mock.MagicMock + awslambda_client = mock.MagicMock + ecr_client = mock.MagicMock + ec2_client = mock.MagicMock + ec2_client.audit_info = self.set_mocked_audit_info() + ecr_client.audit_info = self.set_mocked_audit_info() + awslambda_client.audit_info = self.set_mocked_audit_info() + inspector2_client.audit_info = self.set_mocked_audit_info() inspector2_client.audited_account = AWS_ACCOUNT_ID inspector2_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" inspector2_client.region = AWS_REGION @@ -24,28 +66,59 @@ class Test_inspector2_findings_exist: id=AWS_ACCOUNT_ID, status="DISABLED", region=AWS_REGION, findings=[] ) ] + current_audit_info = self.set_mocked_audit_info() + with mock.patch( - "prowler.providers.aws.services.inspector2.inspector2_service.Inspector2", - new=inspector2_client, + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, ): - # Test Check - from prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist import ( - inspector2_findings_exist, - ) + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.inspector2_client", + new=inspector2_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.ecr_client", + new=ecr_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.ec2_client", + new=ec2_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.awslambda_client", + new=awslambda_client, + ): + # Test Check + from prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist import ( + inspector2_findings_exist, + ) - check = inspector2_findings_exist() - result = check.execute() + check = inspector2_findings_exist() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "FAIL" - assert result[0].status_extended == "Inspector2 is not enabled." - assert result[0].resource_id == AWS_ACCOUNT_ID - assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "Inspector2 is not enabled." + ) + assert result[0].resource_id == AWS_ACCOUNT_ID + assert ( + result[0].resource_arn + == f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" + ) + assert result[0].region == AWS_REGION def test_enabled_no_finding(self): # Mock the inspector2 client inspector2_client = mock.MagicMock + awslambda_client = mock.MagicMock + ecr_client = mock.MagicMock + ec2_client = mock.MagicMock + ec2_client.audit_info = self.set_mocked_audit_info() + ecr_client.audit_info = self.set_mocked_audit_info() + awslambda_client.audit_info = self.set_mocked_audit_info() + inspector2_client.audit_info = self.set_mocked_audit_info() inspector2_client.audited_account = AWS_ACCOUNT_ID inspector2_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" inspector2_client.region = AWS_REGION @@ -54,30 +127,59 @@ class Test_inspector2_findings_exist: id=AWS_ACCOUNT_ID, status="ENABLED", region=AWS_REGION, findings=[] ) ] + current_audit_info = self.set_mocked_audit_info() + with mock.patch( - "prowler.providers.aws.services.inspector2.inspector2_service.Inspector2", - new=inspector2_client, + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, ): - # Test Check - from prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist import ( - inspector2_findings_exist, - ) + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.inspector2_client", + new=inspector2_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.ecr_client", + new=ecr_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.ec2_client", + new=ec2_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.awslambda_client", + new=awslambda_client, + ): + # Test Check + from prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist import ( + inspector2_findings_exist, + ) - check = inspector2_findings_exist() - result = check.execute() + check = inspector2_findings_exist() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "PASS" - assert ( - result[0].status_extended == "Inspector2 is enabled with no findings." - ) - assert result[0].resource_id == AWS_ACCOUNT_ID - assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == "Inspector2 is enabled with no findings." + ) + assert result[0].resource_id == AWS_ACCOUNT_ID + assert ( + result[0].resource_arn + == f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" + ) + assert result[0].region == AWS_REGION def test_enabled_with_no_active_finding(self): # Mock the inspector2 client inspector2_client = mock.MagicMock + awslambda_client = mock.MagicMock + ecr_client = mock.MagicMock + ec2_client = mock.MagicMock + ec2_client.audit_info = self.set_mocked_audit_info() + ecr_client.audit_info = self.set_mocked_audit_info() + awslambda_client.audit_info = self.set_mocked_audit_info() + inspector2_client.audit_info = self.set_mocked_audit_info() inspector2_client.audited_account = AWS_ACCOUNT_ID inspector2_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" inspector2_client.region = AWS_REGION @@ -97,32 +199,59 @@ class Test_inspector2_findings_exist: ], ) ] + current_audit_info = self.set_mocked_audit_info() with mock.patch( - "prowler.providers.aws.services.inspector2.inspector2_service.Inspector2", - new=inspector2_client, + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, ): - # Test Check - from prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist import ( - inspector2_findings_exist, - ) + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.inspector2_client", + new=inspector2_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.ecr_client", + new=ecr_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.ec2_client", + new=ec2_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.awslambda_client", + new=awslambda_client, + ): + # Test Check + from prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist import ( + inspector2_findings_exist, + ) - check = inspector2_findings_exist() - result = check.execute() + check = inspector2_findings_exist() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "PASS" - assert ( - result[0].status_extended - == "Inspector2 is enabled with no active findings." - ) - assert result[0].resource_id == AWS_ACCOUNT_ID - assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == "Inspector2 is enabled with no active findings." + ) + assert result[0].resource_id == AWS_ACCOUNT_ID + assert ( + result[0].resource_arn + == f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" + ) + assert result[0].region == AWS_REGION def test_enabled_with_active_finding(self): # Mock the inspector2 client inspector2_client = mock.MagicMock + awslambda_client = mock.MagicMock + ecr_client = mock.MagicMock + ec2_client = mock.MagicMock + ec2_client.audit_info = self.set_mocked_audit_info() + ecr_client.audit_info = self.set_mocked_audit_info() + awslambda_client.audit_info = self.set_mocked_audit_info() + inspector2_client.audit_info = self.set_mocked_audit_info() inspector2_client.audited_account = AWS_ACCOUNT_ID inspector2_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" inspector2_client.region = AWS_REGION @@ -142,31 +271,59 @@ class Test_inspector2_findings_exist: ], ) ] + current_audit_info = self.set_mocked_audit_info() with mock.patch( - "prowler.providers.aws.services.inspector2.inspector2_service.Inspector2", - new=inspector2_client, + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, ): - # Test Check - from prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist import ( - inspector2_findings_exist, - ) + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.inspector2_client", + new=inspector2_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.ecr_client", + new=ecr_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.ec2_client", + new=ec2_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.awslambda_client", + new=awslambda_client, + ): + # Test Check + from prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist import ( + inspector2_findings_exist, + ) - check = inspector2_findings_exist() - result = check.execute() + check = inspector2_findings_exist() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "FAIL" - assert ( - result[0].status_extended == "There are 1 ACTIVE Inspector2 findings." - ) - assert result[0].resource_id == AWS_ACCOUNT_ID - assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "There are 1 ACTIVE Inspector2 findings." + ) + assert result[0].resource_id == AWS_ACCOUNT_ID + assert ( + result[0].resource_arn + == f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" + ) + assert result[0].region == AWS_REGION def test_enabled_with_active_and_closed_findings(self): # Mock the inspector2 client inspector2_client = mock.MagicMock + awslambda_client = mock.MagicMock + ecr_client = mock.MagicMock + ec2_client = mock.MagicMock + ec2_client.audit_info = self.set_mocked_audit_info() + ecr_client.audit_info = self.set_mocked_audit_info() + awslambda_client.audit_info = self.set_mocked_audit_info() + inspector2_client.audit_info = self.set_mocked_audit_info() inspector2_client.audited_account = AWS_ACCOUNT_ID inspector2_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" inspector2_client.region = AWS_REGION @@ -193,24 +350,194 @@ class Test_inspector2_findings_exist: ], ) ] + current_audit_info = self.set_mocked_audit_info() with mock.patch( - "prowler.providers.aws.services.inspector2.inspector2_service.Inspector2", - new=inspector2_client, + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, ): - # Test Check - from prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist import ( - inspector2_findings_exist, - ) + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.inspector2_client", + new=inspector2_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.ecr_client", + new=ecr_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.ec2_client", + new=ec2_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.awslambda_client", + new=awslambda_client, + ): + # Test Check + from prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist import ( + inspector2_findings_exist, + ) - check = inspector2_findings_exist() - result = check.execute() + check = inspector2_findings_exist() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "FAIL" - assert ( - result[0].status_extended == "There are 1 ACTIVE Inspector2 findings." + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "There are 1 ACTIVE Inspector2 findings." + ) + assert result[0].resource_id == AWS_ACCOUNT_ID + assert ( + result[0].resource_arn + == f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" + ) + assert result[0].region == AWS_REGION + + def test_inspector2_disabled_ignoring(self): + # Mock the inspector2 client + inspector2_client = mock.MagicMock + awslambda_client = mock.MagicMock + awslambda_client.functions = {} + ecr_client = mock.MagicMock + ecr_client.registries = {} + ecr_client.registries[AWS_REGION] = mock.MagicMock + ecr_client.registries[AWS_REGION].repositories = [] + ec2_client = mock.MagicMock + ec2_client.instances = [] + ec2_client.audit_info = self.set_mocked_audit_info() + ecr_client.audit_info = self.set_mocked_audit_info() + awslambda_client.audit_info = self.set_mocked_audit_info() + inspector2_client.audit_info = self.set_mocked_audit_info() + inspector2_client.audit_info.ignore_unused_services = True + inspector2_client.audited_account = AWS_ACCOUNT_ID + inspector2_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" + inspector2_client.region = AWS_REGION + inspector2_client.inspectors = [ + Inspector( + id=AWS_ACCOUNT_ID, status="DISABLED", region=AWS_REGION, findings=[] ) - assert result[0].resource_id == AWS_ACCOUNT_ID - assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" - assert result[0].region == AWS_REGION + ] + current_audit_info = self.set_mocked_audit_info() + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.inspector2_client", + new=inspector2_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.ecr_client", + new=ecr_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.ec2_client", + new=ec2_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.awslambda_client", + new=awslambda_client, + ): + # Test Check + from prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist import ( + inspector2_findings_exist, + ) + + check = inspector2_findings_exist() + result = check.execute() + + assert len(result) == 0 + + def test_inspector2_disabled_ignoring_with_resources(self): + # Mock the inspector2 client + inspector2_client = mock.MagicMock + awslambda_client = mock.MagicMock + awslambda_client.functions = {} + ecr_client = mock.MagicMock + ecr_client.registries = {} + ecr_client.registries[AWS_REGION] = mock.MagicMock + repository_name = "test_repo" + repository_arn = ( + f"arn:aws:ecr:eu-west-1:{AWS_ACCOUNT_ID}:repository/{repository_name}" + ) + repo_policy_public = { + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "ECRRepositoryPolicy", + "Effect": "Allow", + "Principal": { + "AWS": f"arn:aws:iam::{AWS_ACCOUNT_ID}:user/username" + }, + "Action": ["ecr:DescribeImages", "ecr:DescribeRepositories"], + } + ], + } + ecr_client.registries[AWS_REGION].repositories = [ + Repository( + name=repository_name, + arn=repository_arn, + region=AWS_REGION, + scan_on_push=True, + policy=repo_policy_public, + images_details=None, + lifecycle_policy="test-policy", + ) + ] + ec2_client = mock.MagicMock + ec2_client.instances = [] + ec2_client.audit_info = self.set_mocked_audit_info() + ecr_client.audit_info = self.set_mocked_audit_info() + awslambda_client.audit_info = self.set_mocked_audit_info() + inspector2_client.audit_info = self.set_mocked_audit_info() + inspector2_client.audit_info.ignore_unused_services = True + inspector2_client.audited_account = AWS_ACCOUNT_ID + inspector2_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" + inspector2_client.region = AWS_REGION + inspector2_client.inspectors = [ + Inspector( + id=AWS_ACCOUNT_ID, status="DISABLED", region=AWS_REGION, findings=[] + ) + ] + current_audit_info = self.set_mocked_audit_info() + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.inspector2_client", + new=inspector2_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.ecr_client", + new=ecr_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.ec2_client", + new=ec2_client, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist.awslambda_client", + new=awslambda_client, + ): + # Test Check + from prowler.providers.aws.services.inspector2.inspector2_findings_exist.inspector2_findings_exist import ( + inspector2_findings_exist, + ) + + check = inspector2_findings_exist() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "Inspector2 is not enabled." + ) + assert result[0].resource_id == AWS_ACCOUNT_ID + assert ( + result[0].resource_arn + == f"arn:aws:iam::{AWS_ACCOUNT_ID}:root" + ) + assert result[0].region == AWS_REGION diff --git a/tests/providers/aws/services/macie/macie_is_enabled/macie_is_enabled_test.py b/tests/providers/aws/services/macie/macie_is_enabled/macie_is_enabled_test.py index 429687fa..2d414f4a 100644 --- a/tests/providers/aws/services/macie/macie_is_enabled/macie_is_enabled_test.py +++ b/tests/providers/aws/services/macie/macie_is_enabled/macie_is_enabled_test.py @@ -1,13 +1,62 @@ from unittest import mock +from boto3 import session +from moto import mock_s3 + +from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info from prowler.providers.aws.services.macie.macie_service import Session +from prowler.providers.aws.services.s3.s3_service import Bucket +from prowler.providers.common.models import Audit_Metadata AWS_ACCOUNT_NUMBER = "123456789012" +AWS_REGION = "us-east-1" +AWS_ACCOUNT_NUMBER = "123456789012" + + class Test_macie_is_enabled: + # Mocked Audit Info + def set_mocked_audit_info(self): + audit_info = AWS_Audit_Info( + session_config=None, + original_session=None, + audit_session=session.Session( + profile_name=None, + botocore_session=None, + region_name=AWS_REGION, + ), + audited_account=AWS_ACCOUNT_NUMBER, + audited_account_arn=f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root", + audited_user_id=None, + audited_partition="aws", + audited_identity_arn=None, + profile=None, + profile_region=AWS_REGION, + credentials=None, + assumed_role_info=None, + audited_regions=None, + organizations_metadata=None, + audit_resources=None, + mfa_enabled=False, + audit_metadata=Audit_Metadata( + services_scanned=0, + expected_checks=[], + completed_checks=0, + audit_progress=0, + ), + ) + return audit_info + + @mock_s3 def test_macie_disabled(self): + s3_client = mock.MagicMock + s3_client.audit_info = self.set_mocked_audit_info() + s3_client.buckets = [] + s3_client.regions_with_buckets = [] + macie_client = mock.MagicMock + macie_client.audit_info = self.set_mocked_audit_info() macie_client.audited_account = AWS_ACCOUNT_NUMBER macie_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" macie_client.sessions = [ @@ -16,9 +65,17 @@ class Test_macie_is_enabled: region="eu-west-1", ) ] + current_audit_info = self.set_mocked_audit_info() + with mock.patch( - "prowler.providers.aws.services.macie.macie_service.Macie", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled.macie_client", new=macie_client, + ), mock.patch( + "prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled.s3_client", + new=s3_client, ): # Test Check from prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled import ( @@ -33,8 +90,15 @@ class Test_macie_is_enabled: assert result[0].status_extended == "Macie is not enabled." assert result[0].resource_id == AWS_ACCOUNT_NUMBER + @mock_s3 def test_macie_enabled(self): + s3_client = mock.MagicMock + s3_client.audit_info = self.set_mocked_audit_info() + s3_client.buckets = [] + s3_client.regions_with_buckets = [] + macie_client = mock.MagicMock + macie_client.audit_info = self.set_mocked_audit_info() macie_client.audited_account = AWS_ACCOUNT_NUMBER macie_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" macie_client.sessions = [ @@ -43,9 +107,17 @@ class Test_macie_is_enabled: region="eu-west-1", ) ] + current_audit_info = self.set_mocked_audit_info() + with mock.patch( - "prowler.providers.aws.services.macie.macie_service.Macie", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled.macie_client", new=macie_client, + ), mock.patch( + "prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled.s3_client", + new=s3_client, ): # Test Check from prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled import ( @@ -60,8 +132,15 @@ class Test_macie_is_enabled: assert result[0].status_extended == "Macie is enabled." assert result[0].resource_id == AWS_ACCOUNT_NUMBER - def test_macie_suspended(self): + @mock_s3 + def test_macie_suspended_ignored(self): + s3_client = mock.MagicMock + s3_client.audit_info = self.set_mocked_audit_info() + s3_client.buckets = [] + s3_client.regions_with_buckets = [] + macie_client = mock.MagicMock + macie_client.audit_info = self.set_mocked_audit_info() macie_client.audited_account = AWS_ACCOUNT_NUMBER macie_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" macie_client.sessions = [ @@ -70,9 +149,108 @@ class Test_macie_is_enabled: region="eu-west-1", ) ] + + current_audit_info = self.set_mocked_audit_info() + macie_client.audit_info.ignore_unused_services = True + with mock.patch( - "prowler.providers.aws.services.macie.macie_service.Macie", + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled.macie_client", new=macie_client, + ), mock.patch( + "prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled.s3_client", + new=s3_client, + ): + # Test Check + from prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled import ( + macie_is_enabled, + ) + + check = macie_is_enabled() + result = check.execute() + + assert len(result) == 0 + + @mock_s3 + def test_macie_suspended_ignored_with_buckets(self): + s3_client = mock.MagicMock + s3_client.regions_with_buckets = [AWS_REGION] + s3_client.audit_info = self.set_mocked_audit_info() + s3_client.buckets = [ + Bucket( + name="test", + arn="test-arn", + region=AWS_REGION, + ) + ] + + macie_client = mock.MagicMock + macie_client.audit_info = self.set_mocked_audit_info() + macie_client.audited_account = AWS_ACCOUNT_NUMBER + macie_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + macie_client.sessions = [ + Session( + status="PAUSED", + region=AWS_REGION, + ) + ] + + macie_client.audit_info.ignore_unused_services = True + current_audit_info = self.set_mocked_audit_info() + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled.macie_client", + new=macie_client, + ), mock.patch( + "prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled.s3_client", + new=s3_client, + ): + # Test Check + from prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled import ( + macie_is_enabled, + ) + + check = macie_is_enabled() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended == "Macie is currently in a SUSPENDED state." + ) + assert result[0].resource_id == AWS_ACCOUNT_NUMBER + + @mock_s3 + def test_macie_suspended(self): + s3_client = mock.MagicMock + s3_client.audit_info = self.set_mocked_audit_info() + + macie_client = mock.MagicMock + macie_client.audit_info = self.set_mocked_audit_info() + macie_client.audited_account = AWS_ACCOUNT_NUMBER + macie_client.audited_account_arn = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + macie_client.sessions = [ + Session( + status="PAUSED", + region="eu-west-1", + ) + ] + current_audit_info = self.set_mocked_audit_info() + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled.macie_client", + new=macie_client, + ), mock.patch( + "prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled.s3_client", + new=s3_client, ): # Test Check from prowler.providers.aws.services.macie.macie_is_enabled.macie_is_enabled import ( diff --git a/tests/providers/aws/services/networkfirewall/networkfirewall_in_all_vpc/networkfirewall_in_all_vpc_test.py b/tests/providers/aws/services/networkfirewall/networkfirewall_in_all_vpc/networkfirewall_in_all_vpc_test.py index 9e4e62ce..c0e28c82 100644 --- a/tests/providers/aws/services/networkfirewall/networkfirewall_in_all_vpc/networkfirewall_in_all_vpc_test.py +++ b/tests/providers/aws/services/networkfirewall/networkfirewall_in_all_vpc/networkfirewall_in_all_vpc_test.py @@ -53,9 +53,11 @@ class Test_networkfirewall_in_all_vpc: def test_no_vpcs(self): networkfirewall_client = mock.MagicMock + networkfirewall_client.audit_info = self.set_mocked_audit_info() networkfirewall_client.region = AWS_REGION networkfirewall_client.network_firewalls = [] vpc_client = mock.MagicMock + vpc_client.audit_info = self.set_mocked_audit_info() vpc_client.region = AWS_REGION vpc_client.vpcs = {} @@ -85,6 +87,7 @@ class Test_networkfirewall_in_all_vpc: def test_vpcs_with_firewall_all(self): networkfirewall_client = mock.MagicMock + networkfirewall_client.audit_info = self.set_mocked_audit_info() networkfirewall_client.region = AWS_REGION networkfirewall_client.network_firewalls = [ Firewall( @@ -98,6 +101,7 @@ class Test_networkfirewall_in_all_vpc: ) ] vpc_client = mock.MagicMock + vpc_client.audit_info = self.set_mocked_audit_info() vpc_client.region = AWS_REGION vpc_client.vpcs = { VPC_ID_PROTECTED: VPCs( @@ -163,9 +167,11 @@ class Test_networkfirewall_in_all_vpc: def test_vpcs_without_firewall(self): networkfirewall_client = mock.MagicMock + networkfirewall_client.audit_info = self.set_mocked_audit_info() networkfirewall_client.region = AWS_REGION networkfirewall_client.network_firewalls = [] vpc_client = mock.MagicMock + vpc_client.audit_info = self.set_mocked_audit_info() vpc_client.region = AWS_REGION vpc_client.vpcs = { VPC_ID_UNPROTECTED: VPCs( @@ -231,9 +237,12 @@ class Test_networkfirewall_in_all_vpc: def test_vpcs_with_name_without_firewall(self): networkfirewall_client = mock.MagicMock + networkfirewall_client.audit_info = self.set_mocked_audit_info() networkfirewall_client.region = AWS_REGION networkfirewall_client.network_firewalls = [] + vpc_client = mock.MagicMock + vpc_client.audit_info = self.set_mocked_audit_info() vpc_client.region = AWS_REGION vpc_client.vpcs = { VPC_ID_UNPROTECTED: VPCs( @@ -299,6 +308,7 @@ class Test_networkfirewall_in_all_vpc: def test_vpcs_with_and_without_firewall(self): networkfirewall_client = mock.MagicMock + networkfirewall_client.audit_info = self.set_mocked_audit_info() networkfirewall_client.region = AWS_REGION networkfirewall_client.network_firewalls = [ Firewall( @@ -312,6 +322,7 @@ class Test_networkfirewall_in_all_vpc: ) ] vpc_client = mock.MagicMock + vpc_client.audit_info = self.set_mocked_audit_info() vpc_client.region = AWS_REGION vpc_client.vpcs = { VPC_ID_UNPROTECTED: VPCs( @@ -412,3 +423,137 @@ class Test_networkfirewall_in_all_vpc: assert r.resource_id == VPC_ID_UNPROTECTED assert r.resource_tags == [] assert r.resource_arn == "arn_test" + + def test_vpcs_without_firewall_ignoring(self): + networkfirewall_client = mock.MagicMock + networkfirewall_client.audit_info = self.set_mocked_audit_info() + networkfirewall_client.region = AWS_REGION + networkfirewall_client.network_firewalls = [] + vpc_client = mock.MagicMock + vpc_client.audit_info = self.set_mocked_audit_info() + vpc_client.region = AWS_REGION + vpc_client.vpcs = { + VPC_ID_UNPROTECTED: VPCs( + id=VPC_ID_UNPROTECTED, + default=False, + cidr_block="192.168.0.0/16", + flow_log=False, + region=AWS_REGION, + arn="arn_test", + name="vpc_name", + subnets=[ + VpcSubnet( + id="subnet-123456789", + name="", + arn="arn_test", + default=False, + vpc_id=VPC_ID_UNPROTECTED, + cidr_block="192.168.0.0/24", + availability_zone="us-east-1a", + public=False, + nat_gateway=False, + region=AWS_REGION, + tags=[], + mapPublicIpOnLaunch=False, + ) + ], + tags=[], + ) + } + + audit_info = self.set_mocked_audit_info() + vpc_client.audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.networkfirewall.networkfirewall_in_all_vpc.networkfirewall_in_all_vpc.vpc_client", + new=vpc_client, + ): + with mock.patch( + "prowler.providers.aws.services.networkfirewall.networkfirewall_in_all_vpc.networkfirewall_in_all_vpc.networkfirewall_client", + new=networkfirewall_client, + ): + # Test Check + from prowler.providers.aws.services.networkfirewall.networkfirewall_in_all_vpc.networkfirewall_in_all_vpc import ( + networkfirewall_in_all_vpc, + ) + + check = networkfirewall_in_all_vpc() + result = check.execute() + + assert len(result) == 0 + + def test_vpcs_without_firewall_ignoring_vpc_in_use(self): + networkfirewall_client = mock.MagicMock + networkfirewall_client.audit_info = self.set_mocked_audit_info() + networkfirewall_client.region = AWS_REGION + networkfirewall_client.network_firewalls = [] + vpc_client = mock.MagicMock + vpc_client.audit_info = self.set_mocked_audit_info() + vpc_client.region = AWS_REGION + vpc_client.vpcs = { + VPC_ID_UNPROTECTED: VPCs( + id=VPC_ID_UNPROTECTED, + name="vpc_name", + default=False, + cidr_block="192.168.0.0/16", + flow_log=False, + region=AWS_REGION, + arn="arn_test", + in_use=True, + subnets=[ + VpcSubnet( + id="subnet-123456789", + arn="arn_test", + name="subnet_name", + default=False, + vpc_id=VPC_ID_UNPROTECTED, + cidr_block="192.168.0.0/24", + availability_zone="us-east-1a", + public=False, + nat_gateway=False, + region=AWS_REGION, + tags=[], + mapPublicIpOnLaunch=False, + ) + ], + tags=[], + ) + } + + audit_info = self.set_mocked_audit_info() + vpc_client.audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.networkfirewall.networkfirewall_in_all_vpc.networkfirewall_in_all_vpc.vpc_client", + new=vpc_client, + ): + with mock.patch( + "prowler.providers.aws.services.networkfirewall.networkfirewall_in_all_vpc.networkfirewall_in_all_vpc.networkfirewall_client", + new=networkfirewall_client, + ): + # Test Check + from prowler.providers.aws.services.networkfirewall.networkfirewall_in_all_vpc.networkfirewall_in_all_vpc import ( + networkfirewall_in_all_vpc, + ) + + check = networkfirewall_in_all_vpc() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "VPC vpc_name does not have Network Firewall enabled." + ) + assert result[0].region == AWS_REGION + assert result[0].resource_id == VPC_ID_UNPROTECTED + assert result[0].resource_tags == [] + assert result[0].resource_arn == "arn_test" diff --git a/tests/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_test.py b/tests/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_test.py index d7c5aecb..73d341f0 100644 --- a/tests/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_test.py +++ b/tests/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_test.py @@ -58,35 +58,37 @@ class Test_s3_account_level_public_access_blocks: "RestrictPublicBuckets": True, }, ) - from prowler.providers.aws.services.s3.s3_service import S3Control + from prowler.providers.aws.services.s3.s3_service import S3, S3Control audit_info = self.set_mocked_audit_info() with mock.patch( "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", new=audit_info, + ), mock.patch( + "prowler.providers.aws.services.s3.s3_account_level_public_access_blocks.s3_account_level_public_access_blocks.s3_client", + new=S3(audit_info), + ), mock.patch( + "prowler.providers.aws.services.s3.s3_account_level_public_access_blocks.s3_account_level_public_access_blocks.s3control_client", + new=S3Control(audit_info), ): - with mock.patch( - "prowler.providers.aws.services.s3.s3_account_level_public_access_blocks.s3_account_level_public_access_blocks.s3control_client", - new=S3Control(audit_info), - ): - # Test Check - from prowler.providers.aws.services.s3.s3_account_level_public_access_blocks.s3_account_level_public_access_blocks import ( - s3_account_level_public_access_blocks, - ) + # Test Check + from prowler.providers.aws.services.s3.s3_account_level_public_access_blocks.s3_account_level_public_access_blocks import ( + s3_account_level_public_access_blocks, + ) - check = s3_account_level_public_access_blocks() - result = check.execute() + check = s3_account_level_public_access_blocks() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "PASS" - assert ( - result[0].status_extended - == f"Block Public Access is configured for the account {AWS_ACCOUNT_NUMBER}." - ) - assert result[0].resource_id == AWS_ACCOUNT_NUMBER - assert result[0].resource_arn == AWS_ACCOUNT_ARN - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Block Public Access is configured for the account {AWS_ACCOUNT_NUMBER}." + ) + assert result[0].resource_id == AWS_ACCOUNT_NUMBER + assert result[0].resource_arn == AWS_ACCOUNT_ARN + assert result[0].region == AWS_REGION @mock_s3 @mock_s3control @@ -102,32 +104,73 @@ class Test_s3_account_level_public_access_blocks: "RestrictPublicBuckets": False, }, ) - from prowler.providers.aws.services.s3.s3_service import S3Control + from prowler.providers.aws.services.s3.s3_service import S3, S3Control audit_info = self.set_mocked_audit_info() with mock.patch( "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", new=audit_info, + ), mock.patch( + "prowler.providers.aws.services.s3.s3_account_level_public_access_blocks.s3_account_level_public_access_blocks.s3_client", + new=S3(audit_info), + ), mock.patch( + "prowler.providers.aws.services.s3.s3_account_level_public_access_blocks.s3_account_level_public_access_blocks.s3control_client", + new=S3Control(audit_info), ): - with mock.patch( - "prowler.providers.aws.services.s3.s3_account_level_public_access_blocks.s3_account_level_public_access_blocks.s3control_client", - new=S3Control(audit_info), - ): - # Test Check - from prowler.providers.aws.services.s3.s3_account_level_public_access_blocks.s3_account_level_public_access_blocks import ( - s3_account_level_public_access_blocks, - ) + # Test Check + from prowler.providers.aws.services.s3.s3_account_level_public_access_blocks.s3_account_level_public_access_blocks import ( + s3_account_level_public_access_blocks, + ) - check = s3_account_level_public_access_blocks() - result = check.execute() + check = s3_account_level_public_access_blocks() + result = check.execute() - assert len(result) == 1 - assert result[0].status == "FAIL" - assert ( - result[0].status_extended - == f"Block Public Access is not configured for the account {AWS_ACCOUNT_NUMBER}." - ) - assert result[0].resource_id == AWS_ACCOUNT_NUMBER - assert result[0].resource_arn == AWS_ACCOUNT_ARN - assert result[0].region == AWS_REGION + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"Block Public Access is not configured for the account {AWS_ACCOUNT_NUMBER}." + ) + assert result[0].resource_id == AWS_ACCOUNT_NUMBER + assert result[0].resource_arn == AWS_ACCOUNT_ARN + assert result[0].region == AWS_REGION + + @mock_s3 + @mock_s3control + def test_bucket_without_account_public_block_ignoring(self): + # Generate S3Control Client + s3control_client = client("s3control", region_name=AWS_REGION) + s3control_client.put_public_access_block( + AccountId=AWS_ACCOUNT_NUMBER, + PublicAccessBlockConfiguration={ + "BlockPublicAcls": False, + "IgnorePublicAcls": False, + "BlockPublicPolicy": False, + "RestrictPublicBuckets": False, + }, + ) + from prowler.providers.aws.services.s3.s3_service import S3, S3Control + + audit_info = self.set_mocked_audit_info() + audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ), mock.patch( + "prowler.providers.aws.services.s3.s3_account_level_public_access_blocks.s3_account_level_public_access_blocks.s3_client", + new=S3(audit_info), + ), mock.patch( + "prowler.providers.aws.services.s3.s3_account_level_public_access_blocks.s3_account_level_public_access_blocks.s3control_client", + new=S3Control(audit_info), + ): + # Test Check + from prowler.providers.aws.services.s3.s3_account_level_public_access_blocks.s3_account_level_public_access_blocks import ( + s3_account_level_public_access_blocks, + ) + + check = s3_account_level_public_access_blocks() + result = check.execute() + + assert len(result) == 0 diff --git a/tests/providers/aws/services/vpc/vpc_flow_logs_enabled/vpc_flow_logs_enabled_test.py b/tests/providers/aws/services/vpc/vpc_flow_logs_enabled/vpc_flow_logs_enabled_test.py index 8663300c..e3a63f76 100644 --- a/tests/providers/aws/services/vpc/vpc_flow_logs_enabled/vpc_flow_logs_enabled_test.py +++ b/tests/providers/aws/services/vpc/vpc_flow_logs_enabled/vpc_flow_logs_enabled_test.py @@ -1,6 +1,6 @@ from unittest import mock -from boto3 import client, session +from boto3 import client, resource, session from moto import mock_ec2 from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info @@ -155,3 +155,70 @@ class Test_vpc_flow_logs_enabled: == f"VPC {vpc['VpcId']} Flow logs are disabled." ) assert result.resource_id == vpc["VpcId"] + + @mock_ec2 + def test_vpc_without_flow_logs_ignoring(self): + from prowler.providers.aws.services.vpc.vpc_service import VPC + + # Create VPC Mocked Resources + ec2_client = client("ec2", region_name=AWS_REGION) + + ec2_client.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"] + + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.vpc.vpc_flow_logs_enabled.vpc_flow_logs_enabled.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.vpc.vpc_flow_logs_enabled.vpc_flow_logs_enabled import ( + vpc_flow_logs_enabled, + ) + + check = vpc_flow_logs_enabled() + result = check.execute() + + assert len(result) == 0 + + @mock_ec2 + def test_vpc_without_flow_logs_ignoring_in_use(self): + from prowler.providers.aws.services.vpc.vpc_service import VPC + + # Create VPC Mocked Resources + ec2 = resource("ec2", region_name=AWS_REGION) + + vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16") + subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18") + ec2.create_network_interface(SubnetId=subnet.id) + current_audit_info = self.set_mocked_audit_info() + current_audit_info.ignore_unused_services = True + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=current_audit_info, + ), mock.patch( + "prowler.providers.aws.services.vpc.vpc_flow_logs_enabled.vpc_flow_logs_enabled.vpc_client", + new=VPC(current_audit_info), + ): + # Test Check + from prowler.providers.aws.services.vpc.vpc_flow_logs_enabled.vpc_flow_logs_enabled import ( + vpc_flow_logs_enabled, + ) + + check = vpc_flow_logs_enabled() + result = check.execute() + + # Search created VPC among default ones + for result in result: + if result.resource_id == vpc.id: + assert result.status == "FAIL" + assert ( + result.status_extended + == f"VPC {vpc.id} Flow logs are disabled." + ) + assert result.resource_id == vpc.id