From c10b31e9d0232dbfb53cec0cc81cb088eacb34ee Mon Sep 17 00:00:00 2001 From: Sergio Garcia <38561120+sergargar@users.noreply.github.com> Date: Wed, 24 May 2023 10:44:51 +0200 Subject: [PATCH] fix(categories): remove empty categories from metadata (#2401) --- prowler/__main__.py | 2 +- prowler/lib/check/check.py | 5 +- .../drs_job_exist/drs_job_exist.metadata.json | 4 +- ...incidents_enabled_with_plans.metadata.json | 4 +- tests/lib/check/check_test.py | 13 ++ .../check/fixtures/bulk_checks_metadata.py | 152 ++++++++++++++++++ 6 files changed, 171 insertions(+), 9 deletions(-) create mode 100644 tests/lib/check/fixtures/bulk_checks_metadata.py diff --git a/prowler/__main__.py b/prowler/__main__.py index 6ac7a741..5d877f32 100644 --- a/prowler/__main__.py +++ b/prowler/__main__.py @@ -80,7 +80,7 @@ def prowler(): bulk_checks_metadata = bulk_load_checks_metadata(provider) if args.list_categories: - print_categories(list_categories(provider, bulk_checks_metadata)) + print_categories(list_categories(bulk_checks_metadata)) sys.exit() bulk_compliance_frameworks = {} diff --git a/prowler/lib/check/check.py b/prowler/lib/check/check.py index bd2a3bea..f4762b37 100644 --- a/prowler/lib/check/check.py +++ b/prowler/lib/check/check.py @@ -201,11 +201,12 @@ def list_checks(provider: str) -> set(): return sorted(available_checks) -def list_categories(provider: str, bulk_checks_metadata: dict) -> set(): +def list_categories(bulk_checks_metadata: dict) -> set(): available_categories = set() for check in bulk_checks_metadata.values(): for cat in check.Categories: - available_categories.add(cat) + if cat: + available_categories.add(cat) return available_categories diff --git a/prowler/providers/aws/services/drs/drs_job_exist/drs_job_exist.metadata.json b/prowler/providers/aws/services/drs/drs_job_exist/drs_job_exist.metadata.json index 2e3c8e32..416bd22a 100644 --- a/prowler/providers/aws/services/drs/drs_job_exist/drs_job_exist.metadata.json +++ b/prowler/providers/aws/services/drs/drs_job_exist/drs_job_exist.metadata.json @@ -23,9 +23,7 @@ "Url": "https://docs.aws.amazon.com/drs/latest/userguide/what-is-drs.html" } }, - "Categories": [ - "" - ], + "Categories": [], "DependsOn": [], "RelatedTo": [], "Notes": "" 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 1cfccf4c..edf0c425 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 @@ -23,9 +23,7 @@ "Url": "" } }, - "Categories": [ - "" - ], + "Categories": [], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/tests/lib/check/check_test.py b/tests/lib/check/check_test.py index da8f63d2..3aecd55c 100644 --- a/tests/lib/check/check_test.py +++ b/tests/lib/check/check_test.py @@ -4,12 +4,14 @@ from importlib.machinery import FileFinder from pkgutil import ModuleInfo from boto3 import client, session +from fixtures.bulk_checks_metadata import test_bulk_checks_metadata from mock import patch from moto import mock_s3 from prowler.lib.check.check import ( exclude_checks_to_run, exclude_services_to_run, + list_categories, list_modules, list_services, parse_checks_from_file, @@ -319,6 +321,17 @@ class Test_Check: listed_services = list_services(provider) assert listed_services == sorted(expected_services) + def test_list_categories(self): + expected_categories = { + "secrets", + "forensics-ready", + "encryption", + "internet-exposed", + "trustboundaries", + } + listed_categories = list_categories(test_bulk_checks_metadata) + assert listed_categories == expected_categories + @patch("prowler.lib.check.check.list_modules", new=mock_list_modules) def test_recover_checks_from_provider(self): provider = "azure" diff --git a/tests/lib/check/fixtures/bulk_checks_metadata.py b/tests/lib/check/fixtures/bulk_checks_metadata.py new file mode 100644 index 00000000..492f9da3 --- /dev/null +++ b/tests/lib/check/fixtures/bulk_checks_metadata.py @@ -0,0 +1,152 @@ +from prowler.lib.check.models import ( + Check_Metadata_Model, + Code, + Recommendation, + Remediation, +) + +test_bulk_checks_metadata = { + "vpc_peering_routing_tables_with_least_privilege": Check_Metadata_Model( + Provider="aws", + CheckID="vpc_peering_routing_tables_with_least_privilege", + CheckTitle="Ensure routing tables for VPC peering are least access.", + CheckType=["Infrastructure Security"], + ServiceName="vpc", + SubServiceName="route_table", + ResourceIdTemplate="arn:partition:service:region:account-id:resource-id", + Severity="medium", + ResourceType="AwsEc2VpcPeeringConnection", + Description="Ensure routing tables for VPC peering are least access.", + Risk="Being highly selective in peering routing tables is a very effective way of minimizing the impact of breach as resources outside of these routes are inaccessible to the peered VPC.", + RelatedUrl="", + Remediation=Remediation( + Code=Code( + NativeIaC="", + Terraform="", + CLI="https://docs.bridgecrew.io/docs/networking_5#cli-command", + Other="", + ), + Recommendation=Recommendation( + Text="Review routing tables of peered VPCs for whether they route all subnets of each VPC and whether that is necessary to accomplish the intended purposes for peering the VPCs.", + Url="https://docs.aws.amazon.com/vpc/latest/peering/peering-configurations-partial-access.html", + ), + ), + Categories=["forensics-ready"], + DependsOn=[], + RelatedTo=[], + Notes="", + Compliance=None, + ), + "vpc_subnet_different_az": Check_Metadata_Model( + Provider="aws", + CheckID="vpc_subnet_different_az", + CheckTitle="Ensure all vpc has subnets in more than one availability zone", + CheckType=["Infrastructure Security"], + ServiceName="vpc", + SubServiceName="subnet", + 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", + Risk="", + RelatedUrl="https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html", + Remediation=Remediation( + Code=Code( + NativeIaC="", Terraform="", CLI="aws ec2 create-subnet", Other="" + ), + Recommendation=Recommendation( + Text="Ensure all vpc has subnets in more than one availability zone", + Url="", + ), + ), + Categories=["secrets", ""], + DependsOn=[], + RelatedTo=[], + Notes="", + Compliance=None, + ), + "vpc_subnet_separate_private_public": Check_Metadata_Model( + Provider="aws", + CheckID="vpc_subnet_separate_private_public", + CheckTitle="Ensure all vpc has public and private subnets defined", + CheckType=["Infrastructure Security"], + ServiceName="vpc", + SubServiceName="subnet", + ResourceIdTemplate="arn:partition:service:region:account-id:resource-id", + Severity="medium", + ResourceType="AwsEc2Vpc", + Description="Ensure all vpc has public and private subnets defined", + Risk="", + RelatedUrl="https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html", + Remediation=Remediation( + Code=Code( + NativeIaC="", Terraform="", CLI="aws ec2 create-subnet", Other="" + ), + Recommendation=Recommendation( + Text="Ensure all vpc has public and private subnets defined", Url="" + ), + ), + Categories=["internet-exposed", "trustboundaries"], + DependsOn=[], + RelatedTo=[], + Notes="", + Compliance=None, + ), + "workspaces_volume_encryption_enabled": Check_Metadata_Model( + Provider="aws", + CheckID="workspaces_volume_encryption_enabled", + CheckTitle="Ensure that your Amazon WorkSpaces storage volumes are encrypted in order to meet security and compliance requirements", + CheckType=[], + ServiceName="workspaces", + SubServiceName="", + ResourceIdTemplate="arn:aws:workspaces:region:account-id:workspace", + Severity="high", + ResourceType="AwsWorkspaces", + Description="Ensure that your Amazon WorkSpaces storage volumes are encrypted in order to meet security and compliance requirements", + Risk="If the value listed in the Volume Encryption column is Disabled the selected AWS WorkSpaces instance volumes (root and user volumes) are not encrypted. Therefore your data-at-rest is not protected from unauthorized access and does not meet the compliance requirements regarding data encryption.", + RelatedUrl="https://docs.aws.amazon.com/workspaces/latest/adminguide/encrypt-workspaces.html", + Remediation=Remediation( + Code=Code( + NativeIaC="https://docs.bridgecrew.io/docs/ensure-that-workspace-root-volumes-are-encrypted#cloudformation", + Terraform="https://docs.bridgecrew.io/docs/ensure-that-workspace-root-volumes-are-encrypted#terraform", + CLI="", + Other="https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/WorkSpaces/storage-encryption.html", + ), + Recommendation=Recommendation( + Text="WorkSpaces is integrated with the AWS Key Management Service (AWS KMS). This enables you to encrypt storage volumes of WorkSpaces using AWS KMS Key. When you launch a WorkSpace you can encrypt the root volume (for Microsoft Windows - the C drive; for Linux - /) and the user volume (for Windows - the D drive; for Linux - /home). Doing so ensures that the data stored at rest - disk I/O to the volume - and snapshots created from the volumes are all encrypted", + Url="https://docs.aws.amazon.com/workspaces/latest/adminguide/encrypt-workspaces.html", + ), + ), + Categories=["encryption"], + DependsOn=[], + RelatedTo=[], + Notes="", + Compliance=None, + ), + "workspaces_vpc_2private_1public_subnets_nat": Check_Metadata_Model( + Provider="aws", + CheckID="workspaces_vpc_2private_1public_subnets_nat", + CheckTitle="Ensure that the Workspaces VPC are deployed following the best practices using 1 public subnet and 2 private subnets with a NAT Gateway attached", + CheckType=[], + ServiceName="workspaces", + SubServiceName="", + ResourceIdTemplate="arn:aws:workspaces:region:account-id:workspace", + Severity="medium", + ResourceType="AwsWorkspaces", + Description="Ensure that the Workspaces VPC are deployed following the best practices using 1 public subnet and 2 private subnets with a NAT Gateway attached", + Risk="Proper network segmentation is a key security best practice. Workspaces VPC should be deployed using 1 public subnet and 2 private subnets with a NAT Gateway attached", + RelatedUrl="https://docs.aws.amazon.com/workspaces/latest/adminguide/amazon-workspaces-vpc.html", + Remediation=Remediation( + Code=Code(NativeIaC="", Terraform="", CLI="", Other=""), + Recommendation=Recommendation( + Text="Follow the documentation and deploy Workspaces VPC using 1 public subnet and 2 private subnets with a NAT Gateway attached", + Url="https://docs.aws.amazon.com/workspaces/latest/adminguide/amazon-workspaces-vpc.html", + ), + ), + Categories=[""], + DependsOn=[], + RelatedTo=[], + Notes="", + Compliance=None, + ), +}