From e585ae45bdc801b0b2aa7eb35216a18315ed24a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Mart=C3=ADn?= Date: Wed, 6 May 2026 13:11:29 +0200 Subject: [PATCH] feat(aws): rename Essential Eight to ASD Essential Eight (#11054) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: César Arroba --- prowler/__main__.py | 14 ++++---- ..._aws.json => asd_essential_eight_aws.json} | 2 +- prowler/lib/check/compliance_models.py | 16 ++++----- .../__init__.py | 0 .../asd_essential_eight.py} | 20 +++++------ .../asd_essential_eight_aws.py} | 12 +++---- .../models.py | 4 +-- prowler/lib/outputs/compliance/compliance.py | 10 +++--- .../__init__.py | 0 .../asd_essential_eight_aws_test.py} | 34 +++++++++---------- tests/lib/outputs/compliance/fixtures.py | 10 +++--- 11 files changed, 61 insertions(+), 61 deletions(-) rename prowler/compliance/aws/{essential_eight_aws.json => asd_essential_eight_aws.json} (99%) rename prowler/lib/outputs/compliance/{essential_eight => asd_essential_eight}/__init__.py (100%) rename prowler/lib/outputs/compliance/{essential_eight/essential_eight.py => asd_essential_eight/asd_essential_eight.py} (85%) rename prowler/lib/outputs/compliance/{essential_eight/essential_eight_aws.py => asd_essential_eight/asd_essential_eight_aws.py} (95%) rename prowler/lib/outputs/compliance/{essential_eight => asd_essential_eight}/models.py (86%) rename tests/lib/outputs/compliance/{essential_eight => asd_essential_eight}/__init__.py (100%) rename tests/lib/outputs/compliance/{essential_eight/essential_eight_aws_test.py => asd_essential_eight/asd_essential_eight_aws_test.py} (80%) diff --git a/prowler/__main__.py b/prowler/__main__.py index e10c9c745b..ebca7985c5 100644 --- a/prowler/__main__.py +++ b/prowler/__main__.py @@ -57,6 +57,9 @@ from prowler.lib.check.models import CheckMetadata from prowler.lib.cli.parser import ProwlerArgumentParser from prowler.lib.logger import logger, set_logging_config from prowler.lib.outputs.asff.asff import ASFF +from prowler.lib.outputs.compliance.asd_essential_eight.asd_essential_eight_aws import ( + ASDEssentialEightAWS, +) from prowler.lib.outputs.compliance.aws_well_architected.aws_well_architected import ( AWSWellArchitected, ) @@ -90,9 +93,6 @@ from prowler.lib.outputs.compliance.csa.csa_oraclecloud import OracleCloudCSA from prowler.lib.outputs.compliance.ens.ens_aws import AWSENS from prowler.lib.outputs.compliance.ens.ens_azure import AzureENS from prowler.lib.outputs.compliance.ens.ens_gcp import GCPENS -from prowler.lib.outputs.compliance.essential_eight.essential_eight_aws import ( - EssentialEightAWS, -) from prowler.lib.outputs.compliance.generic.generic import GenericCompliance from prowler.lib.outputs.compliance.iso27001.iso27001_aws import AWSISO27001 from prowler.lib.outputs.compliance.iso27001.iso27001_azure import AzureISO27001 @@ -676,18 +676,18 @@ def prowler(): ) generated_outputs["compliance"].append(cis) cis.batch_write_data_to_file() - elif compliance_name.startswith("essential_eight"): + elif compliance_name.startswith("asd_essential_eight"): filename = ( f"{output_options.output_directory}/compliance/" f"{output_options.output_filename}_{compliance_name}.csv" ) - essential_eight = EssentialEightAWS( + asd_essential_eight = ASDEssentialEightAWS( findings=finding_outputs, compliance=bulk_compliance_frameworks[compliance_name], file_path=filename, ) - generated_outputs["compliance"].append(essential_eight) - essential_eight.batch_write_data_to_file() + generated_outputs["compliance"].append(asd_essential_eight) + asd_essential_eight.batch_write_data_to_file() elif compliance_name == "mitre_attack_aws": # Generate MITRE ATT&CK Finding Object filename = ( diff --git a/prowler/compliance/aws/essential_eight_aws.json b/prowler/compliance/aws/asd_essential_eight_aws.json similarity index 99% rename from prowler/compliance/aws/essential_eight_aws.json rename to prowler/compliance/aws/asd_essential_eight_aws.json index 46164ebba5..00b39817e3 100644 --- a/prowler/compliance/aws/essential_eight_aws.json +++ b/prowler/compliance/aws/asd_essential_eight_aws.json @@ -1,5 +1,5 @@ { - "Framework": "Essential-Eight", + "Framework": "ASD-Essential-Eight", "Name": "ASD Essential Eight Maturity Model - Maturity Level One (AWS)", "Version": "Nov 2023", "Provider": "AWS", diff --git a/prowler/lib/check/compliance_models.py b/prowler/lib/check/compliance_models.py index 226af6ec36..82ac54e4d9 100644 --- a/prowler/lib/check/compliance_models.py +++ b/prowler/lib/check/compliance_models.py @@ -102,7 +102,7 @@ class CIS_Requirement_Attribute(BaseModel): References: str -class EssentialEight_Requirement_Attribute_MaturityLevel(str, Enum): +class ASDEssentialEight_Requirement_Attribute_MaturityLevel(str, Enum): """ASD Essential Eight Maturity Level""" ML1 = "ML1" @@ -110,14 +110,14 @@ class EssentialEight_Requirement_Attribute_MaturityLevel(str, Enum): ML3 = "ML3" -class EssentialEight_Requirement_Attribute_AssessmentStatus(str, Enum): +class ASDEssentialEight_Requirement_Attribute_AssessmentStatus(str, Enum): """Essential Eight Requirement Attribute Assessment Status""" Manual = "Manual" Automated = "Automated" -class EssentialEight_Requirement_Attribute_CloudApplicability(str, Enum): +class ASDEssentialEight_Requirement_Attribute_CloudApplicability(str, Enum): """How well the ASD control maps to AWS cloud infrastructure.""" Full = "full" @@ -127,13 +127,13 @@ class EssentialEight_Requirement_Attribute_CloudApplicability(str, Enum): # Essential Eight Requirement Attribute -class EssentialEight_Requirement_Attribute(BaseModel): +class ASDEssentialEight_Requirement_Attribute(BaseModel): """ASD Essential Eight Requirement Attribute""" Section: str - MaturityLevel: EssentialEight_Requirement_Attribute_MaturityLevel - AssessmentStatus: EssentialEight_Requirement_Attribute_AssessmentStatus - CloudApplicability: EssentialEight_Requirement_Attribute_CloudApplicability + MaturityLevel: ASDEssentialEight_Requirement_Attribute_MaturityLevel + AssessmentStatus: ASDEssentialEight_Requirement_Attribute_AssessmentStatus + CloudApplicability: ASDEssentialEight_Requirement_Attribute_CloudApplicability MitigatedThreats: list[str] Description: str RationaleStatement: str @@ -292,7 +292,7 @@ class Compliance_Requirement(BaseModel): Name: Optional[str] = None Attributes: list[ Union[ - EssentialEight_Requirement_Attribute, + ASDEssentialEight_Requirement_Attribute, CIS_Requirement_Attribute, ENS_Requirement_Attribute, ISO27001_2013_Requirement_Attribute, diff --git a/prowler/lib/outputs/compliance/essential_eight/__init__.py b/prowler/lib/outputs/compliance/asd_essential_eight/__init__.py similarity index 100% rename from prowler/lib/outputs/compliance/essential_eight/__init__.py rename to prowler/lib/outputs/compliance/asd_essential_eight/__init__.py diff --git a/prowler/lib/outputs/compliance/essential_eight/essential_eight.py b/prowler/lib/outputs/compliance/asd_essential_eight/asd_essential_eight.py similarity index 85% rename from prowler/lib/outputs/compliance/essential_eight/essential_eight.py rename to prowler/lib/outputs/compliance/asd_essential_eight/asd_essential_eight.py index 9438a613f8..75481fb6aa 100644 --- a/prowler/lib/outputs/compliance/essential_eight/essential_eight.py +++ b/prowler/lib/outputs/compliance/asd_essential_eight/asd_essential_eight.py @@ -4,7 +4,7 @@ from tabulate import tabulate from prowler.config.config import orange_color -def get_essential_eight_table( +def get_asd_essential_eight_table( findings: list, bulk_checks_metadata: dict, compliance_framework: str, @@ -13,7 +13,7 @@ def get_essential_eight_table( compliance_overview: bool, ): sections = {} - essential_eight_compliance_table = { + asd_essential_eight_compliance_table = { "Provider": [], "Section": [], "Status": [], @@ -26,7 +26,7 @@ def get_essential_eight_table( check = bulk_checks_metadata[finding.check_metadata.CheckID] check_compliances = check.Compliance for compliance in check_compliances: - if compliance.Framework == "Essential-Eight": + if compliance.Framework == "ASD-Essential-Eight": for requirement in compliance.Requirements: for attribute in requirement.Attributes: section = attribute.Section @@ -50,19 +50,19 @@ def get_essential_eight_table( sections = dict(sorted(sections.items())) for section in sections: - essential_eight_compliance_table["Provider"].append(compliance.Provider) - essential_eight_compliance_table["Section"].append(section) + asd_essential_eight_compliance_table["Provider"].append(compliance.Provider) + asd_essential_eight_compliance_table["Section"].append(section) if sections[section]["FAIL"] > 0: - essential_eight_compliance_table["Status"].append( + asd_essential_eight_compliance_table["Status"].append( f"{Fore.RED}FAIL({sections[section]['FAIL']}){Style.RESET_ALL}" ) elif sections[section]["PASS"] > 0: - essential_eight_compliance_table["Status"].append( + asd_essential_eight_compliance_table["Status"].append( f"{Fore.GREEN}PASS({sections[section]['PASS']}){Style.RESET_ALL}" ) else: - essential_eight_compliance_table["Status"].append("-") - essential_eight_compliance_table["Muted"].append( + asd_essential_eight_compliance_table["Status"].append("-") + asd_essential_eight_compliance_table["Muted"].append( f"{orange_color}{sections[section]['Muted']}{Style.RESET_ALL}" ) if len(fail_count) + len(pass_count) + len(muted_count) > 1: @@ -84,7 +84,7 @@ def get_essential_eight_table( ) print( tabulate( - essential_eight_compliance_table, + asd_essential_eight_compliance_table, headers="keys", tablefmt="rounded_grid", ) diff --git a/prowler/lib/outputs/compliance/essential_eight/essential_eight_aws.py b/prowler/lib/outputs/compliance/asd_essential_eight/asd_essential_eight_aws.py similarity index 95% rename from prowler/lib/outputs/compliance/essential_eight/essential_eight_aws.py rename to prowler/lib/outputs/compliance/asd_essential_eight/asd_essential_eight_aws.py index 198e3ab331..78ef53c5e6 100644 --- a/prowler/lib/outputs/compliance/essential_eight/essential_eight_aws.py +++ b/prowler/lib/outputs/compliance/asd_essential_eight/asd_essential_eight_aws.py @@ -1,13 +1,13 @@ from prowler.config.config import timestamp from prowler.lib.check.compliance_models import Compliance -from prowler.lib.outputs.compliance.compliance_output import ComplianceOutput -from prowler.lib.outputs.compliance.essential_eight.models import ( - EssentialEightAWSModel, +from prowler.lib.outputs.compliance.asd_essential_eight.models import ( + ASDEssentialEightAWSModel, ) +from prowler.lib.outputs.compliance.compliance_output import ComplianceOutput from prowler.lib.outputs.finding import Finding -class EssentialEightAWS(ComplianceOutput): +class ASDEssentialEightAWS(ComplianceOutput): """ This class represents the AWS ASD Essential Eight compliance output. @@ -41,7 +41,7 @@ class EssentialEightAWS(ComplianceOutput): for requirement in compliance.Requirements: if requirement.Id in finding_requirements: for attribute in requirement.Attributes: - compliance_row = EssentialEightAWSModel( + compliance_row = ASDEssentialEightAWSModel( Provider=finding.provider, Description=compliance.Description, AccountId=finding.account_uid, @@ -77,7 +77,7 @@ class EssentialEightAWS(ComplianceOutput): for requirement in compliance.Requirements: if not requirement.Checks: for attribute in requirement.Attributes: - compliance_row = EssentialEightAWSModel( + compliance_row = ASDEssentialEightAWSModel( Provider=compliance.Provider.lower(), Description=compliance.Description, AccountId="", diff --git a/prowler/lib/outputs/compliance/essential_eight/models.py b/prowler/lib/outputs/compliance/asd_essential_eight/models.py similarity index 86% rename from prowler/lib/outputs/compliance/essential_eight/models.py rename to prowler/lib/outputs/compliance/asd_essential_eight/models.py index 89e0191dac..f0760832e1 100644 --- a/prowler/lib/outputs/compliance/essential_eight/models.py +++ b/prowler/lib/outputs/compliance/asd_essential_eight/models.py @@ -1,9 +1,9 @@ from pydantic.v1 import BaseModel -class EssentialEightAWSModel(BaseModel): +class ASDEssentialEightAWSModel(BaseModel): """ - EssentialEightAWSModel generates a finding's output in AWS ASD Essential Eight Compliance format. + ASDEssentialEightAWSModel generates a finding's output in AWS ASD Essential Eight Compliance format. """ Provider: str diff --git a/prowler/lib/outputs/compliance/compliance.py b/prowler/lib/outputs/compliance/compliance.py index 7fe2330550..b6b2f1f81f 100644 --- a/prowler/lib/outputs/compliance/compliance.py +++ b/prowler/lib/outputs/compliance/compliance.py @@ -1,6 +1,9 @@ import sys from prowler.lib.logger import logger +from prowler.lib.outputs.compliance.asd_essential_eight.asd_essential_eight import ( + get_asd_essential_eight_table, +) from prowler.lib.outputs.compliance.c5.c5 import get_c5_table from prowler.lib.outputs.compliance.ccc.ccc import get_ccc_table from prowler.lib.outputs.compliance.cis.cis import get_cis_table @@ -9,9 +12,6 @@ from prowler.lib.outputs.compliance.compliance_check import ( # noqa: F401 - re ) from prowler.lib.outputs.compliance.csa.csa import get_csa_table from prowler.lib.outputs.compliance.ens.ens import get_ens_table -from prowler.lib.outputs.compliance.essential_eight.essential_eight import ( - get_essential_eight_table, -) from prowler.lib.outputs.compliance.generic.generic_table import ( get_generic_compliance_table, ) @@ -233,8 +233,8 @@ def display_compliance_table( output_directory, compliance_overview, ) - elif "essential_eight" in compliance_framework: - get_essential_eight_table( + elif "asd_essential_eight" in compliance_framework: + get_asd_essential_eight_table( findings, bulk_checks_metadata, compliance_framework, diff --git a/tests/lib/outputs/compliance/essential_eight/__init__.py b/tests/lib/outputs/compliance/asd_essential_eight/__init__.py similarity index 100% rename from tests/lib/outputs/compliance/essential_eight/__init__.py rename to tests/lib/outputs/compliance/asd_essential_eight/__init__.py diff --git a/tests/lib/outputs/compliance/essential_eight/essential_eight_aws_test.py b/tests/lib/outputs/compliance/asd_essential_eight/asd_essential_eight_aws_test.py similarity index 80% rename from tests/lib/outputs/compliance/essential_eight/essential_eight_aws_test.py rename to tests/lib/outputs/compliance/asd_essential_eight/asd_essential_eight_aws_test.py index 2abbdadb9c..90042c9d57 100644 --- a/tests/lib/outputs/compliance/essential_eight/essential_eight_aws_test.py +++ b/tests/lib/outputs/compliance/asd_essential_eight/asd_essential_eight_aws_test.py @@ -4,13 +4,13 @@ from unittest import mock from freezegun import freeze_time from mock import patch -from prowler.lib.outputs.compliance.essential_eight.essential_eight_aws import ( - EssentialEightAWS, +from prowler.lib.outputs.compliance.asd_essential_eight.asd_essential_eight_aws import ( + ASDEssentialEightAWS, ) -from prowler.lib.outputs.compliance.essential_eight.models import ( - EssentialEightAWSModel, +from prowler.lib.outputs.compliance.asd_essential_eight.models import ( + ASDEssentialEightAWSModel, ) -from tests.lib.outputs.compliance.fixtures import ESSENTIAL_EIGHT_AWS +from tests.lib.outputs.compliance.fixtures import ASD_ESSENTIAL_EIGHT_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 @@ -18,26 +18,26 @@ from tests.providers.aws.utils import AWS_ACCOUNT_NUMBER, AWS_REGION_EU_WEST_1 # clause 8: removal of unsupported online services). The second Requirement is # E8-6.1 (Restrict Office macros, clause 1) which has no Checks and is therefore # emitted as a manual row. -COMPLIANCE_NAME = "Essential-Eight-Nov 2023" +COMPLIANCE_NAME = "ASD-Essential-Eight-Nov 2023" -class TestEssentialEightAWS: +class TestASDEssentialEightAWS: def test_output_transform(self): findings = [generate_finding_output(compliance={COMPLIANCE_NAME: "E8-1.8"})] - output = EssentialEightAWS(findings, ESSENTIAL_EIGHT_AWS) + output = ASDEssentialEightAWS(findings, ASD_ESSENTIAL_EIGHT_AWS) output_data = output.data[0] - assert isinstance(output_data, EssentialEightAWSModel) + assert isinstance(output_data, ASDEssentialEightAWSModel) assert output_data.Provider == "aws" - assert output_data.Framework == ESSENTIAL_EIGHT_AWS.Framework - assert output_data.Name == ESSENTIAL_EIGHT_AWS.Name - assert output_data.Description == ESSENTIAL_EIGHT_AWS.Description + assert output_data.Framework == ASD_ESSENTIAL_EIGHT_AWS.Framework + assert output_data.Name == ASD_ESSENTIAL_EIGHT_AWS.Name + assert output_data.Description == ASD_ESSENTIAL_EIGHT_AWS.Description assert output_data.AccountId == AWS_ACCOUNT_NUMBER assert output_data.Region == AWS_REGION_EU_WEST_1 assert output_data.Requirements_Id == "E8-1.8" assert ( output_data.Requirements_Description - == ESSENTIAL_EIGHT_AWS.Requirements[0].Description + == ASD_ESSENTIAL_EIGHT_AWS.Requirements[0].Description ) assert output_data.Requirements_Attributes_Section == "1 Patch applications" assert output_data.Requirements_Attributes_MaturityLevel == "ML1" @@ -49,7 +49,7 @@ class TestEssentialEightAWS: ) assert ( output_data.Requirements_Attributes_Description - == ESSENTIAL_EIGHT_AWS.Requirements[0].Attributes[0].Description + == ASD_ESSENTIAL_EIGHT_AWS.Requirements[0].Attributes[0].Description ) assert output_data.Status == "PASS" assert output_data.StatusExtended == "" @@ -60,7 +60,7 @@ class TestEssentialEightAWS: def test_manual_requirement(self): findings = [generate_finding_output(compliance={COMPLIANCE_NAME: "E8-1.8"})] - output = EssentialEightAWS(findings, ESSENTIAL_EIGHT_AWS) + output = ASDEssentialEightAWS(findings, ASD_ESSENTIAL_EIGHT_AWS) # E8-6.1 (macros) has no Checks -> emitted as a manual row, non-applicable manual_rows = [row for row in output.data if row.Status == "MANUAL"] @@ -90,13 +90,13 @@ class TestEssentialEightAWS: @freeze_time("2025-01-01 00:00:00") @mock.patch( - "prowler.lib.outputs.compliance.essential_eight.essential_eight_aws.timestamp", + "prowler.lib.outputs.compliance.asd_essential_eight.asd_essential_eight_aws.timestamp", "2025-01-01 00:00:00", ) def test_batch_write_data_to_file(self): mock_file = StringIO() findings = [generate_finding_output(compliance={COMPLIANCE_NAME: "E8-1.8"})] - output = EssentialEightAWS(findings, ESSENTIAL_EIGHT_AWS) + output = ASDEssentialEightAWS(findings, ASD_ESSENTIAL_EIGHT_AWS) output._file_descriptor = mock_file with patch.object(mock_file, "close", return_value=None): diff --git a/tests/lib/outputs/compliance/fixtures.py b/tests/lib/outputs/compliance/fixtures.py index 9aac01392f..e1929ee4d4 100644 --- a/tests/lib/outputs/compliance/fixtures.py +++ b/tests/lib/outputs/compliance/fixtures.py @@ -1,4 +1,5 @@ from prowler.lib.check.compliance_models import ( + ASDEssentialEight_Requirement_Attribute, AWS_Well_Architected_Requirement_Attribute, CCC_Requirement_Attribute, CIS_Requirement_Attribute, @@ -7,7 +8,6 @@ from prowler.lib.check.compliance_models import ( ENS_Requirement_Attribute, ENS_Requirement_Attribute_Nivel, ENS_Requirement_Attribute_Tipos, - EssentialEight_Requirement_Attribute, Generic_Compliance_Requirement_Attribute, ISO27001_2013_Requirement_Attribute, KISA_ISMSP_Requirement_Attribute, @@ -1191,8 +1191,8 @@ CCC_GCP_FIXTURE = Compliance( ], ) -ESSENTIAL_EIGHT_AWS = Compliance( - Framework="Essential-Eight", +ASD_ESSENTIAL_EIGHT_AWS = Compliance( + Framework="ASD-Essential-Eight", Name="ASD Essential Eight Maturity Model - Maturity Level One (AWS)", Version="Nov 2023", Provider="AWS", @@ -1202,7 +1202,7 @@ ESSENTIAL_EIGHT_AWS = Compliance( Id="E8-1.8", Description="Online services that are no longer supported by vendors are removed.", Attributes=[ - EssentialEight_Requirement_Attribute( + ASDEssentialEight_Requirement_Attribute( Section="1 Patch applications", MaturityLevel="ML1", AssessmentStatus="Automated", @@ -1226,7 +1226,7 @@ ESSENTIAL_EIGHT_AWS = Compliance( Id="E8-6.1", Description="Microsoft Office macros are disabled for users that do not have a demonstrated business requirement.", Attributes=[ - EssentialEight_Requirement_Attribute( + ASDEssentialEight_Requirement_Attribute( Section="6 Restrict Microsoft Office macros", MaturityLevel="ML1", AssessmentStatus="Manual",