diff --git a/prowler/lib/check/models.py b/prowler/lib/check/models.py index 6cb1c210a9..6711026023 100644 --- a/prowler/lib/check/models.py +++ b/prowler/lib/check/models.py @@ -210,8 +210,10 @@ class CheckMetadata(BaseModel): valid_resource_type(resource_type): Validator function to validate the resource type is not empty. validate_service_name(service_name, values): Validator function to validate the service name matches CheckID. valid_check_id(check_id): Validator function to validate the CheckID format. - validate_check_title(check_title): Validator function to validate CheckTitle max length (150 chars). - validate_check_type(check_type, values): Validator function to validate CheckType - no empty strings for all providers, plus predefined types validation for AWS (loaded from config file). + validate_check_title(check_title): Validator function to validate CheckTitle max length (150 chars) and not starting with 'Ensure'. + validate_related_url(related_url): Validator function to validate RelatedUrl is empty (deprecated field). + validate_recommendation_url(remediation): Validator function to validate Recommendation URL points to Prowler Hub. + validate_check_type(check_type, values): Validator function to validate CheckType - must be empty for non-AWS providers, no empty strings and predefined types validation for AWS. validate_description(description): Validator function to validate Description max length (400 chars). validate_risk(risk): Validator function to validate Risk max length (400 chars). validate_resource_group(resource_group): Validator function to validate ResourceGroup against predefined values. @@ -309,20 +311,47 @@ class CheckMetadata(BaseModel): raise ValueError( f"CheckTitle must not exceed 150 characters, got {len(check_title)} characters" ) + if check_title.startswith("Ensure"): + raise ValueError( + "CheckTitle must not start with 'Ensure'. Use a descriptive title that focuses on the security state." + ) return check_title + @validator("RelatedUrl", pre=True, always=True) + def validate_related_url(cls, related_url): + if related_url: + raise ValueError("RelatedUrl must be empty. This field is deprecated.") + return related_url + + @validator("Remediation") + def validate_recommendation_url(remediation): + url = remediation.Recommendation.Url + if url and not url.startswith("https://hub.prowler.com/"): + raise ValueError( + f"Remediation Recommendation URL must point to Prowler Hub (https://hub.prowler.com/...), got '{url}'." + ) + return remediation + @validator("CheckType", pre=True, always=True) def validate_check_type(cls, check_type, values): - # Check for empty strings in the list - applies to ALL providers + provider = values.get("Provider", "").lower() + + # Non-AWS providers must have an empty CheckType list + if provider != "aws" and provider not in EXTERNAL_TOOL_PROVIDERS: + if check_type: + raise ValueError( + f"CheckType must be empty for non-AWS providers. Got {check_type} for provider '{provider}'." + ) + return check_type + + # Check for empty strings in the list - applies to AWS for i, check_type_item in enumerate(check_type): if not check_type_item or check_type_item.strip() == "": raise ValueError( f"CheckType list cannot contain empty strings. Found empty string at index {i}." ) - provider = values.get("Provider", "").lower() - - # For AWS provider, also validate against config hierarchy (like custom checks) + # For AWS provider, validate against config hierarchy if provider == "aws": for check_type_item in check_type: if not _validate_aws_check_type_in_config(check_type_item): diff --git a/tests/lib/check/check_loader_test.py b/tests/lib/check/check_loader_test.py index f082557778..140dbdaaa7 100644 --- a/tests/lib/check/check_loader_test.py +++ b/tests/lib/check/check_loader_test.py @@ -42,7 +42,7 @@ class TestCheckLoader: ResourceType="AwsS3Bucket", Description="Check S3 Bucket Level Public Access Block.", Risk="Public access policies may be applied to sensitive data buckets.", - RelatedUrl="https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html", + RelatedUrl="", Remediation=Remediation( Code=Code( NativeIaC="", @@ -52,7 +52,7 @@ class TestCheckLoader: ), Recommendation=Recommendation( Text="You can enable Public Access Block at the bucket level to prevent the exposure of your data stored in S3.", - Url="https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html", + Url="https://hub.prowler.com/check/s3_bucket_level_public_access_block", ), ), Categories=["internet-exposed"], @@ -78,7 +78,7 @@ class TestCheckLoader: ResourceType="AwsIamUser", Description="Check IAM User No MFA.", Risk="IAM users should have Multi-Factor Authentication (MFA) enabled.", - RelatedUrl="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html", + RelatedUrl="", Remediation=Remediation( Code=Code( NativeIaC="", @@ -88,7 +88,7 @@ class TestCheckLoader: ), Recommendation=Recommendation( Text="You can enable MFA for your IAM user to prevent unauthorized access to your AWS account.", - Url="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html", + Url="https://hub.prowler.com/check/iam_user_no_mfa", ), ), Categories=[], @@ -102,7 +102,7 @@ class TestCheckLoader: return CheckMetadata( Provider="aws", CheckID=CLOUDTRAIL_THREAT_DETECTION_ENUMERATION_NAME, - CheckTitle="Ensure there are no potential enumeration threats in CloudTrail", + CheckTitle="CloudTrail should not have potential enumeration threats", CheckType=["TTPs/Discovery"], ServiceName="cloudtrail", SubServiceName="", @@ -116,7 +116,7 @@ class TestCheckLoader: Code=Code(CLI="", NativeIaC="", Other="", Terraform=""), Recommendation=Recommendation( Text="To remediate this issue, ensure that there are no potential enumeration threats in CloudTrail.", - Url="https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-logging-data-events", + Url="https://hub.prowler.com/check/cloudtrail_threat_detection_enumeration", ), ), Categories=["threat-detection"], diff --git a/tests/lib/check/check_test.py b/tests/lib/check/check_test.py index 868d4c66fe..aec9d72e00 100644 --- a/tests/lib/check/check_test.py +++ b/tests/lib/check/check_test.py @@ -412,7 +412,7 @@ class TestCheck: }, "expected": { "CheckID": "iam_user_accesskey_unused", - "CheckTitle": "Ensure Access Keys unused are disabled", + "CheckTitle": "Access Keys unused should be disabled", "ServiceName": "iam", "Severity": "low", }, @@ -502,7 +502,7 @@ class TestCheck: "ResourceType": "AwsCustomResource", "Description": "A test custom check", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": {"CLI": "", "NativeIaC": "", "Other": "", "Terraform": ""}, "Recommendation": {"Text": "", "Url": ""}, @@ -614,7 +614,7 @@ class TestCheck: "forensics-ready", "encryption", "internet-exposed", - "trustboundaries", + "trust-boundaries", } listed_categories = list_categories(test_bulk_checks_metadata) assert listed_categories == expected_categories diff --git a/tests/lib/check/compliance_check_test.py b/tests/lib/check/compliance_check_test.py index 9e45fb8acc..73f93e3b38 100644 --- a/tests/lib/check/compliance_check_test.py +++ b/tests/lib/check/compliance_check_test.py @@ -205,7 +205,7 @@ class TestCompliance: ResourceType="resource1", Description="Description 1", Risk="risk1", - RelatedUrl="url1", + RelatedUrl="", Remediation={ "Code": { "CLI": "cli1", @@ -213,7 +213,10 @@ class TestCompliance: "Other": "other1", "Terraform": "terraform1", }, - "Recommendation": {"Text": "text1", "Url": "url1"}, + "Recommendation": { + "Text": "text1", + "Url": "https://hub.prowler.com/check/accessanalyzer_enabled", + }, }, Categories=["encryption"], DependsOn=["dependency1"], @@ -233,7 +236,7 @@ class TestCompliance: ResourceType="resource2", Description="Description 2", Risk="risk2", - RelatedUrl="url2", + RelatedUrl="", Remediation={ "Code": { "CLI": "cli2", @@ -241,7 +244,10 @@ class TestCompliance: "Other": "other2", "Terraform": "terraform2", }, - "Recommendation": {"Text": "text2", "Url": "url2"}, + "Recommendation": { + "Text": "text2", + "Url": "https://hub.prowler.com/check/iam_user_mfa_enabled_console_access", + }, }, Categories=["logging"], DependsOn=["dependency2"], diff --git a/tests/lib/check/custom_checks_metadata_test.py b/tests/lib/check/custom_checks_metadata_test.py index 32c57199bc..9037131675 100644 --- a/tests/lib/check/custom_checks_metadata_test.py +++ b/tests/lib/check/custom_checks_metadata_test.py @@ -27,7 +27,9 @@ S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_REMEDIATION_OTHER = "https://github.com/clou S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_REMEDIATION_TEXT = ( "Enable the S3 bucket level public access block." ) -S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_REMEDIATION_URL = "https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html" +S3_BUCKET_LEVEL_PUBLIC_ACCESS_BLOCK_REMEDIATION_URL = ( + "https://hub.prowler.com/check/s3_bucket_level_public_access_block" +) class TestCustomChecksMetadata: @@ -45,7 +47,7 @@ class TestCustomChecksMetadata: ResourceType="AwsS3Bucket", Description="Check S3 Bucket Level Public Access Block.", Risk="Public access policies may be applied to sensitive data buckets.", - RelatedUrl="https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html", + RelatedUrl="", Remediation=Remediation( Code=Code( NativeIaC="", diff --git a/tests/lib/check/fixtures/bulk_checks_metadata.py b/tests/lib/check/fixtures/bulk_checks_metadata.py index 878d694a75..5cd8c649e4 100644 --- a/tests/lib/check/fixtures/bulk_checks_metadata.py +++ b/tests/lib/check/fixtures/bulk_checks_metadata.py @@ -4,7 +4,7 @@ test_bulk_checks_metadata = { "vpc_peering_routing_tables_with_least_privilege": CheckMetadata( Provider="aws", CheckID="vpc_peering_routing_tables_with_least_privilege", - CheckTitle="Ensure routing tables for VPC peering are least access.", + CheckTitle="VPC peering routing tables should follow least access.", CheckType=[ "Software and Configuration Checks/AWS Security Best Practices/Network Reachability" ], @@ -13,7 +13,7 @@ test_bulk_checks_metadata = { ResourceIdTemplate="arn:partition:service:region:account-id:resource-id", Severity="medium", ResourceType="AwsEc2VpcPeeringConnection", - Description="Ensure routing tables for VPC peering are least access.", + Description="VPC peering routing tables should follow 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( @@ -25,7 +25,7 @@ test_bulk_checks_metadata = { ), 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", + Url="https://hub.prowler.com/check/vpc_peering_routing_tables_with_least_privilege", ), ), Categories=["forensics-ready"], @@ -37,7 +37,7 @@ test_bulk_checks_metadata = { "vpc_subnet_different_az": CheckMetadata( Provider="aws", CheckID="vpc_subnet_different_az", - CheckTitle="Ensure all vpc has subnets in more than one availability zone", + CheckTitle="VPC should have subnets in more than one availability zone", CheckType=[ "Software and Configuration Checks/AWS Security Best Practices/Network Reachability" ], @@ -48,13 +48,13 @@ test_bulk_checks_metadata = { 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", + RelatedUrl="", 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", + Text="VPC should have subnets in more than one availability zone", Url="", ), ), @@ -67,7 +67,7 @@ test_bulk_checks_metadata = { "vpc_subnet_separate_private_public": CheckMetadata( Provider="aws", CheckID="vpc_subnet_separate_private_public", - CheckTitle="Ensure all vpc has public and private subnets defined", + CheckTitle="VPC should have public and private subnets defined", CheckType=[ "Software and Configuration Checks/AWS Security Best Practices/Network Reachability" ], @@ -78,13 +78,13 @@ test_bulk_checks_metadata = { 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", + RelatedUrl="", 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="" + Text="VPC should have public and private subnets defined", Url="" ), ), Categories=["internet-exposed", "trust-boundaries"], @@ -96,7 +96,7 @@ test_bulk_checks_metadata = { "workspaces_volume_encryption_enabled": CheckMetadata( 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", + CheckTitle="Amazon WorkSpaces storage volumes should be encrypted", CheckType=[ "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis" ], @@ -105,9 +105,9 @@ test_bulk_checks_metadata = { 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", + Description="Amazon WorkSpaces storage volumes should be encrypted 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", + RelatedUrl="", Remediation=Remediation( Code=Code( NativeIaC="https://docs.prowler.com/checks/ensure-that-workspace-root-volumes-are-encrypted#cloudformation", @@ -117,7 +117,7 @@ test_bulk_checks_metadata = { ), 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", + Url="https://hub.prowler.com/check/workspaces_volume_encryption_enabled", ), ), Categories=["encryption"], @@ -129,7 +129,7 @@ test_bulk_checks_metadata = { "workspaces_vpc_2private_1public_subnets_nat": CheckMetadata( 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", + CheckTitle="Workspaces VPC should use 1 public and 2 private subnets with NAT Gateway", CheckType=[ "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis" ], @@ -138,14 +138,14 @@ test_bulk_checks_metadata = { 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", + Description="Workspaces VPC should be deployed with 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", + RelatedUrl="", 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", + Url="https://hub.prowler.com/check/workspaces_vpc_2private_1public_subnets_nat", ), ), Categories=[], diff --git a/tests/lib/check/fixtures/metadata.json b/tests/lib/check/fixtures/metadata.json index a376d491a9..b26438aac8 100644 --- a/tests/lib/check/fixtures/metadata.json +++ b/tests/lib/check/fixtures/metadata.json @@ -1,10 +1,10 @@ { "Categories": [ - "cat-one", - "cat-two" + "encryption", + "logging" ], "CheckID": "iam_user_accesskey_unused", - "CheckTitle": "Ensure Access Keys unused are disabled", + "CheckTitle": "Access Keys unused should be disabled", "CheckType": [ "Software and Configuration Checks" ], @@ -25,14 +25,14 @@ "othercheck1", "othercheck2" ], - "Description": "Ensure Access Keys unused are disabled", + "Description": "Access Keys unused should be disabled", "Notes": "additional information", "Provider": "aws", "RelatedTo": [ "othercheck3", "othercheck4" ], - "RelatedUrl": "https://serviceofficialsiteorpageforthissubject", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "cli command or URL to the cli command location.", @@ -42,7 +42,7 @@ }, "Recommendation": { "Text": "Run sudo yum update and cross your fingers and toes.", - "Url": "https://myfp.com/recommendations/dangerous_things_and_how_to_fix_them.html" + "Url": "https://hub.prowler.com/check/iam_user_accesskey_unused" } }, "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", diff --git a/tests/lib/check/models_test.py b/tests/lib/check/models_test.py index 4726cd3f04..8efa307c54 100644 --- a/tests/lib/check/models_test.py +++ b/tests/lib/check/models_test.py @@ -19,7 +19,7 @@ mock_metadata = CheckMetadata( ResourceType="resource1", Description="Description 1", Risk="risk1", - RelatedUrl="url1", + RelatedUrl="", Remediation={ "Code": { "CLI": "cli1", @@ -27,7 +27,10 @@ mock_metadata = CheckMetadata( "Other": "other1", "Terraform": "terraform1", }, - "Recommendation": {"Text": "text1", "Url": "url1"}, + "Recommendation": { + "Text": "text1", + "Url": "https://hub.prowler.com/check/accessanalyzer_enabled", + }, }, Categories=["encryption"], DependsOn=["dependency1"], @@ -48,7 +51,7 @@ mock_metadata_lambda = CheckMetadata( ResourceType="resource1", Description="Description 1", Risk="risk1", - RelatedUrl="url1", + RelatedUrl="", Remediation={ "Code": { "CLI": "cli1", @@ -56,7 +59,10 @@ mock_metadata_lambda = CheckMetadata( "Other": "other1", "Terraform": "terraform1", }, - "Recommendation": {"Text": "text1", "Url": "url1"}, + "Recommendation": { + "Text": "text1", + "Url": "https://hub.prowler.com/check/awslambda_function_url_public", + }, }, Categories=["encryption"], DependsOn=["dependency1"], @@ -340,9 +346,7 @@ class TestCheckMetadataValidators: "Provider": "azure", "CheckID": "test_check", "CheckTitle": "Test Check", - "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices/Network Reachability" - ], + "CheckType": [], "ServiceName": "test", "SubServiceName": "subtest", "ResourceIdTemplate": "template", @@ -350,7 +354,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -360,7 +364,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption", "logging", "secrets"], @@ -389,7 +393,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -399,7 +403,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": [123], # Invalid: number instead of string @@ -428,7 +432,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -438,7 +442,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["invalid_category!"], # Invalid: contains special character @@ -470,7 +474,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -480,7 +484,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["not-a-real-category"], # Invalid: not in predefined list @@ -504,7 +508,7 @@ class TestCheckMetadataValidators: "Provider": "azure", "CheckID": "test_check", "CheckTitle": "Test Check", - "CheckType": ["Security"], + "CheckType": [], "ServiceName": "test", "SubServiceName": "subtest", "ResourceIdTemplate": "template", @@ -512,7 +516,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -522,7 +526,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": [category], @@ -539,9 +543,7 @@ class TestCheckMetadataValidators: "Provider": "azure", "CheckID": "test_check", "CheckTitle": "Test Check", - "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices/Network Reachability" - ], + "CheckType": [], "ServiceName": "test", "SubServiceName": "subtest", "ResourceIdTemplate": "template", @@ -549,7 +551,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -559,7 +561,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -577,9 +579,7 @@ class TestCheckMetadataValidators: "Provider": "azure", "CheckID": "test_check", "CheckTitle": "Test Check", - "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices/Network Reachability" - ], + "CheckType": [], "ServiceName": "test", "SubServiceName": "subtest", "ResourceIdTemplate": "template", @@ -587,7 +587,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "aws iam create-role --role-name test", # Valid CLI command @@ -597,7 +597,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -626,7 +626,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "https://example.com/command", # Invalid: URL instead of command @@ -636,7 +636,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -655,9 +655,7 @@ class TestCheckMetadataValidators: "Provider": "azure", "CheckID": "test_check", "CheckTitle": "Test Check", - "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices/Network Reachability" - ], + "CheckType": [], "ServiceName": "test", "SubServiceName": "subtest", "ResourceIdTemplate": "template", @@ -665,7 +663,7 @@ class TestCheckMetadataValidators: "ResourceType": "AWS::IAM::Role", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -675,7 +673,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -703,7 +701,7 @@ class TestCheckMetadataValidators: "ResourceType": "", # Invalid: empty string "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -713,7 +711,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -732,9 +730,7 @@ class TestCheckMetadataValidators: "Provider": "azure", "CheckID": "s3_bucket_public_read", "CheckTitle": "Test Check", - "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices/Network Reachability" - ], + "CheckType": [], "ServiceName": "s3", # Matches first part of CheckID "SubServiceName": "subtest", "ResourceIdTemplate": "template", @@ -742,7 +738,7 @@ class TestCheckMetadataValidators: "ResourceType": "AWS::S3::Bucket", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -752,7 +748,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -780,7 +776,7 @@ class TestCheckMetadataValidators: "ResourceType": "AWS::S3::Bucket", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -790,7 +786,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -820,7 +816,7 @@ class TestCheckMetadataValidators: "ResourceType": "AWS::S3::Bucket", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -830,7 +826,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -859,7 +855,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -869,7 +865,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -887,9 +883,7 @@ class TestCheckMetadataValidators: "Provider": "azure", "CheckID": "s3_bucket_public_read_check", "CheckTitle": "Test Check", - "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices/Network Reachability" - ], + "CheckType": [], "ServiceName": "s3", "SubServiceName": "subtest", "ResourceIdTemplate": "template", @@ -897,7 +891,7 @@ class TestCheckMetadataValidators: "ResourceType": "AWS::S3::Bucket", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -907,7 +901,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -935,7 +929,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -945,7 +939,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -974,7 +968,7 @@ class TestCheckMetadataValidators: "ResourceType": "AWS::S3::Bucket", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -984,7 +978,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1006,9 +1000,7 @@ class TestCheckMetadataValidators: "Provider": "azure", "CheckID": "test_check", "CheckTitle": "A" * 150, # Exactly 150 characters - "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices/Network Reachability" - ], + "CheckType": [], "ServiceName": "test", "SubServiceName": "subtest", "ResourceIdTemplate": "template", @@ -1016,7 +1008,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1026,7 +1018,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1054,7 +1046,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1064,7 +1056,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1079,13 +1071,15 @@ class TestCheckMetadataValidators: exc_info.value ) - def test_validate_check_type_success(self): - """Test CheckType validation with valid check types""" - valid_metadata = { - "Provider": "azure", # Using non-AWS provider to avoid config validation + def test_validate_check_title_failure_starts_with_ensure(self): + """Test CheckTitle validation fails when starting with 'Ensure'""" + invalid_metadata = { + "Provider": "aws", "CheckID": "test_check", - "CheckTitle": "Test Check", - "CheckType": ["Security", "Network"], + "CheckTitle": "Ensure S3 buckets have encryption enabled", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices" + ], "ServiceName": "test", "SubServiceName": "subtest", "ResourceIdTemplate": "template", @@ -1093,7 +1087,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1103,7 +1097,85 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", + }, + }, + "Categories": ["encryption"], + "DependsOn": [], + "RelatedTo": [], + "Notes": "Test notes", + } + + with pytest.raises(ValidationError) as exc_info: + CheckMetadata(**invalid_metadata) + assert "CheckTitle must not start with 'Ensure'" in str(exc_info.value) + + def test_validate_related_url_must_be_empty(self): + """Test RelatedUrl validation fails when not empty""" + invalid_metadata = { + "Provider": "aws", + "CheckID": "test_check", + "CheckTitle": "Test Check", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices" + ], + "ServiceName": "test", + "SubServiceName": "subtest", + "ResourceIdTemplate": "template", + "Severity": "high", + "ResourceType": "TestResource", + "Description": "Test description", + "Risk": "Test risk", + "RelatedUrl": "https://example.com", # Invalid: must be empty + "Remediation": { + "Code": { + "CLI": "test command", + "NativeIaC": "test native", + "Other": "test other", + "Terraform": "test terraform", + }, + "Recommendation": { + "Text": "test recommendation", + "Url": "https://hub.prowler.com/check/test_check", + }, + }, + "Categories": ["encryption"], + "DependsOn": [], + "RelatedTo": [], + "Notes": "Test notes", + } + + with pytest.raises(ValidationError) as exc_info: + CheckMetadata(**invalid_metadata) + assert "RelatedUrl must be empty" in str(exc_info.value) + + def test_validate_related_url_empty_is_valid(self): + """Test RelatedUrl validation passes when empty""" + valid_metadata = { + "Provider": "aws", + "CheckID": "test_check", + "CheckTitle": "Test Check", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices" + ], + "ServiceName": "test", + "SubServiceName": "subtest", + "ResourceIdTemplate": "template", + "Severity": "high", + "ResourceType": "TestResource", + "Description": "Test description", + "Risk": "Test risk", + "RelatedUrl": "", + "Remediation": { + "Code": { + "CLI": "test command", + "NativeIaC": "test native", + "Other": "test other", + "Terraform": "test terraform", + }, + "Recommendation": { + "Text": "test recommendation", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1113,15 +1185,17 @@ class TestCheckMetadataValidators: } check_metadata = CheckMetadata(**valid_metadata) - assert check_metadata.CheckType == ["Security", "Network"] + assert check_metadata.RelatedUrl == "" - def test_validate_check_type_failure_empty_string(self): - """Test CheckType validation fails with empty string in list""" + def test_validate_recommendation_url_must_be_hub(self): + """Test Recommendation URL validation fails when not pointing to Prowler Hub""" invalid_metadata = { - "Provider": "azure", + "Provider": "aws", "CheckID": "test_check", "CheckTitle": "Test Check", - "CheckType": ["Security", ""], # Invalid: empty string in list + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices" + ], "ServiceName": "test", "SubServiceName": "subtest", "ResourceIdTemplate": "template", @@ -1129,7 +1203,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1139,7 +1213,198 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://docs.aws.amazon.com/some-page", # Invalid: not HUB + }, + }, + "Categories": ["encryption"], + "DependsOn": [], + "RelatedTo": [], + "Notes": "Test notes", + } + + with pytest.raises(ValidationError) as exc_info: + CheckMetadata(**invalid_metadata) + assert "Remediation Recommendation URL must point to Prowler Hub" in str( + exc_info.value + ) + + def test_validate_recommendation_url_hub_is_valid(self): + """Test Recommendation URL validation passes with Prowler Hub URL""" + valid_metadata = { + "Provider": "aws", + "CheckID": "test_check", + "CheckTitle": "Test Check", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices" + ], + "ServiceName": "test", + "SubServiceName": "subtest", + "ResourceIdTemplate": "template", + "Severity": "high", + "ResourceType": "TestResource", + "Description": "Test description", + "Risk": "Test risk", + "RelatedUrl": "", + "Remediation": { + "Code": { + "CLI": "test command", + "NativeIaC": "test native", + "Other": "test other", + "Terraform": "test terraform", + }, + "Recommendation": { + "Text": "test recommendation", + "Url": "https://hub.prowler.com/check/test_check", + }, + }, + "Categories": ["encryption"], + "DependsOn": [], + "RelatedTo": [], + "Notes": "Test notes", + } + + check_metadata = CheckMetadata(**valid_metadata) + assert ( + check_metadata.Remediation.Recommendation.Url + == "https://hub.prowler.com/check/test_check" + ) + + def test_validate_recommendation_url_empty_is_valid(self): + """Test Recommendation URL validation passes when empty""" + valid_metadata = { + "Provider": "aws", + "CheckID": "test_check", + "CheckTitle": "Test Check", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices" + ], + "ServiceName": "test", + "SubServiceName": "subtest", + "ResourceIdTemplate": "template", + "Severity": "high", + "ResourceType": "TestResource", + "Description": "Test description", + "Risk": "Test risk", + "RelatedUrl": "", + "Remediation": { + "Code": { + "CLI": "test command", + "NativeIaC": "test native", + "Other": "test other", + "Terraform": "test terraform", + }, + "Recommendation": { + "Text": "test recommendation", + "Url": "", + }, + }, + "Categories": ["encryption"], + "DependsOn": [], + "RelatedTo": [], + "Notes": "Test notes", + } + + check_metadata = CheckMetadata(**valid_metadata) + assert check_metadata.Remediation.Recommendation.Url == "" + + def test_validate_check_type_non_aws_must_be_empty(self): + """Test CheckType must be empty for non-AWS providers""" + invalid_metadata = { + "Provider": "azure", + "CheckID": "test_check", + "CheckTitle": "Test Check", + "CheckType": ["SomeType"], # Invalid: non-AWS must be empty + "ServiceName": "test", + "SubServiceName": "subtest", + "ResourceIdTemplate": "template", + "Severity": "high", + "ResourceType": "TestResource", + "Description": "Test description", + "Risk": "Test risk", + "RelatedUrl": "", + "Remediation": { + "Code": { + "CLI": "test command", + "NativeIaC": "test native", + "Other": "test other", + "Terraform": "test terraform", + }, + "Recommendation": { + "Text": "test recommendation", + "Url": "https://hub.prowler.com/check/test_check", + }, + }, + "Categories": ["encryption"], + "DependsOn": [], + "RelatedTo": [], + "Notes": "Test notes", + } + + with pytest.raises(ValidationError) as exc_info: + CheckMetadata(**invalid_metadata) + assert "CheckType must be empty for non-AWS providers" in str(exc_info.value) + + def test_validate_check_type_success(self): + """Test CheckType validation with valid check types""" + valid_metadata = { + "Provider": "azure", # Using non-AWS provider to avoid config validation + "CheckID": "test_check", + "CheckTitle": "Test Check", + "CheckType": [], + "ServiceName": "test", + "SubServiceName": "subtest", + "ResourceIdTemplate": "template", + "Severity": "high", + "ResourceType": "TestResource", + "Description": "Test description", + "Risk": "Test risk", + "RelatedUrl": "", + "Remediation": { + "Code": { + "CLI": "test command", + "NativeIaC": "test native", + "Other": "test other", + "Terraform": "test terraform", + }, + "Recommendation": { + "Text": "test recommendation", + "Url": "https://hub.prowler.com/check/test_check", + }, + }, + "Categories": ["encryption"], + "DependsOn": [], + "RelatedTo": [], + "Notes": "Test notes", + } + + check_metadata = CheckMetadata(**valid_metadata) + assert check_metadata.CheckType == [] + + def test_validate_check_type_failure_empty_string(self): + """Test CheckType validation fails with empty string in list""" + invalid_metadata = { + "Provider": "aws", + "CheckID": "test_check", + "CheckTitle": "Test Check", + "CheckType": ["TTPs/Discovery", ""], # Invalid: empty string in list + "ServiceName": "test", + "SubServiceName": "subtest", + "ResourceIdTemplate": "template", + "Severity": "high", + "ResourceType": "TestResource", + "Description": "Test description", + "Risk": "Test risk", + "RelatedUrl": "", + "Remediation": { + "Code": { + "CLI": "test command", + "NativeIaC": "test native", + "Other": "test other", + "Terraform": "test terraform", + }, + "Recommendation": { + "Text": "test recommendation", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1158,9 +1423,7 @@ class TestCheckMetadataValidators: "Provider": "azure", "CheckID": "test_check", "CheckTitle": "Test Check", - "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices/Network Reachability" - ], + "CheckType": [], "ServiceName": "test", "SubServiceName": "subtest", "ResourceIdTemplate": "template", @@ -1168,7 +1431,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "A" * 400, # Exactly 400 characters "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1178,7 +1441,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1206,7 +1469,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "A" * 401, # Too long: 401 characters "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1216,7 +1479,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1237,9 +1500,7 @@ class TestCheckMetadataValidators: "Provider": "azure", "CheckID": "test_check", "CheckTitle": "Test Check", - "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices/Network Reachability" - ], + "CheckType": [], "ServiceName": "test", "SubServiceName": "subtest", "ResourceIdTemplate": "template", @@ -1247,7 +1508,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "A" * 400, # Exactly 400 characters - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1257,7 +1518,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1285,7 +1546,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "A" * 401, # Too long: 401 characters - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1295,7 +1556,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1325,7 +1586,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1335,7 +1596,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1363,7 +1624,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1373,7 +1634,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1386,12 +1647,12 @@ class TestCheckMetadataValidators: assert check_metadata.CheckType == ["TTPs/Initial Access"] def test_validate_check_type_non_aws_provider(self): - """Test CheckType validation doesn't apply AWS rules to non-AWS providers""" + """Test CheckType validation requires empty list for non-AWS providers""" valid_metadata = { "Provider": "azure", "CheckID": "test_check", "CheckTitle": "Test Check", - "CheckType": ["CustomType"], # Valid for non-AWS provider + "CheckType": [], # Non-AWS providers must have empty CheckType "ServiceName": "test", "SubServiceName": "subtest", "ResourceIdTemplate": "template", @@ -1399,7 +1660,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1409,7 +1670,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1419,7 +1680,7 @@ class TestCheckMetadataValidators: } check_metadata = CheckMetadata(**valid_metadata) - assert check_metadata.CheckType == ["CustomType"] + assert check_metadata.CheckType == [] def test_validate_check_type_aws_validation_called(self): """Test that AWS CheckType validation function works for AWS provider""" @@ -1436,7 +1697,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1446,7 +1707,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1459,12 +1720,15 @@ class TestCheckMetadataValidators: assert check_metadata.CheckType == ["Effects/Data Exposure"] def test_validate_check_type_multiple_types_all_valid(self): - """Test CheckType validation with multiple valid types for non-AWS provider""" + """Test CheckType validation with multiple valid types for AWS provider""" valid_metadata = { - "Provider": "azure", + "Provider": "aws", "CheckID": "test_check", "CheckTitle": "Test Check", - "CheckType": ["Security", "Network", "Compliance"], # Multiple valid types + "CheckType": [ + "TTPs/Discovery", + "Effects/Data Exposure", + ], # Multiple valid AWS types "ServiceName": "test", "SubServiceName": "subtest", "ResourceIdTemplate": "template", @@ -1472,7 +1736,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1482,7 +1746,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1492,7 +1756,7 @@ class TestCheckMetadataValidators: } check_metadata = CheckMetadata(**valid_metadata) - assert check_metadata.CheckType == ["Security", "Network", "Compliance"] + assert check_metadata.CheckType == ["TTPs/Discovery", "Effects/Data Exposure"] def test_validate_check_type_aws_multiple_types_mixed_validity(self): """Test CheckType validation with multiple types where one is invalid for AWS""" @@ -1509,7 +1773,7 @@ class TestCheckMetadataValidators: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1519,7 +1783,7 @@ class TestCheckMetadataValidators: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], @@ -1546,7 +1810,7 @@ class TestCheckMetadataValidators: ResourceType="resource1", Description="Description 1", Risk="risk1", - RelatedUrl="url1", + RelatedUrl="", Remediation={ "Code": { "CLI": "cli1", @@ -1554,7 +1818,10 @@ class TestCheckMetadataValidators: "Other": "other1", "Terraform": "terraform1", }, - "Recommendation": {"Text": "text1", "Url": "url1"}, + "Recommendation": { + "Text": "text1", + "Url": "https://hub.prowler.com/check/test_check", + }, }, Categories=["encryption"], DependsOn=["dependency1"], @@ -1584,7 +1851,7 @@ class TestCheckMetadataValidators: ResourceType="resource1", Description="Description 1", Risk="risk1", - RelatedUrl="url1", + RelatedUrl="", Remediation={ "Code": { "CLI": "cli1", @@ -1592,7 +1859,10 @@ class TestCheckMetadataValidators: "Other": "other1", "Terraform": "terraform1", }, - "Recommendation": {"Text": "text1", "Url": "url1"}, + "Recommendation": { + "Text": "text1", + "Url": "https://hub.prowler.com/check/test_check", + }, }, Categories=["encryption"], DependsOn=["dependency1"], @@ -1620,7 +1890,7 @@ class TestCheckMetadataValidators: ResourceType="resource1", Description="Description 1", Risk="risk1", - RelatedUrl="url1", + RelatedUrl="", Remediation={ "Code": { "CLI": "cli1", @@ -1628,7 +1898,10 @@ class TestCheckMetadataValidators: "Other": "other1", "Terraform": "terraform1", }, - "Recommendation": {"Text": "text1", "Url": "url1"}, + "Recommendation": { + "Text": "text1", + "Url": "https://hub.prowler.com/check/test_check", + }, }, Categories=["encryption"], DependsOn=["dependency1"], @@ -1656,7 +1929,7 @@ class TestCheckMetadataValidators: ResourceType="resource1", Description="Description 1", Risk="risk1", - RelatedUrl="url1", + RelatedUrl="", Remediation={ "Code": { "CLI": "cli1", @@ -1664,7 +1937,10 @@ class TestCheckMetadataValidators: "Other": "other1", "Terraform": "terraform1", }, - "Recommendation": {"Text": "text1", "Url": "url1"}, + "Recommendation": { + "Text": "text1", + "Url": "https://hub.prowler.com/check/test_check", + }, }, Categories=["encryption"], DependsOn=["dependency1"], @@ -1692,7 +1968,7 @@ class TestCheckMetadataValidators: ResourceType="resource1", Description="Description 1", Risk="risk1", - RelatedUrl="url1", + RelatedUrl="", Remediation={ "Code": { "CLI": "cli1", @@ -1700,7 +1976,10 @@ class TestCheckMetadataValidators: "Other": "other1", "Terraform": "terraform1", }, - "Recommendation": {"Text": "text1", "Url": "url1"}, + "Recommendation": { + "Text": "text1", + "Url": "https://hub.prowler.com/check/test_check", + }, }, Categories=["encryption"], DependsOn=["dependency1"], @@ -1728,7 +2007,7 @@ class TestCheckMetadataValidators: ResourceType="resource1", Description="Description 1", Risk="risk1", - RelatedUrl="url1", + RelatedUrl="", Remediation={ "Code": { "CLI": "cli1", @@ -1736,7 +2015,10 @@ class TestCheckMetadataValidators: "Other": "other1", "Terraform": "terraform1", }, - "Recommendation": {"Text": "text1", "Url": "url1"}, + "Recommendation": { + "Text": "text1", + "Url": "https://hub.prowler.com/check/test_check", + }, }, Categories=["encryption"], DependsOn=["dependency1"], @@ -1773,7 +2055,10 @@ class TestCheckMetadataValidators: "Other": "other1", "Terraform": "terraform1", }, - "Recommendation": {"Text": "text1", "Url": "url1"}, + "Recommendation": { + "Text": "text1", + "Url": "https://hub.prowler.com/check/test_check", + }, }, Categories=["encryption"], DependsOn=["dependency1"], @@ -1809,7 +2094,10 @@ class TestCheckMetadataValidators: "Other": "other1", "Terraform": "terraform1", }, - "Recommendation": {"Text": "text1", "Url": "url1"}, + "Recommendation": { + "Text": "text1", + "Url": "https://hub.prowler.com/check/test_check", + }, }, Categories=["encryption"], DependsOn=["dependency1"], @@ -1848,7 +2136,10 @@ class TestCheckMetadataValidators: "Other": "other1", "Terraform": "terraform1", }, - "Recommendation": {"Text": "text1", "Url": "url1"}, + "Recommendation": { + "Text": "text1", + "Url": "https://hub.prowler.com/check/test_check", + }, }, Categories=["encryption"], DependsOn=["dependency1"], @@ -1877,7 +2168,7 @@ class TestCheckMetadataValidators: ResourceType="resource1", Description="Description 1", Risk="risk1", - RelatedUrl="https://example.com", + RelatedUrl="", Remediation={ "Code": { "CLI": "cli1", @@ -1885,7 +2176,10 @@ class TestCheckMetadataValidators: "Other": "other1", "Terraform": "terraform1", }, - "Recommendation": {"Text": "text1", "Url": "url1"}, + "Recommendation": { + "Text": "text1", + "Url": "https://hub.prowler.com/check/test_check", + }, }, Categories=["encryption"], DependsOn=["dependency1"], @@ -1914,7 +2208,7 @@ class TestCheckMetadataValidators: ResourceType="resource1", Description="Description 1", Risk="risk1", - RelatedUrl="https://example.com", + RelatedUrl="", Remediation={ "Code": { "CLI": "cli1", @@ -1922,7 +2216,10 @@ class TestCheckMetadataValidators: "Other": "other1", "Terraform": "terraform1", }, - "Recommendation": {"Text": "text1", "Url": "url1"}, + "Recommendation": { + "Text": "text1", + "Url": "https://hub.prowler.com/check/test_check", + }, }, Categories=["encryption"], DependsOn=["dependency1"], @@ -1954,7 +2251,7 @@ class TestResourceGroupValidator: "ResourceType": "TestResource", "Description": "Test description", "Risk": "Test risk", - "RelatedUrl": "https://example.com", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "test command", @@ -1964,7 +2261,7 @@ class TestResourceGroupValidator: }, "Recommendation": { "Text": "test recommendation", - "Url": "https://example.com", + "Url": "https://hub.prowler.com/check/test_check", }, }, "Categories": ["encryption"], diff --git a/tests/lib/outputs/csv/csv_test.py b/tests/lib/outputs/csv/csv_test.py index 3b06ce787a..b2b5d390df 100644 --- a/tests/lib/outputs/csv/csv_test.py +++ b/tests/lib/outputs/csv/csv_test.py @@ -29,9 +29,9 @@ class TestCSV: partition="aws", description="Description of the finding", risk="High", - related_url="http://example.com", + related_url="", remediation_recommendation_text="Recommendation text", - remediation_recommendation_url="http://example.com/remediation", + remediation_recommendation_url="https://hub.prowler.com/check/test_check", remediation_code_nativeiac="native-iac-code", remediation_code_terraform="terraform-code", remediation_code_other="other-code", @@ -89,11 +89,11 @@ class TestCSV: assert output_data["REGION"] == AWS_REGION_EU_WEST_1 assert output_data["DESCRIPTION"] == "Description of the finding" assert output_data["RISK"] == "High" - assert output_data["RELATED_URL"] == "http://example.com" + assert output_data["RELATED_URL"] == "" assert output_data["REMEDIATION_RECOMMENDATION_TEXT"] == "Recommendation text" assert ( output_data["REMEDIATION_RECOMMENDATION_URL"] - == "http://example.com/remediation" + == "https://hub.prowler.com/check/test_check" ) assert output_data["REMEDIATION_CODE_NATIVEIAC"] == "native-iac-code" assert output_data["REMEDIATION_CODE_TERRAFORM"] == "terraform-code" @@ -126,7 +126,7 @@ class TestCSV: output.batch_write_data_to_file() mock_file.seek(0) - expected_csv = f"AUTH_METHOD;TIMESTAMP;ACCOUNT_UID;ACCOUNT_NAME;ACCOUNT_EMAIL;ACCOUNT_ORGANIZATION_UID;ACCOUNT_ORGANIZATION_NAME;ACCOUNT_TAGS;FINDING_UID;PROVIDER;CHECK_ID;CHECK_TITLE;CHECK_TYPE;STATUS;STATUS_EXTENDED;MUTED;SERVICE_NAME;SUBSERVICE_NAME;SEVERITY;RESOURCE_TYPE;RESOURCE_UID;RESOURCE_NAME;RESOURCE_DETAILS;RESOURCE_TAGS;PARTITION;REGION;DESCRIPTION;RISK;RELATED_URL;REMEDIATION_RECOMMENDATION_TEXT;REMEDIATION_RECOMMENDATION_URL;REMEDIATION_CODE_NATIVEIAC;REMEDIATION_CODE_TERRAFORM;REMEDIATION_CODE_CLI;REMEDIATION_CODE_OTHER;COMPLIANCE;CATEGORIES;DEPENDS_ON;RELATED_TO;NOTES;PROWLER_VERSION;ADDITIONAL_URLS;ACCOUNT_OU_UID;ACCOUNT_OU_NAME\r\nprofile: default;{datetime.now()};123456789012;123456789012;;test-organization-id;test-organization;test-tag:test-value;test-unique-finding;aws;service_test_check_id;service_test_check_id;Software and Configuration Checks/AWS Security Best Practices/Network Reachability;PASS;;False;service;;high;test-resource;;;;;aws;eu-west-1;check description;test-risk;test-url;;;;;;;test-compliance: test-compliance;encryption;test-dependency;test-related-to;test-notes;{prowler_version};https://docs.aws.amazon.com/prescriptive-guidance/latest/migration-operations-integration/best-practices.html | https://docs.aws.amazon.com/prescriptive-guidance/latest/migration-operations-integration/introduction.html;ou-abc1-12345678;Production/WebServices\r\n" + expected_csv = f"AUTH_METHOD;TIMESTAMP;ACCOUNT_UID;ACCOUNT_NAME;ACCOUNT_EMAIL;ACCOUNT_ORGANIZATION_UID;ACCOUNT_ORGANIZATION_NAME;ACCOUNT_TAGS;FINDING_UID;PROVIDER;CHECK_ID;CHECK_TITLE;CHECK_TYPE;STATUS;STATUS_EXTENDED;MUTED;SERVICE_NAME;SUBSERVICE_NAME;SEVERITY;RESOURCE_TYPE;RESOURCE_UID;RESOURCE_NAME;RESOURCE_DETAILS;RESOURCE_TAGS;PARTITION;REGION;DESCRIPTION;RISK;RELATED_URL;REMEDIATION_RECOMMENDATION_TEXT;REMEDIATION_RECOMMENDATION_URL;REMEDIATION_CODE_NATIVEIAC;REMEDIATION_CODE_TERRAFORM;REMEDIATION_CODE_CLI;REMEDIATION_CODE_OTHER;COMPLIANCE;CATEGORIES;DEPENDS_ON;RELATED_TO;NOTES;PROWLER_VERSION;ADDITIONAL_URLS;ACCOUNT_OU_UID;ACCOUNT_OU_NAME\r\nprofile: default;{datetime.now()};123456789012;123456789012;;test-organization-id;test-organization;test-tag:test-value;test-unique-finding;aws;service_test_check_id;service_test_check_id;Software and Configuration Checks/AWS Security Best Practices/Network Reachability;PASS;;False;service;;high;test-resource;;;;;aws;eu-west-1;check description;test-risk;;;;;;;;test-compliance: test-compliance;encryption;test-dependency;test-related-to;test-notes;{prowler_version};https://docs.aws.amazon.com/prescriptive-guidance/latest/migration-operations-integration/best-practices.html | https://docs.aws.amazon.com/prescriptive-guidance/latest/migration-operations-integration/introduction.html;ou-abc1-12345678;Production/WebServices\r\n" content = mock_file.read() assert content == expected_csv @@ -204,7 +204,7 @@ class TestCSV: with patch.object(temp_file, "close", return_value=None): csv.batch_write_data_to_file() - expected_csv = f"AUTH_METHOD;TIMESTAMP;ACCOUNT_UID;ACCOUNT_NAME;ACCOUNT_EMAIL;ACCOUNT_ORGANIZATION_UID;ACCOUNT_ORGANIZATION_NAME;ACCOUNT_TAGS;FINDING_UID;PROVIDER;CHECK_ID;CHECK_TITLE;CHECK_TYPE;STATUS;STATUS_EXTENDED;MUTED;SERVICE_NAME;SUBSERVICE_NAME;SEVERITY;RESOURCE_TYPE;RESOURCE_UID;RESOURCE_NAME;RESOURCE_DETAILS;RESOURCE_TAGS;PARTITION;REGION;DESCRIPTION;RISK;RELATED_URL;REMEDIATION_RECOMMENDATION_TEXT;REMEDIATION_RECOMMENDATION_URL;REMEDIATION_CODE_NATIVEIAC;REMEDIATION_CODE_TERRAFORM;REMEDIATION_CODE_CLI;REMEDIATION_CODE_OTHER;COMPLIANCE;CATEGORIES;DEPENDS_ON;RELATED_TO;NOTES;PROWLER_VERSION;ADDITIONAL_URLS;ACCOUNT_OU_UID;ACCOUNT_OU_NAME\nprofile: default;{datetime.now()};123456789012;123456789012;;test-organization-id;test-organization;test-tag:test-value;test-unique-finding;aws;service_test_check_id;service_test_check_id;Software and Configuration Checks/AWS Security Best Practices/Network Reachability;PASS;;False;service;;high;test-resource;;;;;aws;eu-west-1;check description;test-risk;test-url;;;;;;;test-compliance: test-compliance;encryption;test-dependency;test-related-to;test-notes;{prowler_version};https://docs.aws.amazon.com/prescriptive-guidance/latest/migration-operations-integration/best-practices.html | https://docs.aws.amazon.com/prescriptive-guidance/latest/migration-operations-integration/introduction.html;ou-abc1-12345678;Production/WebServices\n" + expected_csv = f"AUTH_METHOD;TIMESTAMP;ACCOUNT_UID;ACCOUNT_NAME;ACCOUNT_EMAIL;ACCOUNT_ORGANIZATION_UID;ACCOUNT_ORGANIZATION_NAME;ACCOUNT_TAGS;FINDING_UID;PROVIDER;CHECK_ID;CHECK_TITLE;CHECK_TYPE;STATUS;STATUS_EXTENDED;MUTED;SERVICE_NAME;SUBSERVICE_NAME;SEVERITY;RESOURCE_TYPE;RESOURCE_UID;RESOURCE_NAME;RESOURCE_DETAILS;RESOURCE_TAGS;PARTITION;REGION;DESCRIPTION;RISK;RELATED_URL;REMEDIATION_RECOMMENDATION_TEXT;REMEDIATION_RECOMMENDATION_URL;REMEDIATION_CODE_NATIVEIAC;REMEDIATION_CODE_TERRAFORM;REMEDIATION_CODE_CLI;REMEDIATION_CODE_OTHER;COMPLIANCE;CATEGORIES;DEPENDS_ON;RELATED_TO;NOTES;PROWLER_VERSION;ADDITIONAL_URLS;ACCOUNT_OU_UID;ACCOUNT_OU_NAME\nprofile: default;{datetime.now()};123456789012;123456789012;;test-organization-id;test-organization;test-tag:test-value;test-unique-finding;aws;service_test_check_id;service_test_check_id;Software and Configuration Checks/AWS Security Best Practices/Network Reachability;PASS;;False;service;;high;test-resource;;;;;aws;eu-west-1;check description;test-risk;;;;;;;;test-compliance: test-compliance;encryption;test-dependency;test-related-to;test-notes;{prowler_version};https://docs.aws.amazon.com/prescriptive-guidance/latest/migration-operations-integration/best-practices.html | https://docs.aws.amazon.com/prescriptive-guidance/latest/migration-operations-integration/introduction.html;ou-abc1-12345678;Production/WebServices\n" temp_file.seek(0) diff --git a/tests/lib/outputs/finding_test.py b/tests/lib/outputs/finding_test.py index 8a2aadb97b..00ce2fe1f7 100644 --- a/tests/lib/outputs/finding_test.py +++ b/tests/lib/outputs/finding_test.py @@ -910,16 +910,19 @@ class TestFinding: "provider": "test_provider", "checkid": "service_check_001", "checktitle": "Test Check", - "checktype": ["Security"], + "checktype": [], "servicename": "service", "subservicename": "SubService", "severity": "high", "resourcetype": "TestResource", "description": "A test check", "risk": "High risk", - "relatedurl": "http://example.com", + "relatedurl": "", "remediation": { - "recommendation": {"text": "Fix it", "url": "http://fix.com"}, + "recommendation": { + "text": "Fix it", + "url": "https://hub.prowler.com/check/service_check_001", + }, "code": { "nativeiac": "iac_code", "terraform": "terraform_code", @@ -953,16 +956,19 @@ class TestFinding: assert meta.Provider == "test_provider" assert meta.CheckID == "service_check_001" assert meta.CheckTitle == "Test Check" - assert meta.CheckType == ["Security"] + assert meta.CheckType == [] assert meta.ServiceName == "service" assert meta.SubServiceName == "SubService" assert meta.Severity == "high" assert meta.ResourceType == "TestResource" assert meta.Description == "A test check" assert meta.Risk == "High risk" - assert meta.RelatedUrl == "http://example.com" + assert meta.RelatedUrl == "" assert meta.Remediation.Recommendation.Text == "Fix it" - assert meta.Remediation.Recommendation.Url == "http://fix.com" + assert ( + meta.Remediation.Recommendation.Url + == "https://hub.prowler.com/check/service_check_001" + ) assert meta.Remediation.Code.NativeIaC == "iac_code" assert meta.Remediation.Code.Terraform == "terraform_code" assert meta.Remediation.Code.CLI == "cli_code" @@ -1034,11 +1040,11 @@ class TestFinding: "dependson": [], "relatedto": [], "categories": [], - "checktitle": "Ensure that Auto provisioning of 'Log Analytics agent for Azure VMs' is Set to 'On'", + "checktitle": "Auto provisioning of Log Analytics agent for Azure VMs should be On", "compliance": None, - "relatedurl": "https://docs.microsoft.com/en-us/azure/security-center/security-center-data-security", + "relatedurl": "", "description": ( - "Ensure that Auto provisioning of 'Log Analytics agent for Azure VMs' is Set to 'On'. " + "Auto provisioning of Log Analytics agent for Azure VMs should be On. " "The Microsoft Monitoring Agent scans for various security-related configurations and events such as system updates, " "OS vulnerabilities, endpoint protection, and provides alerts." ), @@ -1050,9 +1056,9 @@ class TestFinding: "terraform": "", }, "recommendation": { - "url": "https://learn.microsoft.com/en-us/azure/defender-for-cloud/monitoring-components", + "url": "https://hub.prowler.com/check/defender_auto_provisioning_log_analytics_agent_vms_on", "text": ( - "Ensure comprehensive visibility into possible security vulnerabilities, including missing updates, " + "Comprehensive visibility into possible security vulnerabilities, including missing updates, " "misconfigured operating system security settings, and active threats, allowing for timely mitigation and improved overall security posture" ), }, @@ -1099,16 +1105,16 @@ class TestFinding: assert meta.CheckID == "defender_auto_provisioning_log_analytics_agent_vms_on" assert ( meta.CheckTitle - == "Ensure that Auto provisioning of 'Log Analytics agent for Azure VMs' is Set to 'On'" + == "Auto provisioning of Log Analytics agent for Azure VMs should be On" ) assert meta.Severity == "medium" assert meta.ResourceType == "AzureDefenderPlan" assert ( meta.Remediation.Recommendation.Url - == "https://learn.microsoft.com/en-us/azure/defender-for-cloud/monitoring-components" + == "https://hub.prowler.com/check/defender_auto_provisioning_log_analytics_agent_vms_on" ) assert meta.Remediation.Recommendation.Text.startswith( - "Ensure comprehensive visibility" + "Comprehensive visibility" ) expected_segments = [ @@ -1156,7 +1162,7 @@ class TestFinding: "resourcetype": "GCPResourceType", "description": "GCP check description", "risk": "Medium risk", - "relatedurl": "http://gcp.example.com", + "relatedurl": "", "remediation": { "code": { "nativeiac": "iac_code", @@ -1164,7 +1170,10 @@ class TestFinding: "cli": "cli_code", "other": "other_code", }, - "recommendation": {"text": "Fix it", "url": "http://fix-gcp.com"}, + "recommendation": { + "text": "Fix it", + "url": "https://hub.prowler.com/check/service_gcp_check_001", + }, }, "resourceidtemplate": "template", "categories": ["encryption", "logging"], @@ -1236,7 +1245,7 @@ class TestFinding: "resourcetype": "K8sResourceType", "description": "K8s check description", "risk": "Low risk", - "relatedurl": "http://k8s.example.com", + "relatedurl": "", "remediation": { "code": { "nativeiac": "iac_code", @@ -1244,7 +1253,10 @@ class TestFinding: "cli": "cli_code", "other": "other_code", }, - "recommendation": {"text": "Fix it", "url": "http://fix-k8s.com"}, + "recommendation": { + "text": "Fix it", + "url": "https://hub.prowler.com/check/service_k8s_check_001", + }, }, "resourceidtemplate": "template", "categories": ["encryption"], @@ -1302,7 +1314,7 @@ class TestFinding: "resourcetype": "M365ResourceType", "description": "M365 check description", "risk": "High risk", - "relatedurl": "http://m365.example.com", + "relatedurl": "", "remediation": { "code": { "nativeiac": "iac_code", @@ -1310,7 +1322,10 @@ class TestFinding: "cli": "cli_code", "other": "other_code", }, - "recommendation": {"text": "Fix it", "url": "http://fix-m365.com"}, + "recommendation": { + "text": "Fix it", + "url": "https://hub.prowler.com/check/service_m365_check_001", + }, }, "resourceidtemplate": "template", "categories": ["encryption"], diff --git a/tests/lib/outputs/fixtures/fixtures.py b/tests/lib/outputs/fixtures/fixtures.py index 6d7881e6fd..3163f161c7 100644 --- a/tests/lib/outputs/fixtures/fixtures.py +++ b/tests/lib/outputs/fixtures/fixtures.py @@ -25,7 +25,7 @@ def generate_finding_output( partition: str = "aws", description: str = "check description", risk: str = "test-risk", - related_url: str = "test-url", + related_url: str = "", remediation_recommendation_text: str = "", remediation_recommendation_url: str = "", remediation_code_nativeiac: str = "", @@ -43,13 +43,19 @@ def generate_finding_output( service_name: str = "service", check_id: str = "service_test_check_id", check_title: str = "service_test_check_id", - check_type: list[str] = [ - "Software and Configuration Checks/AWS Security Best Practices/Network Reachability" - ], + check_type: list[str] = None, provider_uid: str = None, account_ou_uid: str = "ou-abc1-12345678", account_ou_name: str = "Production/WebServices", ) -> Finding: + if check_type is None: + check_type = ( + [ + "Software and Configuration Checks/AWS Security Best Practices/Network Reachability" + ] + if provider == "aws" + else [] + ) return Finding( auth_method="profile: default", timestamp=timestamp if timestamp else datetime.now(), diff --git a/tests/lib/outputs/fixtures/metadata.json b/tests/lib/outputs/fixtures/metadata.json index a376d491a9..b26438aac8 100644 --- a/tests/lib/outputs/fixtures/metadata.json +++ b/tests/lib/outputs/fixtures/metadata.json @@ -1,10 +1,10 @@ { "Categories": [ - "cat-one", - "cat-two" + "encryption", + "logging" ], "CheckID": "iam_user_accesskey_unused", - "CheckTitle": "Ensure Access Keys unused are disabled", + "CheckTitle": "Access Keys unused should be disabled", "CheckType": [ "Software and Configuration Checks" ], @@ -25,14 +25,14 @@ "othercheck1", "othercheck2" ], - "Description": "Ensure Access Keys unused are disabled", + "Description": "Access Keys unused should be disabled", "Notes": "additional information", "Provider": "aws", "RelatedTo": [ "othercheck3", "othercheck4" ], - "RelatedUrl": "https://serviceofficialsiteorpageforthissubject", + "RelatedUrl": "", "Remediation": { "Code": { "CLI": "cli command or URL to the cli command location.", @@ -42,7 +42,7 @@ }, "Recommendation": { "Text": "Run sudo yum update and cross your fingers and toes.", - "Url": "https://myfp.com/recommendations/dangerous_things_and_how_to_fix_them.html" + "Url": "https://hub.prowler.com/check/iam_user_accesskey_unused" } }, "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", diff --git a/tests/lib/outputs/ocsf/ocsf_test.py b/tests/lib/outputs/ocsf/ocsf_test.py index b101dec9a7..16ff1ce317 100644 --- a/tests/lib/outputs/ocsf/ocsf_test.py +++ b/tests/lib/outputs/ocsf/ocsf_test.py @@ -213,7 +213,7 @@ class TestOCSF: "status_detail": "status extended", "status_id": 1, "unmapped": { - "related_url": "test-url", + "related_url": "", "categories": ["encryption"], "depends_on": ["test-dependency"], "related_to": ["test-related-to"], diff --git a/tests/lib/scan/scan_test.py b/tests/lib/scan/scan_test.py index e6ff948ed7..b0fe82b7b2 100644 --- a/tests/lib/scan/scan_test.py +++ b/tests/lib/scan/scan_test.py @@ -27,15 +27,15 @@ finding = generate_finding_output( partition="aws", description="Description of the finding", risk="High", - related_url="http://example.com", + related_url="", remediation_recommendation_text="Recommendation text", - remediation_recommendation_url="http://example.com/remediation", + remediation_recommendation_url="https://hub.prowler.com/check/test_check", remediation_code_nativeiac="native-iac-code", remediation_code_terraform="terraform-code", remediation_code_other="other-code", remediation_code_cli="cli-code", compliance={"compliance_key": "compliance_value"}, - categories=["categorya", "categoryb"], + categories=["encryption", "logging"], depends_on=["dependency"], related_to=["related"], notes="Notes about the finding",