feat(compliance): Add CIS 1.8 framework for Kubernetes (#3600)

Co-authored-by: Sergio Garcia <sergargar1@gmail.com>
This commit is contained in:
Pedro Martín
2024-03-26 14:03:39 +01:00
committed by GitHub
parent 1506da54fc
commit d9b6624d65
11 changed files with 2870 additions and 4 deletions

View File

@@ -31,6 +31,7 @@ Currently, the available frameworks are:
- `cis_2.0_aws`
- `cis_2.0_gcp`
- `cis_3.0_aws`
- `cis_1.8_kubernetes`
- `cisa_aws`
- `ens_rd2022_aws`
- `fedramp_low_revision_4_aws`

File diff suppressed because it is too large Load Diff

View File

@@ -30,7 +30,7 @@ actual_directory = pathlib.Path(os.path.dirname(os.path.realpath(__file__)))
def get_available_compliance_frameworks(provider=None):
available_compliance_frameworks = []
providers = ["aws", "gcp", "azure"]
providers = ["aws", "gcp", "azure", "kubernetes"]
if provider:
providers = [provider]
for provider in providers:

View File

@@ -88,6 +88,7 @@ class CIS_Requirement_Attribute(BaseModel):
AuditProcedure: str
AdditionalInformation: str
References: str
DefaultValue: Optional[str]
# Well Architected Requirement Attribute

View File

@@ -1,5 +1,8 @@
from prowler.lib.outputs.compliance.cis_aws import generate_compliance_row_cis_aws
from prowler.lib.outputs.compliance.cis_gcp import generate_compliance_row_cis_gcp
from prowler.lib.outputs.compliance.cis_kubernetes import (
generate_compliance_row_cis_kubernetes,
)
from prowler.lib.outputs.csv.csv import write_csv
@@ -30,6 +33,12 @@ def write_compliance_row_cis(
(compliance_row, csv_header) = generate_compliance_row_cis_gcp(
finding, compliance, requirement, attribute, output_options
)
elif compliance.Provider == "Kubernetes":
(compliance_row, csv_header) = (
generate_compliance_row_cis_kubernetes(
finding, compliance, requirement, attribute, output_options
)
)
write_csv(
file_descriptors[compliance_output], csv_header, compliance_row

View File

@@ -0,0 +1,35 @@
from prowler.config.config import timestamp
from prowler.lib.outputs.compliance.models import Check_Output_CSV_KUBERNETES_CIS
from prowler.lib.outputs.csv.csv import generate_csv_fields
from prowler.lib.utils.utils import outputs_unix_timestamp
def generate_compliance_row_cis_kubernetes(
finding, compliance, requirement, attribute, output_options
):
compliance_row = Check_Output_CSV_KUBERNETES_CIS(
Provider=finding.check_metadata.Provider,
Description=compliance.Description,
Region=finding.namespace,
AssessmentDate=outputs_unix_timestamp(output_options.unix_timestamp, timestamp),
Requirements_Id=requirement.Id,
Requirements_Description=requirement.Description,
Requirements_Attributes_Section=attribute.Section,
Requirements_Attributes_Profile=attribute.Profile,
Requirements_Attributes_AssessmentStatus=attribute.AssessmentStatus,
Requirements_Attributes_Description=attribute.Description,
Requirements_Attributes_RationaleStatement=attribute.RationaleStatement,
Requirements_Attributes_ImpactStatement=attribute.ImpactStatement,
Requirements_Attributes_RemediationProcedure=attribute.RemediationProcedure,
Requirements_Attributes_AuditProcedure=attribute.AuditProcedure,
Requirements_Attributes_AdditionalInformation=attribute.AdditionalInformation,
Requirements_Attributes_References=attribute.References,
Requirements_Attributes_DefaultValue=attribute.DefaultValue,
Status=finding.status,
StatusExtended=finding.status_extended,
ResourceId=finding.resource_id,
CheckId=finding.check_metadata.CheckID,
)
csv_header = generate_csv_fields(Check_Output_CSV_KUBERNETES_CIS)
return compliance_row, csv_header

View File

@@ -38,6 +38,7 @@ def add_manual_controls(
manual_finding.region = ""
manual_finding.location = ""
manual_finding.project_id = ""
manual_finding.namespace = ""
fill_compliance(
output_options,
manual_finding,
@@ -284,12 +285,12 @@ def display_compliance_table(
fail_count += 1
elif finding.status == "PASS":
pass_count += 1
if attribute.Profile == "Level 1":
if "Level 1" in attribute.Profile:
if finding.status == "FAIL":
sections[section]["Level 1"]["FAIL"] += 1
else:
sections[section]["Level 1"]["PASS"] += 1
elif attribute.Profile == "Level 2":
elif "Level 2" in attribute.Profile:
if finding.status == "FAIL":
sections[section]["Level 2"]["FAIL"] += 1
else:

View File

@@ -113,6 +113,34 @@ class Check_Output_CSV_GCP_CIS(BaseModel):
CheckId: str
class Check_Output_CSV_KUBERNETES_CIS(BaseModel):
"""
Check_Output_CSV_CIS generates a finding's output in CSV CIS format.
"""
Provider: str
Description: str
Region: 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
CheckId: str
class Check_Output_CSV_Generic_Compliance(BaseModel):
"""
Check_Output_CSV_Generic_Compliance generates a finding's output in CSV Generic Compliance format.

View File

@@ -16,6 +16,7 @@ from prowler.lib.outputs.compliance.models import (
Check_Output_CSV_ENS_RD2022,
Check_Output_CSV_GCP_CIS,
Check_Output_CSV_Generic_Compliance,
Check_Output_CSV_KUBERNETES_CIS,
Check_Output_MITRE_ATTACK,
)
from prowler.lib.outputs.csv.csv import generate_csv_fields
@@ -91,6 +92,21 @@ def fill_file_descriptors(output_modes, output_directory, output_filename, provi
)
file_descriptors.update({output_mode: file_descriptor})
elif provider.type == "kubernetes":
filename = f"{output_directory}/compliance/{output_filename}_{output_mode}{csv_file_suffix}"
if "cis_" in output_mode:
file_descriptor = initialize_file_descriptor(
filename, output_mode, Check_Output_CSV_KUBERNETES_CIS
)
file_descriptors.update({output_mode: file_descriptor})
else:
file_descriptor = initialize_file_descriptor(
filename,
output_mode,
Check_Output_CSV_Generic_Compliance,
)
file_descriptors.update({output_mode: file_descriptor})
elif provider.type == "aws":
if output_mode == "json-asff":
filename = f"{output_directory}/{output_filename}{json_asff_file_suffix}"

View File

@@ -1,6 +1,6 @@
{
"Provider": "kubernetes",
"CheckID": "controller_manager_disable_profiling",
"CheckID": "controllermanager_disable_profiling",
"CheckTitle": "Ensure that the --profiling argument is set to false",
"CheckType": [],
"ServiceName": "controller-manager",

View File

@@ -132,6 +132,7 @@ class Test_Config:
"fedramp_moderate_revision_4_aws",
"fedramp_low_revision_4_aws",
"cis_2.0_gcp",
"cis_1.8_kubernetes",
]
assert (
get_available_compliance_frameworks().sort() == compliance_frameworks.sort()