mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-09 21:14:22 +00:00
feat(aws): rename Essential Eight to ASD Essential Eight (#11054)
Co-authored-by: César Arroba <cesar@prowler.com>
This commit is contained in:
co-authored by
César Arroba
parent
4d9921a9b7
commit
e585ae45bd
+7
-7
@@ -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 = (
|
||||
|
||||
+1
-1
@@ -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",
|
||||
@@ -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,
|
||||
|
||||
+10
-10
@@ -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",
|
||||
)
|
||||
+6
-6
@@ -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="",
|
||||
+2
-2
@@ -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
|
||||
@@ -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,
|
||||
|
||||
+17
-17
@@ -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):
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user