feat: add checktitle, relatedurl and checktype validators

This commit is contained in:
Daniel Barranquero
2026-03-13 14:59:18 +01:00
parent c5ad19f997
commit fd369ea6c0
14 changed files with 572 additions and 217 deletions
+35 -6
View File
@@ -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):
+6 -6
View File
@@ -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"],
+3 -3
View File
@@ -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
+10 -4
View File
@@ -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"],
@@ -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="",
@@ -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=[],
+6 -6
View File
@@ -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",
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -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)
+35 -20
View File
@@ -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"],
+10 -4
View File
@@ -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(),
+6 -6
View File
@@ -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",
+1 -1
View File
@@ -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"],
+3 -3
View File
@@ -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",