diff --git a/prowler/lib/check/compliance_models.py b/prowler/lib/check/compliance_models.py index 03411cfcc8..5372bf5ee3 100644 --- a/prowler/lib/check/compliance_models.py +++ b/prowler/lib/check/compliance_models.py @@ -91,7 +91,6 @@ class CIS_Requirement_Attribute(BaseModel): AdditionalInformation: str DefaultValue: Optional[str] References: str - DefaultValue: Optional[str] # Well Architected Requirement Attribute diff --git a/prowler/lib/outputs/compliance/cis/cis_aws.py b/prowler/lib/outputs/compliance/cis/cis_aws.py index efbc39665d..b2f2fee38a 100644 --- a/prowler/lib/outputs/compliance/cis/cis_aws.py +++ b/prowler/lib/outputs/compliance/cis/cis_aws.py @@ -2,7 +2,7 @@ from csv import DictWriter from venv import logger from prowler.lib.check.compliance_models import ComplianceBaseModel -from prowler.lib.outputs.compliance.cis.models import AWS +from prowler.lib.outputs.compliance.cis.models import CISAWS from prowler.lib.outputs.compliance.compliance_output import ComplianceOutput from prowler.lib.outputs.finding import Finding @@ -43,7 +43,7 @@ class AWSCIS(ComplianceOutput): for requirement in compliance.Requirements: if requirement.Id in finding_requirements: for attribute in requirement.Attributes: - compliance_row = AWS( + compliance_row = CISAWS( Provider=finding.provider, Description=compliance.Description, AccountId=finding.account_uid, @@ -64,6 +64,7 @@ class AWSCIS(ComplianceOutput): Status=finding.status, StatusExtended=finding.status_extended, ResourceId=finding.resource_uid, + ResourceName=finding.resource_name, CheckId=finding.check_id, Muted=finding.muted, ) diff --git a/prowler/lib/outputs/compliance/cis/cis_azure.py b/prowler/lib/outputs/compliance/cis/cis_azure.py index 46ca2a2ecf..be62330ab8 100644 --- a/prowler/lib/outputs/compliance/cis/cis_azure.py +++ b/prowler/lib/outputs/compliance/cis/cis_azure.py @@ -2,7 +2,7 @@ from csv import DictWriter from venv import logger from prowler.lib.check.compliance_models import ComplianceBaseModel -from prowler.lib.outputs.compliance.cis.models import Azure +from prowler.lib.outputs.compliance.cis.models import CISAzure from prowler.lib.outputs.compliance.compliance_output import ComplianceOutput from prowler.lib.outputs.finding import Finding @@ -43,7 +43,7 @@ class AzureCIS(ComplianceOutput): for requirement in compliance.Requirements: if requirement.Id in finding_requirements: for attribute in requirement.Attributes: - compliance_row = Azure( + compliance_row = CISAzure( Provider=finding.provider, Description=compliance.Description, Subscription=finding.account_name, diff --git a/prowler/lib/outputs/compliance/cis/cis_gcp.py b/prowler/lib/outputs/compliance/cis/cis_gcp.py index 362b1b17bc..52c7f93ac1 100644 --- a/prowler/lib/outputs/compliance/cis/cis_gcp.py +++ b/prowler/lib/outputs/compliance/cis/cis_gcp.py @@ -2,7 +2,7 @@ from csv import DictWriter from venv import logger from prowler.lib.check.compliance_models import ComplianceBaseModel -from prowler.lib.outputs.compliance.cis.models import GCP +from prowler.lib.outputs.compliance.cis.models import CISGCP from prowler.lib.outputs.compliance.compliance_output import ComplianceOutput from prowler.lib.outputs.finding import Finding @@ -43,7 +43,7 @@ class GCPCIS(ComplianceOutput): for requirement in compliance.Requirements: if requirement.Id in finding_requirements: for attribute in requirement.Attributes: - compliance_row = GCP( + compliance_row = CISGCP( Provider=finding.provider, Description=compliance.Description, ProjectId=finding.account_uid, diff --git a/prowler/lib/outputs/compliance/cis/cis_kubernetes.py b/prowler/lib/outputs/compliance/cis/cis_kubernetes.py index 98ccdf7ef0..62f231aca9 100644 --- a/prowler/lib/outputs/compliance/cis/cis_kubernetes.py +++ b/prowler/lib/outputs/compliance/cis/cis_kubernetes.py @@ -2,7 +2,7 @@ from csv import DictWriter from venv import logger from prowler.lib.check.compliance_models import ComplianceBaseModel -from prowler.lib.outputs.compliance.cis.models import Kubernetes +from prowler.lib.outputs.compliance.cis.models import CISKubernetes from prowler.lib.outputs.compliance.compliance_output import ComplianceOutput from prowler.lib.outputs.finding import Finding @@ -43,7 +43,7 @@ class KubernetesCIS(ComplianceOutput): for requirement in compliance.Requirements: if requirement.Id in finding_requirements: for attribute in requirement.Attributes: - compliance_row = Kubernetes( + compliance_row = CISKubernetes( Provider=finding.provider, Description=compliance.Description, Context=finding.account_name, @@ -65,6 +65,7 @@ class KubernetesCIS(ComplianceOutput): Status=finding.status, StatusExtended=finding.status_extended, ResourceId=finding.resource_uid, + ResourceName=finding.resource_name, CheckId=finding.check_id, Muted=finding.muted, ) diff --git a/prowler/lib/outputs/compliance/cis/models.py b/prowler/lib/outputs/compliance/cis/models.py index ffc40b75b3..a914b3e33a 100644 --- a/prowler/lib/outputs/compliance/cis/models.py +++ b/prowler/lib/outputs/compliance/cis/models.py @@ -1,13 +1,15 @@ from pydantic import BaseModel -class CIS(BaseModel): +class CISAWS(BaseModel): """ - CIS generates a finding's output in CIS Compliance format. + CISAWS generates a finding's output in AWS CIS Compliance format. """ Provider: str Description: str + AccountId: str + Region: str AssessmentDate: str Requirements_Id: str Requirements_Description: str @@ -24,41 +26,137 @@ class CIS(BaseModel): Status: str StatusExtended: str ResourceId: str + ResourceName: str CheckId: str Muted: bool -class AWS(CIS): +class CISAzure(BaseModel): """ - AWS CIS Compliance format. - """ - - AccountId: str - Region: str - - -class Azure(CIS): - """ - Azure CIS Compliance format. + CISAzure generates a finding's output in Azure CIS Compliance format. """ + Provider: str + Description: str Subscription: str Location: str + AssessmentDate: str + Requirements_Id: str + Requirements_Description: str + Requirements_Attributes_Section: str + Requirements_Attributes_Profile: str + Requirements_Attributes_AssessmentStatus: str + Requirements_Attributes_Description: str + Requirements_Attributes_RationaleStatement: str + Requirements_Attributes_ImpactStatement: str + Requirements_Attributes_RemediationProcedure: str + Requirements_Attributes_AuditProcedure: str + Requirements_Attributes_AdditionalInformation: str + Requirements_Attributes_DefaultValue: str + Requirements_Attributes_References: str + Status: str + StatusExtended: str + ResourceId: str + ResourceName: str + CheckId: str + Muted: bool -class GCP(CIS): +class CISGCP(BaseModel): """ - GCP CIS Compliance format. + CISGCP generates a finding's output in GCP CIS Compliance format. """ + Provider: str + Description: str ProjectId: str Location: str + AssessmentDate: str + Requirements_Id: str + Requirements_Description: str + Requirements_Attributes_Section: str + Requirements_Attributes_Profile: str + Requirements_Attributes_AssessmentStatus: str + Requirements_Attributes_Description: str + Requirements_Attributes_RationaleStatement: str + Requirements_Attributes_ImpactStatement: str + Requirements_Attributes_RemediationProcedure: str + Requirements_Attributes_AuditProcedure: str + Requirements_Attributes_AdditionalInformation: str + Requirements_Attributes_References: str + Status: str + StatusExtended: str + ResourceId: str + ResourceName: str + CheckId: str + Muted: bool -class Kubernetes(CIS): +class CISKubernetes(BaseModel): """ - Kubernetes CIS Compliance format. + CISKubernetes generates a finding's output in Kubernetes CIS Compliance format. """ + Provider: str + Description: str Context: str Namespace: str + AssessmentDate: str + Requirements_Id: str + Requirements_Description: str + Requirements_Attributes_Section: str + Requirements_Attributes_Profile: str + Requirements_Attributes_AssessmentStatus: str + Requirements_Attributes_Description: str + Requirements_Attributes_RationaleStatement: str + Requirements_Attributes_ImpactStatement: str + Requirements_Attributes_RemediationProcedure: str + Requirements_Attributes_AuditProcedure: str + Requirements_Attributes_AdditionalInformation: str + Requirements_Attributes_References: str + Requirements_Attributes_DefaultValue: str + Status: str + StatusExtended: str + ResourceId: str + ResourceName: str + CheckId: str + Muted: bool + + +# TODO: Create a parent class for the common fields of CIS and have the specific classes from each provider to inherit from it. +# It is not done yet because it is needed to respect the current order of the fields in the output file. + +# class AWS(CIS): +# """ +# AWS CIS Compliance format. +# """ + +# AccountId: str +# Region: str + + +# class Azure(CIS): +# """ +# Azure CIS Compliance format. +# """ + +# Subscription: str +# Location: str + + +# class GCP(CIS): +# """ +# GCP CIS Compliance format. +# """ + +# ProjectId: str +# Location: str + + +# class Kubernetes(CIS): +# """ +# Kubernetes CIS Compliance format. +# """ + +# Context: str +# Namespace: str diff --git a/tests/lib/outputs/compliance/cis_aws_test.py b/tests/lib/outputs/compliance/cis_aws_test.py index 3821d9d9d9..1f2d4653b4 100644 --- a/tests/lib/outputs/compliance/cis_aws_test.py +++ b/tests/lib/outputs/compliance/cis_aws_test.py @@ -5,7 +5,7 @@ from freezegun import freeze_time from mock import patch from prowler.lib.outputs.compliance.cis.cis_aws import AWSCIS -from prowler.lib.outputs.compliance.cis.models import AWS +from prowler.lib.outputs.compliance.cis.models import CISAWS from tests.lib.outputs.compliance.fixtures import CIS_1_4_AWS from tests.lib.outputs.fixtures.fixtures import generate_finding_output from tests.providers.aws.utils import AWS_ACCOUNT_NUMBER, AWS_REGION_EU_WEST_1 @@ -17,7 +17,7 @@ class TestAWSCIS: output = AWSCIS(findings, CIS_1_4_AWS) output_data = output.data[0] - assert isinstance(output_data, AWS) + assert isinstance(output_data, CISAWS) assert output_data.Provider == "aws" assert output_data.AccountId == AWS_ACCOUNT_NUMBER assert output_data.Region == AWS_REGION_EU_WEST_1 @@ -70,6 +70,7 @@ class TestAWSCIS: assert output_data.Status == "PASS" assert output_data.StatusExtended == "" assert output_data.ResourceId == "" + assert output_data.ResourceName == "" assert output_data.CheckId == "test-check-id" assert output_data.Muted is False @@ -86,5 +87,5 @@ class TestAWSCIS: mock_file.seek(0) content = mock_file.read() - expected_csv = f"""PROVIDER;DESCRIPTION;ASSESSMENTDATE;REQUIREMENTS_ID;REQUIREMENTS_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_SECTION;REQUIREMENTS_ATTRIBUTES_PROFILE;REQUIREMENTS_ATTRIBUTES_ASSESSMENTSTATUS;REQUIREMENTS_ATTRIBUTES_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_RATIONALESTATEMENT;REQUIREMENTS_ATTRIBUTES_IMPACTSTATEMENT;REQUIREMENTS_ATTRIBUTES_REMEDIATIONPROCEDURE;REQUIREMENTS_ATTRIBUTES_AUDITPROCEDURE;REQUIREMENTS_ATTRIBUTES_ADDITIONALINFORMATION;REQUIREMENTS_ATTRIBUTES_REFERENCES;STATUS;STATUSEXTENDED;RESOURCEID;CHECKID;MUTED;ACCOUNTID;REGION\r\naws;The CIS Benchmark for CIS Amazon Web Services Foundations Benchmark, v1.4.0, Level 1 and 2 provides prescriptive guidance for configuring security options for a subset of Amazon Web Services. It has an emphasis on foundational, testable, and architecture agnostic settings;{datetime.now()};2.1.3;Ensure MFA Delete is enabled on S3 buckets;2.1. Simple Storage Service (S3);Level 1;Automated;Once MFA Delete is enabled on your sensitive and classified S3 bucket it requires the user to have two forms of authentication.;Adding MFA delete to an S3 bucket, requires additional authentication when you change the version state of your bucket or you delete and object version adding another layer of security in the event your security credentials are compromised or unauthorized access is granted.;;"Perform the steps below to enable MFA delete on an S3 bucket.\n\nNote:\n-You cannot enable MFA Delete using the AWS Management Console. You must use the AWS CLI or API.\n-You must use your \'root\' account to enable MFA Delete on S3 buckets.\n\n**From Command line:**\n\n1. Run the s3api put-bucket-versioning command\n\n```\naws s3api put-bucket-versioning --profile my-root-profile --bucket Bucket_Name --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa “arn:aws:iam::aws_account_id:mfa/root-account-mfa-device passcode”\n```";"Perform the steps below to confirm MFA delete is configured on an S3 Bucket\n\n**From Console:**\n\n1. Login to the S3 console at `https://console.aws.amazon.com/s3/`\n\n2. Click the `Check` box next to the Bucket name you want to confirm\n\n3. In the window under `Properties`\n\n4. Confirm that Versioning is `Enabled`\n\n5. Confirm that MFA Delete is `Enabled`\n\n**From Command Line:**\n\n1. Run the `get-bucket-versioning`\n```\naws s3api get-bucket-versioning --bucket my-bucket\n```\n\nOutput example:\n```\n \n Enabled\n Enabled \n\n```\n\nIf the Console or the CLI output does not show Versioning and MFA Delete `enabled` refer to the remediation below.";;https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html#MultiFactorAuthenticationDelete:https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html:https://aws.amazon.com/blogs/security/securing-access-to-aws-using-mfa-part-3/:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html;PASS;;;test-check-id;False;123456789012;eu-west-1\r\n""" + expected_csv = f"""PROVIDER;DESCRIPTION;ACCOUNTID;REGION;ASSESSMENTDATE;REQUIREMENTS_ID;REQUIREMENTS_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_SECTION;REQUIREMENTS_ATTRIBUTES_PROFILE;REQUIREMENTS_ATTRIBUTES_ASSESSMENTSTATUS;REQUIREMENTS_ATTRIBUTES_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_RATIONALESTATEMENT;REQUIREMENTS_ATTRIBUTES_IMPACTSTATEMENT;REQUIREMENTS_ATTRIBUTES_REMEDIATIONPROCEDURE;REQUIREMENTS_ATTRIBUTES_AUDITPROCEDURE;REQUIREMENTS_ATTRIBUTES_ADDITIONALINFORMATION;REQUIREMENTS_ATTRIBUTES_REFERENCES;STATUS;STATUSEXTENDED;RESOURCEID;RESOURCENAME;CHECKID;MUTED\r\naws;The CIS Benchmark for CIS Amazon Web Services Foundations Benchmark, v1.4.0, Level 1 and 2 provides prescriptive guidance for configuring security options for a subset of Amazon Web Services. It has an emphasis on foundational, testable, and architecture agnostic settings;123456789012;eu-west-1;{datetime.now()};2.1.3;Ensure MFA Delete is enabled on S3 buckets;2.1. Simple Storage Service (S3);Level 1;Automated;Once MFA Delete is enabled on your sensitive and classified S3 bucket it requires the user to have two forms of authentication.;Adding MFA delete to an S3 bucket, requires additional authentication when you change the version state of your bucket or you delete and object version adding another layer of security in the event your security credentials are compromised or unauthorized access is granted.;;"Perform the steps below to enable MFA delete on an S3 bucket.\n\nNote:\n-You cannot enable MFA Delete using the AWS Management Console. You must use the AWS CLI or API.\n-You must use your \'root\' account to enable MFA Delete on S3 buckets.\n\n**From Command line:**\n\n1. Run the s3api put-bucket-versioning command\n\n```\naws s3api put-bucket-versioning --profile my-root-profile --bucket Bucket_Name --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa “arn:aws:iam::aws_account_id:mfa/root-account-mfa-device passcode”\n```";"Perform the steps below to confirm MFA delete is configured on an S3 Bucket\n\n**From Console:**\n\n1. Login to the S3 console at `https://console.aws.amazon.com/s3/`\n\n2. Click the `Check` box next to the Bucket name you want to confirm\n\n3. In the window under `Properties`\n\n4. Confirm that Versioning is `Enabled`\n\n5. Confirm that MFA Delete is `Enabled`\n\n**From Command Line:**\n\n1. Run the `get-bucket-versioning`\n```\naws s3api get-bucket-versioning --bucket my-bucket\n```\n\nOutput example:\n```\n \n Enabled\n Enabled \n\n```\n\nIf the Console or the CLI output does not show Versioning and MFA Delete `enabled` refer to the remediation below.";;https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html#MultiFactorAuthenticationDelete:https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html:https://aws.amazon.com/blogs/security/securing-access-to-aws-using-mfa-part-3/:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html;PASS;;;;test-check-id;False\r\n""" assert content == expected_csv diff --git a/tests/lib/outputs/compliance/cis_azure_test.py b/tests/lib/outputs/compliance/cis_azure_test.py index f08abb5d7b..d705aad9d8 100644 --- a/tests/lib/outputs/compliance/cis_azure_test.py +++ b/tests/lib/outputs/compliance/cis_azure_test.py @@ -5,7 +5,7 @@ from freezegun import freeze_time from mock import patch from prowler.lib.outputs.compliance.cis.cis_azure import AzureCIS -from prowler.lib.outputs.compliance.cis.models import Azure +from prowler.lib.outputs.compliance.cis.models import CISAzure from tests.lib.outputs.compliance.fixtures import CIS_2_0_AZURE from tests.lib.outputs.fixtures.fixtures import generate_finding_output from tests.providers.azure.azure_fixtures import ( @@ -28,7 +28,7 @@ class TestAzureCIS: output = AzureCIS(findings, CIS_2_0_AZURE) output_data = output.data[0] - assert isinstance(output_data, Azure) + assert isinstance(output_data, CISAzure) assert output_data.Provider == "azure" assert output_data.Subscription == AZURE_SUBSCRIPTION_NAME assert output_data.Location == "" @@ -78,9 +78,14 @@ class TestAzureCIS: output_data.Requirements_Attributes_References == CIS_2_0_AZURE.Requirements[0].Attributes[0].References ) + assert ( + output_data.Requirements_Attributes_DefaultValue + == CIS_2_0_AZURE.Requirements[0].Attributes[0].DefaultValue + ) assert output_data.Status == "PASS" assert output_data.StatusExtended == "" assert output_data.ResourceId == "" + assert output_data.ResourceName == "" assert output_data.CheckId == "test-check-id" assert output_data.Muted is False @@ -106,8 +111,8 @@ class TestAzureCIS: mock_file.seek(0) content = mock_file.read() expected_csv = ( - "PROVIDER;DESCRIPTION;ASSESSMENTDATE;REQUIREMENTS_ID;REQUIREMENTS_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_SECTION;REQUIREMENTS_ATTRIBUTES_PROFILE;REQUIREMENTS_ATTRIBUTES_ASSESSMENTSTATUS;REQUIREMENTS_ATTRIBUTES_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_RATIONALESTATEMENT;REQUIREMENTS_ATTRIBUTES_IMPACTSTATEMENT;REQUIREMENTS_ATTRIBUTES_REMEDIATIONPROCEDURE;REQUIREMENTS_ATTRIBUTES_AUDITPROCEDURE;REQUIREMENTS_ATTRIBUTES_ADDITIONALINFORMATION;REQUIREMENTS_ATTRIBUTES_REFERENCES;STATUS;STATUSEXTENDED;RESOURCEID;CHECKID;MUTED;SUBSCRIPTION;LOCATION\r\nazure;The CIS Azure Foundations Benchmark provides prescriptive guidance for configuring security options for a subset of Azure with an emphasis on foundational, testable, and architecture agnostic settings.;" + "PROVIDER;DESCRIPTION;SUBSCRIPTION;LOCATION;ASSESSMENTDATE;REQUIREMENTS_ID;REQUIREMENTS_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_SECTION;REQUIREMENTS_ATTRIBUTES_PROFILE;REQUIREMENTS_ATTRIBUTES_ASSESSMENTSTATUS;REQUIREMENTS_ATTRIBUTES_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_RATIONALESTATEMENT;REQUIREMENTS_ATTRIBUTES_IMPACTSTATEMENT;REQUIREMENTS_ATTRIBUTES_REMEDIATIONPROCEDURE;REQUIREMENTS_ATTRIBUTES_AUDITPROCEDURE;REQUIREMENTS_ATTRIBUTES_ADDITIONALINFORMATION;REQUIREMENTS_ATTRIBUTES_DEFAULTVALUE;REQUIREMENTS_ATTRIBUTES_REFERENCES;STATUS;STATUSEXTENDED;RESOURCEID;RESOURCENAME;CHECKID;MUTED\r\nazure;The CIS Azure Foundations Benchmark provides prescriptive guidance for configuring security options for a subset of Azure with an emphasis on foundational, testable, and architecture agnostic settings.;Subscription Name;;" + str(datetime.now()) - + ";2.1.3;Ensure That Microsoft Defender for Databases Is Set To 'On';2.1 Microsoft Defender for Cloud;Level 2;Manual;Turning on Microsoft Defender for Databases enables threat detection for the instances running your database software. This provides threat intelligence, anomaly detection, and behavior analytics in the Azure Microsoft Defender for Cloud. Instead of being enabled on services like Platform as a Service (PaaS), this implementation will run within your instances as Infrastructure as a Service (IaaS) on the Operating Systems hosting your databases.;Enabling Microsoft Defender for Azure SQL Databases allows your organization more granular control of the infrastructure running your database software. Instead of waiting on Microsoft release updates or other similar processes, you can manage them yourself. Threat detection is provided by the Microsoft Security Response Center (MSRC).;Running Defender on Infrastructure as a service (IaaS) may incur increased costs associated with running the service and the instance it is on. Similarly, you will need qualified personnel to maintain the operating system and software updates. If it is not maintained, security patches will not be applied and it may be open to vulnerabilities.;From Azure Portal 1. Go to Microsoft Defender for Cloud 2. Select Environment Settings 3. Click on the subscription name 4. Select Defender plans 5. Set Databases Status to On 6. Select Save Review the chosen pricing tier. For the Azure Databases resource review the different plan information and choose one that fits the needs of your organization. From Azure CLI Run the following commands: az security pricing create -n 'SqlServers' --tier 'Standard' az security pricing create -n 'SqlServerVirtualMachines' --tier 'Standard' az security pricing create -n 'OpenSourceRelationalDatabases' --tier 'Standard' az security pricing create -n 'CosmosDbs' --tier 'Standard' From Azure PowerShell Run the following commands: Set-AzSecurityPricing -Name 'SqlServers' -PricingTier 'Standard' Set-AzSecurityPricing -Name 'SqlServerVirtualMachines' -PricingTier 'Standard' Set-AzSecurityPricing -Name 'OpenSourceRelationalDatabases' -PricingTier 'Standard' Set-AzSecurityPricing -Name 'CosmosDbs' -PricingTier 'Standard';From Azure Portal 1. Go to Microsoft Defender for Cloud 2. Select Environment Settings 3. Click on the subscription name 4. Select Defender plans 5. Ensure Databases Status is set to On 6. Review the chosen pricing tier From Azure CLI Ensure the output of the below commands is Standard az security pricing show -n 'SqlServers' az security pricing show -n 'SqlServerVirtualMachines' az security pricing show -n 'OpenSourceRelationalDatabases' az security pricing show -n 'CosmosDbs' If the output of any of the above commands shows pricingTier with a value of Free, the setting is out of compliance. From PowerShell Connect-AzAccount Get-AzSecurityPricing |select-object Name,PricingTier |where-object {$_.Name -match 'Sql' -or $_.Name -match 'Cosmos' -or $_.Name -match 'OpenSource'} Ensure the output shows Standard for each database type under the PricingTier column. Any that show Free are considered out of compliance.;;https://docs.microsoft.com/en-us/azure/azure-sql/database/azure-defender-for-sql?view=azuresql:https://docs.microsoft.com/en-us/azure/defender-for-cloud/quickstart-enable-database-protections:https://docs.microsoft.com/en-us/azure/defender-for-cloud/defender-for-databases-usage:https://docs.microsoft.com/en-us/azure/security-center/security-center-detection-capabilities:https://docs.microsoft.com/en-us/rest/api/securitycenter/pricings/list:https://docs.microsoft.com/en-us/security/benchmark/azure/security-controls-v3-logging-threat-detection#lt-1-enable-threat-detection-capabilities;PASS;;;test-check-id;False;Subscription Name;\r\n" + + ";2.1.3;Ensure That Microsoft Defender for Databases Is Set To 'On';2.1 Microsoft Defender for Cloud;Level 2;Manual;Turning on Microsoft Defender for Databases enables threat detection for the instances running your database software. This provides threat intelligence, anomaly detection, and behavior analytics in the Azure Microsoft Defender for Cloud. Instead of being enabled on services like Platform as a Service (PaaS), this implementation will run within your instances as Infrastructure as a Service (IaaS) on the Operating Systems hosting your databases.;Enabling Microsoft Defender for Azure SQL Databases allows your organization more granular control of the infrastructure running your database software. Instead of waiting on Microsoft release updates or other similar processes, you can manage them yourself. Threat detection is provided by the Microsoft Security Response Center (MSRC).;Running Defender on Infrastructure as a service (IaaS) may incur increased costs associated with running the service and the instance it is on. Similarly, you will need qualified personnel to maintain the operating system and software updates. If it is not maintained, security patches will not be applied and it may be open to vulnerabilities.;From Azure Portal 1. Go to Microsoft Defender for Cloud 2. Select Environment Settings 3. Click on the subscription name 4. Select Defender plans 5. Set Databases Status to On 6. Select Save Review the chosen pricing tier. For the Azure Databases resource review the different plan information and choose one that fits the needs of your organization. From Azure CLI Run the following commands: az security pricing create -n 'SqlServers' --tier 'Standard' az security pricing create -n 'SqlServerVirtualMachines' --tier 'Standard' az security pricing create -n 'OpenSourceRelationalDatabases' --tier 'Standard' az security pricing create -n 'CosmosDbs' --tier 'Standard' From Azure PowerShell Run the following commands: Set-AzSecurityPricing -Name 'SqlServers' -PricingTier 'Standard' Set-AzSecurityPricing -Name 'SqlServerVirtualMachines' -PricingTier 'Standard' Set-AzSecurityPricing -Name 'OpenSourceRelationalDatabases' -PricingTier 'Standard' Set-AzSecurityPricing -Name 'CosmosDbs' -PricingTier 'Standard';From Azure Portal 1. Go to Microsoft Defender for Cloud 2. Select Environment Settings 3. Click on the subscription name 4. Select Defender plans 5. Ensure Databases Status is set to On 6. Review the chosen pricing tier From Azure CLI Ensure the output of the below commands is Standard az security pricing show -n 'SqlServers' az security pricing show -n 'SqlServerVirtualMachines' az security pricing show -n 'OpenSourceRelationalDatabases' az security pricing show -n 'CosmosDbs' If the output of any of the above commands shows pricingTier with a value of Free, the setting is out of compliance. From PowerShell Connect-AzAccount Get-AzSecurityPricing |select-object Name,PricingTier |where-object {$_.Name -match 'Sql' -or $_.Name -match 'Cosmos' -or $_.Name -match 'OpenSource'} Ensure the output shows Standard for each database type under the PricingTier column. Any that show Free are considered out of compliance.;;By default, Microsoft Defender plan is off.;https://docs.microsoft.com/en-us/azure/azure-sql/database/azure-defender-for-sql?view=azuresql:https://docs.microsoft.com/en-us/azure/defender-for-cloud/quickstart-enable-database-protections:https://docs.microsoft.com/en-us/azure/defender-for-cloud/defender-for-databases-usage:https://docs.microsoft.com/en-us/azure/security-center/security-center-detection-capabilities:https://docs.microsoft.com/en-us/rest/api/securitycenter/pricings/list:https://docs.microsoft.com/en-us/security/benchmark/azure/security-controls-v3-logging-threat-detection#lt-1-enable-threat-detection-capabilities;PASS;;;;test-check-id;False\r\n" ) assert content == expected_csv diff --git a/tests/lib/outputs/compliance/cis_gcp_test.py b/tests/lib/outputs/compliance/cis_gcp_test.py index 2fe88623d0..338a2d2fe7 100644 --- a/tests/lib/outputs/compliance/cis_gcp_test.py +++ b/tests/lib/outputs/compliance/cis_gcp_test.py @@ -5,7 +5,7 @@ from freezegun import freeze_time from mock import patch from prowler.lib.outputs.compliance.cis.cis_gcp import GCPCIS -from prowler.lib.outputs.compliance.cis.models import GCP +from prowler.lib.outputs.compliance.cis.models import CISGCP from tests.lib.outputs.compliance.fixtures import CIS_2_0_GCP from tests.lib.outputs.fixtures.fixtures import generate_finding_output from tests.providers.gcp.gcp_fixtures import GCP_PROJECT_ID @@ -25,7 +25,7 @@ class TestGCPCIS: output = GCPCIS(findings, CIS_2_0_GCP) output_data = output.data[0] - assert isinstance(output_data, GCP) + assert isinstance(output_data, CISGCP) assert output_data.Provider == "gcp" assert output_data.ProjectId == GCP_PROJECT_ID assert output_data.Location == "" @@ -78,6 +78,7 @@ class TestGCPCIS: assert output_data.Status == "PASS" assert output_data.StatusExtended == "" assert output_data.ResourceId == "" + assert output_data.ResourceName == "" assert output_data.CheckId == "test-check-id" assert output_data.Muted is False @@ -102,5 +103,5 @@ class TestGCPCIS: mock_file.seek(0) content = mock_file.read() - expected_csv = f"PROVIDER;DESCRIPTION;ASSESSMENTDATE;REQUIREMENTS_ID;REQUIREMENTS_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_SECTION;REQUIREMENTS_ATTRIBUTES_PROFILE;REQUIREMENTS_ATTRIBUTES_ASSESSMENTSTATUS;REQUIREMENTS_ATTRIBUTES_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_RATIONALESTATEMENT;REQUIREMENTS_ATTRIBUTES_IMPACTSTATEMENT;REQUIREMENTS_ATTRIBUTES_REMEDIATIONPROCEDURE;REQUIREMENTS_ATTRIBUTES_AUDITPROCEDURE;REQUIREMENTS_ATTRIBUTES_ADDITIONALINFORMATION;REQUIREMENTS_ATTRIBUTES_REFERENCES;STATUS;STATUSEXTENDED;RESOURCEID;CHECKID;MUTED;PROJECTID;LOCATION\r\ngcp;This CIS Benchmark is the product of a community consensus process and consists of secure configuration guidelines developed for Google Cloud Computing Platform;{datetime.now()};2.13;Ensure That Microsoft Defender for Databases Is Set To 'On';2. Logging and Monitoring;Level 1;Automated;GCP Cloud Asset Inventory is services that provides a historical view of GCP resources and IAM policies through a time-series database. The information recorded includes metadata on Google Cloud resources, metadata on policies set on Google Cloud projects or resources, and runtime information gathered within a Google Cloud resource.;The GCP resources and IAM policies captured by GCP Cloud Asset Inventory enables security analysis, resource change tracking, and compliance auditing. It is recommended GCP Cloud Asset Inventory be enabled for all GCP projects.;;**From Google Cloud Console** Enable the Cloud Asset API: 1. Go to `API & Services/Library` by visiting https://console.cloud.google.com/apis/library(https://console.cloud.google.com/apis/library) 2. Search for `Cloud Asset API` and select the result for _Cloud Asset API_ 3. Click the `ENABLE` button. **From Google Cloud CLI** Enable the Cloud Asset API: 1. Enable the Cloud Asset API through the services interface: ``` gcloud services enable cloudasset.googleapis.com ```;**From Google Cloud Console** Ensure that the Cloud Asset API is enabled: 1. Go to `API & Services/Library` by visiting https://console.cloud.google.com/apis/library(https://console.cloud.google.com/apis/library) 2. Search for `Cloud Asset API` and select the result for _Cloud Asset API_ 3. Ensure that `API Enabled` is displayed. **From Google Cloud CLI** Ensure that the Cloud Asset API is enabled: 1. Query enabled services: ``` gcloud services list --enabled --filter=name:cloudasset.googleapis.com ``` If the API is listed, then it is enabled. If the response is `Listed 0 items` the API is not enabled.;Additional info - Cloud Asset Inventory only keeps a five-week history of Google Cloud asset metadata. If a longer history is desired, automation to export the history to Cloud Storage or BigQuery should be evaluated.;https://cloud.google.com/asset-inventory/docs;PASS;;;test-check-id;False;123456789012;\r\n" + expected_csv = f"PROVIDER;DESCRIPTION;PROJECTID;LOCATION;ASSESSMENTDATE;REQUIREMENTS_ID;REQUIREMENTS_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_SECTION;REQUIREMENTS_ATTRIBUTES_PROFILE;REQUIREMENTS_ATTRIBUTES_ASSESSMENTSTATUS;REQUIREMENTS_ATTRIBUTES_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_RATIONALESTATEMENT;REQUIREMENTS_ATTRIBUTES_IMPACTSTATEMENT;REQUIREMENTS_ATTRIBUTES_REMEDIATIONPROCEDURE;REQUIREMENTS_ATTRIBUTES_AUDITPROCEDURE;REQUIREMENTS_ATTRIBUTES_ADDITIONALINFORMATION;REQUIREMENTS_ATTRIBUTES_REFERENCES;STATUS;STATUSEXTENDED;RESOURCEID;RESOURCENAME;CHECKID;MUTED\r\ngcp;This CIS Benchmark is the product of a community consensus process and consists of secure configuration guidelines developed for Google Cloud Computing Platform;123456789012;;{datetime.now()};2.13;Ensure That Microsoft Defender for Databases Is Set To 'On';2. Logging and Monitoring;Level 1;Automated;GCP Cloud Asset Inventory is services that provides a historical view of GCP resources and IAM policies through a time-series database. The information recorded includes metadata on Google Cloud resources, metadata on policies set on Google Cloud projects or resources, and runtime information gathered within a Google Cloud resource.;The GCP resources and IAM policies captured by GCP Cloud Asset Inventory enables security analysis, resource change tracking, and compliance auditing. It is recommended GCP Cloud Asset Inventory be enabled for all GCP projects.;;**From Google Cloud Console** Enable the Cloud Asset API: 1. Go to `API & Services/Library` by visiting https://console.cloud.google.com/apis/library(https://console.cloud.google.com/apis/library) 2. Search for `Cloud Asset API` and select the result for _Cloud Asset API_ 3. Click the `ENABLE` button. **From Google Cloud CLI** Enable the Cloud Asset API: 1. Enable the Cloud Asset API through the services interface: ``` gcloud services enable cloudasset.googleapis.com ```;**From Google Cloud Console** Ensure that the Cloud Asset API is enabled: 1. Go to `API & Services/Library` by visiting https://console.cloud.google.com/apis/library(https://console.cloud.google.com/apis/library) 2. Search for `Cloud Asset API` and select the result for _Cloud Asset API_ 3. Ensure that `API Enabled` is displayed. **From Google Cloud CLI** Ensure that the Cloud Asset API is enabled: 1. Query enabled services: ``` gcloud services list --enabled --filter=name:cloudasset.googleapis.com ``` If the API is listed, then it is enabled. If the response is `Listed 0 items` the API is not enabled.;Additional info - Cloud Asset Inventory only keeps a five-week history of Google Cloud asset metadata. If a longer history is desired, automation to export the history to Cloud Storage or BigQuery should be evaluated.;https://cloud.google.com/asset-inventory/docs;PASS;;;;test-check-id;False\r\n" assert content == expected_csv diff --git a/tests/lib/outputs/compliance/cis_kubernetes_test.py b/tests/lib/outputs/compliance/cis_kubernetes_test.py index 48c82ed4cf..bcdfd0d01c 100644 --- a/tests/lib/outputs/compliance/cis_kubernetes_test.py +++ b/tests/lib/outputs/compliance/cis_kubernetes_test.py @@ -5,7 +5,7 @@ from freezegun import freeze_time from mock import patch from prowler.lib.outputs.compliance.cis.cis_kubernetes import KubernetesCIS -from prowler.lib.outputs.compliance.cis.models import Kubernetes +from prowler.lib.outputs.compliance.cis.models import CISKubernetes from tests.lib.outputs.compliance.fixtures import CIS_1_8_KUBERNETES from tests.lib.outputs.fixtures.fixtures import generate_finding_output from tests.providers.kubernetes.kubernetes_fixtures import ( @@ -28,7 +28,7 @@ class TestKubernetesCIS: output = KubernetesCIS(findings, CIS_1_8_KUBERNETES) output_data = output.data[0] - assert isinstance(output_data, Kubernetes) + assert isinstance(output_data, CISKubernetes) assert output_data.Provider == "kubernetes" assert output_data.Context == KUBERNETES_CLUSTER_NAME assert output_data.Namespace == KUBERNETES_NAMESPACE @@ -78,9 +78,14 @@ class TestKubernetesCIS: output_data.Requirements_Attributes_References == CIS_1_8_KUBERNETES.Requirements[0].Attributes[0].References ) + assert ( + output_data.Requirements_Attributes_DefaultValue + == CIS_1_8_KUBERNETES.Requirements[0].Attributes[0].DefaultValue + ) assert output_data.Status == "PASS" assert output_data.StatusExtended == "" assert output_data.ResourceId == "" + assert output_data.ResourceName == "" assert output_data.CheckId == "test-check-id" assert output_data.Muted is False @@ -105,5 +110,5 @@ class TestKubernetesCIS: mock_file.seek(0) content = mock_file.read() - expected_csv = f"PROVIDER;DESCRIPTION;ASSESSMENTDATE;REQUIREMENTS_ID;REQUIREMENTS_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_SECTION;REQUIREMENTS_ATTRIBUTES_PROFILE;REQUIREMENTS_ATTRIBUTES_ASSESSMENTSTATUS;REQUIREMENTS_ATTRIBUTES_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_RATIONALESTATEMENT;REQUIREMENTS_ATTRIBUTES_IMPACTSTATEMENT;REQUIREMENTS_ATTRIBUTES_REMEDIATIONPROCEDURE;REQUIREMENTS_ATTRIBUTES_AUDITPROCEDURE;REQUIREMENTS_ATTRIBUTES_ADDITIONALINFORMATION;REQUIREMENTS_ATTRIBUTES_REFERENCES;STATUS;STATUSEXTENDED;RESOURCEID;CHECKID;MUTED;CONTEXT;NAMESPACE\r\nkubernetes;This CIS Kubernetes Benchmark provides prescriptive guidance for establishing a secure configuration posture for Kubernetes v1.27.;{datetime.now()};1.1.3;Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive;1.1 Control Plane Node Configuration Files;Level 1 - Master Node;Automated;Ensure that the controller manager pod specification file has permissions of `600` or more restrictive.;The controller manager pod specification file controls various parameters that set the behavior of the Controller Manager on the master node. You should restrict its file permissions to maintain the integrity of the file. The file should be writable by only the administrators on the system.;;Run the below command (based on the file location on your system) on the Control Plane node. For example, ``` chmod 600 /etc/kubernetes/manifests/kube-controller-manager.yaml ```;Run the below command (based on the file location on your system) on the Control Plane node. For example, ``` stat -c %a /etc/kubernetes/manifests/kube-controller-manager.yaml ``` Verify that the permissions are `600` or more restrictive.;;https://kubernetes.io/docs/admin/kube-apiserver/;PASS;;;test-check-id;False;test-cluster;test-namespace\r\n" + expected_csv = f"PROVIDER;DESCRIPTION;CONTEXT;NAMESPACE;ASSESSMENTDATE;REQUIREMENTS_ID;REQUIREMENTS_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_SECTION;REQUIREMENTS_ATTRIBUTES_PROFILE;REQUIREMENTS_ATTRIBUTES_ASSESSMENTSTATUS;REQUIREMENTS_ATTRIBUTES_DESCRIPTION;REQUIREMENTS_ATTRIBUTES_RATIONALESTATEMENT;REQUIREMENTS_ATTRIBUTES_IMPACTSTATEMENT;REQUIREMENTS_ATTRIBUTES_REMEDIATIONPROCEDURE;REQUIREMENTS_ATTRIBUTES_AUDITPROCEDURE;REQUIREMENTS_ATTRIBUTES_ADDITIONALINFORMATION;REQUIREMENTS_ATTRIBUTES_REFERENCES;REQUIREMENTS_ATTRIBUTES_DEFAULTVALUE;STATUS;STATUSEXTENDED;RESOURCEID;RESOURCENAME;CHECKID;MUTED\r\nkubernetes;This CIS Kubernetes Benchmark provides prescriptive guidance for establishing a secure configuration posture for Kubernetes v1.27.;test-cluster;test-namespace;{datetime.now()};1.1.3;Ensure that the controller manager pod specification file permissions are set to 600 or more restrictive;1.1 Control Plane Node Configuration Files;Level 1 - Master Node;Automated;Ensure that the controller manager pod specification file has permissions of `600` or more restrictive.;The controller manager pod specification file controls various parameters that set the behavior of the Controller Manager on the master node. You should restrict its file permissions to maintain the integrity of the file. The file should be writable by only the administrators on the system.;;Run the below command (based on the file location on your system) on the Control Plane node. For example, ``` chmod 600 /etc/kubernetes/manifests/kube-controller-manager.yaml ```;Run the below command (based on the file location on your system) on the Control Plane node. For example, ``` stat -c %a /etc/kubernetes/manifests/kube-controller-manager.yaml ``` Verify that the permissions are `600` or more restrictive.;;https://kubernetes.io/docs/admin/kube-apiserver/;By default, the `kube-controller-manager.yaml` file has permissions of `640`.;PASS;;;;test-check-id;False\r\n" assert content == expected_csv