From c425e8249b1ede615e67a589fd111b430ee58a32 Mon Sep 17 00:00:00 2001 From: Mario Rodriguez Lopez <101330800+MarioRgzLpz@users.noreply.github.com> Date: Tue, 17 Sep 2024 20:01:19 +0200 Subject: [PATCH] fix(inspector2): Ensure Inspector2 is enabled for ECR, EC2, Lambda and Lambda Code (#5061) Co-authored-by: Sergio Garcia <38561120+sergargar@users.noreply.github.com> --- .../inspector2_is_enabled.metadata.json | 18 ++--- .../inspector2_is_enabled.py | 55 +++++++++----- .../services/inspector2/inspector2_service.py | 11 +++ .../inspector2_active_findings_exist_test.py | 16 +++++ .../inspector2_is_enabled_test.py | 71 +++++++++++++++++-- .../inspector2/inspector2_service_test.py | 9 +++ 6 files changed, 150 insertions(+), 30 deletions(-) diff --git a/prowler/providers/aws/services/inspector2/inspector2_is_enabled/inspector2_is_enabled.metadata.json b/prowler/providers/aws/services/inspector2/inspector2_is_enabled/inspector2_is_enabled.metadata.json index ec548c3401..0fc6c26267 100644 --- a/prowler/providers/aws/services/inspector2/inspector2_is_enabled/inspector2_is_enabled.metadata.json +++ b/prowler/providers/aws/services/inspector2/inspector2_is_enabled/inspector2_is_enabled.metadata.json @@ -1,29 +1,31 @@ { "Provider": "aws", "CheckID": "inspector2_is_enabled", - "CheckTitle": "Check if Inspector2 is enabled", + "CheckTitle": "Check if Inspector2 is enabled for Amazon EC2 instances, ECR container images and Lambda functions.", "CheckAliases": [ "inspector2_findings_exist" ], - "CheckType": [], + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices" + ], "ServiceName": "inspector2", "SubServiceName": "", "ResourceIdTemplate": "arn:aws:inspector2:region:account-id/detector-id", "Severity": "medium", - "ResourceType": "Other", - "Description": "Check if Inspector2 is enabled", + "ResourceType": "AwsAccount", + "Description": "Ensure that the new version of Amazon Inspector is enabled in order to help you improve the security and compliance of your AWS cloud environment. Amazon Inspector 2 is a vulnerability management solution that continually scans scans your Amazon EC2 instances, ECR container images, and Lambda functions to identify software vulnerabilities and instances of unintended network exposure.", "Risk": "Without using AWS Inspector, you may not be aware of all the security vulnerabilities in your AWS resources, which could lead to unauthorized access, data breaches, or other security incidents.", "RelatedUrl": "https://docs.aws.amazon.com/inspector/latest/user/findings-understanding.html", "Remediation": { "Code": { - "CLI": "aws inspector2 enable", + "CLI": "aws inspector2 enable --resource-types 'EC2' 'ECR' 'LAMBDA' 'LAMBDA_CODE'", "NativeIaC": "", - "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Inspector/amazon-inspector-findings.html", + "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Inspector2/enable-amazon-inspector2.html", "Terraform": "" }, "Recommendation": { - "Text": "Enable Inspector2", - "Url": "https://docs.aws.amazon.com/inspector/latest/user/what-is-inspector.html" + "Text": "Enable Amazon Inspector 2 for your AWS account.", + "Url": "https://docs.aws.amazon.com/inspector/latest/user/getting_started_tutorial.html" } }, "Categories": [], diff --git a/prowler/providers/aws/services/inspector2/inspector2_is_enabled/inspector2_is_enabled.py b/prowler/providers/aws/services/inspector2/inspector2_is_enabled/inspector2_is_enabled.py index 95969653c3..e735f42661 100644 --- a/prowler/providers/aws/services/inspector2/inspector2_is_enabled/inspector2_is_enabled.py +++ b/prowler/providers/aws/services/inspector2/inspector2_is_enabled/inspector2_is_enabled.py @@ -17,25 +17,44 @@ class inspector2_is_enabled(Check): report.region = inspector.region if inspector.status == "ENABLED": report.status = "PASS" - report.status_extended = "Inspector2 is enabled." + report.status_extended = "Inspector2 is enabled for EC2 instances, ECR container images, Lambda functions and code." + 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 + failed_services = [] + + if inspector.ec2_status != "ENABLED" and ( + inspector2_client.provider.scan_unused_services or ec2_in_region + ): + failed_services.append("EC2") + if inspector.ecr_status != "ENABLED" and ( + inspector2_client.provider.scan_unused_services + or ecr_client.registries[inspector.region].repositories + ): + failed_services.append("ECR") + if inspector.lambda_status != "ENABLED" and ( + inspector2_client.provider.scan_unused_services + or funtions_in_region + ): + failed_services.append("Lambda") + if inspector.lambda_code_status != "ENABLED" and ( + inspector2_client.provider.scan_unused_services + or funtions_in_region + ): + failed_services.append("Lambda Code") + + if failed_services: + report.status = "FAIL" + report.status_extended = f"Inspector2 is not enabled for the following services: {', '.join(failed_services)}." findings.append(report) else: - if not inspector2_client.provider.scan_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 inspector2_client.provider.scan_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) + report.status = "FAIL" + report.status_extended = "Inspector2 is not enabled in this account." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/inspector2/inspector2_service.py b/prowler/providers/aws/services/inspector2/inspector2_service.py index 1c17806392..35626bc926 100644 --- a/prowler/providers/aws/services/inspector2/inspector2_service.py +++ b/prowler/providers/aws/services/inspector2/inspector2_service.py @@ -20,11 +20,18 @@ class Inspector2(AWSService): batch_get_account_status = regional_client.batch_get_account_status( accountIds=[self.audited_account] )["accounts"][0] + resourceStates = batch_get_account_status.get("resourceState") self.inspectors.append( Inspector( id="Inspector2", arn=f"arn:{self.audited_partition}:inspector2:{regional_client.region}:{self.audited_account}:inspector2", status=batch_get_account_status.get("state").get("status"), + ec2_status=resourceStates.get("ec2", {}).get("status"), + ecr_status=resourceStates.get("ecr", {}).get("status"), + lambda_status=resourceStates.get("lambda", {}).get("status"), + lambda_code_status=resourceStates.get("lambdaCode", {}).get( + "status" + ), region=regional_client.region, ) ) @@ -59,4 +66,8 @@ class Inspector(BaseModel): arn: str region: str status: str + ec2_status: str + ecr_status: str + lambda_status: str + lambda_code_status: str active_findings: bool = False diff --git a/tests/providers/aws/services/inspector2/inspector2_active_findings_exist/inspector2_active_findings_exist_test.py b/tests/providers/aws/services/inspector2/inspector2_active_findings_exist/inspector2_active_findings_exist_test.py index 093f29d7a2..ef0abf9f55 100644 --- a/tests/providers/aws/services/inspector2/inspector2_active_findings_exist/inspector2_active_findings_exist_test.py +++ b/tests/providers/aws/services/inspector2/inspector2_active_findings_exist/inspector2_active_findings_exist_test.py @@ -28,6 +28,10 @@ class Test_inspector2_active_findings_exist: id=AWS_ACCOUNT_NUMBER, arn=f"arn:aws:inspector2:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:inspector2", status="ENABLED", + ec2_status="ENABLED", + ecr_status="DISABLED", + lambda_status="DISABLED", + lambda_code_status="ENABLED", region=AWS_REGION_EU_WEST_1, active_findings=False, ) @@ -80,6 +84,10 @@ class Test_inspector2_active_findings_exist: arn=f"arn:aws:inspector2:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:inspector2", region=AWS_REGION_EU_WEST_1, status="ENABLED", + ec2_status="ENABLED", + ecr_status="DISABLED", + lambda_status="DISABLED", + lambda_code_status="ENABLED", active_findings=False, ) ] @@ -131,6 +139,10 @@ class Test_inspector2_active_findings_exist: arn=f"arn:aws:inspector2:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:inspector2", region=AWS_REGION_EU_WEST_1, status="ENABLED", + ec2_status="ENABLED", + ecr_status="DISABLED", + lambda_status="DISABLED", + lambda_code_status="ENABLED", active_findings=True, ) ] @@ -191,6 +203,10 @@ class Test_inspector2_active_findings_exist: id=AWS_ACCOUNT_NUMBER, arn=f"arn:aws:inspector2:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:inspector2", status="DISABLED", + ec2_status="ENABLED", + ecr_status="DISABLED", + lambda_status="DISABLED", + lambda_code_status="ENABLED", region=AWS_REGION_EU_WEST_1, active_findings=False, ) diff --git a/tests/providers/aws/services/inspector2/inspector2_is_enabled/inspector2_is_enabled_test.py b/tests/providers/aws/services/inspector2/inspector2_is_enabled/inspector2_is_enabled_test.py index 34a4fc1922..ab1d691a38 100644 --- a/tests/providers/aws/services/inspector2/inspector2_is_enabled/inspector2_is_enabled_test.py +++ b/tests/providers/aws/services/inspector2/inspector2_is_enabled/inspector2_is_enabled_test.py @@ -33,8 +33,11 @@ class Test_inspector2_is_enabled: id=AWS_ACCOUNT_NUMBER, arn=f"arn:aws:inspector2:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:inspector2", status="DISABLED", + ec2_status="DISABLED", + ecr_status="DISABLED", + lambda_status="DISABLED", + lambda_code_status="DISABLED", region=AWS_REGION_EU_WEST_1, - findings=[], ) ] aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) @@ -57,7 +60,10 @@ class Test_inspector2_is_enabled: assert len(result) == 1 assert result[0].status == "FAIL" - assert result[0].status_extended == "Inspector2 is not enabled." + assert ( + result[0].status_extended + == "Inspector2 is not enabled in this account." + ) assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert ( result[0].resource_arn @@ -79,8 +85,11 @@ class Test_inspector2_is_enabled: id=AWS_ACCOUNT_NUMBER, arn=f"arn:aws:inspector2:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:inspector2", status="ENABLED", + ec2_status="ENABLED", + ecr_status="ENABLED", + lambda_status="ENABLED", + lambda_code_status="ENABLED", region=AWS_REGION_EU_WEST_1, - findings=[], ) ] aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) @@ -103,7 +112,61 @@ class Test_inspector2_is_enabled: assert len(result) == 1 assert result[0].status == "PASS" - assert result[0].status_extended == "Inspector2 is enabled." + assert ( + result[0].status_extended + == "Inspector2 is enabled for EC2 instances, ECR container images, Lambda functions and code." + ) + assert result[0].resource_id == AWS_ACCOUNT_NUMBER + assert ( + result[0].resource_arn + == f"arn:aws:inspector2:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:inspector2" + ) + assert result[0].region == AWS_REGION_EU_WEST_1 + + def test_enabled_finding(self): + inspector2_client = mock.MagicMock + inspector2_client.provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + inspector2_client.audited_account = AWS_ACCOUNT_NUMBER + inspector2_client.audited_account_arn = ( + f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + ) + inspector2_client.region = AWS_REGION_EU_WEST_1 + inspector2_client.inspectors = [ + Inspector( + id=AWS_ACCOUNT_NUMBER, + arn=f"arn:aws:inspector2:{AWS_REGION_EU_WEST_1}:{AWS_ACCOUNT_NUMBER}:inspector2", + status="ENABLED", + ec2_status="ENABLED", + ecr_status="DISABLED", + lambda_status="DISABLED", + lambda_code_status="ENABLED", + region=AWS_REGION_EU_WEST_1, + ) + ] + aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1]) + + with mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=aws_provider, + ): + with mock.patch( + "prowler.providers.aws.services.inspector2.inspector2_is_enabled.inspector2_is_enabled.inspector2_client", + new=inspector2_client, + ): + # Test Check + from prowler.providers.aws.services.inspector2.inspector2_is_enabled.inspector2_is_enabled import ( + inspector2_is_enabled, + ) + + check = inspector2_is_enabled() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "Inspector2 is not enabled for the following services: ECR, Lambda." + ) assert result[0].resource_id == AWS_ACCOUNT_NUMBER assert ( result[0].resource_arn diff --git a/tests/providers/aws/services/inspector2/inspector2_service_test.py b/tests/providers/aws/services/inspector2/inspector2_service_test.py index 8f865ac898..c84797eacd 100644 --- a/tests/providers/aws/services/inspector2/inspector2_service_test.py +++ b/tests/providers/aws/services/inspector2/inspector2_service_test.py @@ -41,6 +41,11 @@ def mock_make_api_call(self, operation_name, kwargs): "errorMessage": "string", "status": "ENABLED", }, + "lambdaCode": { + "errorCode": "ALREADY_ENABLED", + "errorMessage": "string", + "status": "ENABLED", + }, }, "state": { "errorCode": "ALREADY_ENABLED", @@ -104,6 +109,10 @@ class Test_Inspector2_Service: assert inspector2.inspectors[0].id == "Inspector2" assert inspector2.inspectors[0].region == AWS_REGION_EU_WEST_1 assert inspector2.inspectors[0].status == "ENABLED" + assert inspector2.inspectors[0].ec2_status == "ENABLED" + assert inspector2.inspectors[0].ecr_status == "ENABLED" + assert inspector2.inspectors[0].lambda_status == "ENABLED" + assert inspector2.inspectors[0].lambda_code_status == "ENABLED" def test_list_active_findings(self): aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])