mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 04:51:51 +00:00
feat: add checktitle, relatedurl and checktype validators
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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"],
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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=[],
|
||||
|
||||
@@ -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",
|
||||
|
||||
+430
-133
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
|
||||
|
||||
@@ -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"],
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"],
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user