feat(json-asff): adds AWS resource tags in json-asff and SecurityHub findings (#2786)

Co-authored-by: samuel.burgos <samuel.burgos@flywire.com>
Co-authored-by: Sergio Garcia <sergargar1@gmail.com>
This commit is contained in:
Samuel Burgos
2023-10-02 18:20:35 +02:00
committed by GitHub
parent a2dfb60466
commit 6558aedee3
5 changed files with 39 additions and 2 deletions

View File

@@ -63,12 +63,14 @@ def fill_json_asff(finding_output, audit_info, finding, output_options):
if len(finding.status_extended) > 1000 if len(finding.status_extended) > 1000
else finding.status_extended else finding.status_extended
) )
resource_tags = generate_json_asff_resource_tags(finding.resource_tags)
finding_output.Resources = [ finding_output.Resources = [
Resource( Resource(
Id=finding.resource_arn, Id=finding.resource_arn,
Type=finding.check_metadata.ResourceType, Type=finding.check_metadata.ResourceType,
Partition=audit_info.audited_partition, Partition=audit_info.audited_partition,
Region=finding.region, Region=finding.region,
Tags=resource_tags,
) )
] ]
# Iterate for each compliance framework # Iterate for each compliance framework
@@ -121,6 +123,26 @@ def generate_json_asff_status(status: str) -> str:
return json_asff_status return json_asff_status
def generate_json_asff_resource_tags(tags):
try:
resource_tags = {}
if tags and tags != [None]:
for tag in tags:
if "Key" in tag and "Value" in tag:
resource_tags[tag["Key"]] = tag["Value"]
else:
resource_tags.update(tag)
if len(resource_tags) == 0:
return None
else:
return None
return resource_tags
except Exception as error:
logger.error(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def fill_json_ocsf(audit_info, finding, output_options) -> Check_Output_JSON_OCSF: def fill_json_ocsf(audit_info, finding, output_options) -> Check_Output_JSON_OCSF:
try: try:
resource_region = "" resource_region = ""

View File

@@ -683,6 +683,7 @@ class Resource(BaseModel):
Id: str Id: str
Partition: str Partition: str
Region: str Region: str
Tags: Optional[dict]
class Compliance(BaseModel): class Compliance(BaseModel):

View File

@@ -102,7 +102,7 @@ def report(check_findings, output_options, audit_info):
) )
json.dump( json.dump(
finding_output.dict(), finding_output.dict(exclude_none=True),
file_descriptors["json-asff"], file_descriptors["json-asff"],
indent=4, indent=4,
) )

View File

@@ -40,7 +40,9 @@ def prepare_security_hub_findings(
) )
# Include that finding within their region in the JSON format # Include that finding within their region in the JSON format
security_hub_findings_per_region[region].append(finding_json_asff.dict()) security_hub_findings_per_region[region].append(
finding_json_asff.dict(exclude_none=True)
)
return security_hub_findings_per_region return security_hub_findings_per_region

View File

@@ -28,6 +28,7 @@ from prowler.lib.outputs.json import (
fill_json_asff, fill_json_asff,
fill_json_ocsf, fill_json_ocsf,
generate_json_asff_status, generate_json_asff_status,
generate_json_asff_resource_tags,
generate_json_ocsf_severity_id, generate_json_ocsf_severity_id,
generate_json_ocsf_status, generate_json_ocsf_status,
generate_json_ocsf_status_id, generate_json_ocsf_status_id,
@@ -1349,6 +1350,17 @@ class Test_Outputs:
assert generate_json_asff_status("WARNING") == "WARNING" assert generate_json_asff_status("WARNING") == "WARNING"
assert generate_json_asff_status("SOMETHING ELSE") == "NOT_AVAILABLE" assert generate_json_asff_status("SOMETHING ELSE") == "NOT_AVAILABLE"
def test_generate_json_asff_resource_tags(self):
assert generate_json_asff_resource_tags(None) is None
assert generate_json_asff_resource_tags([]) is None
assert generate_json_asff_resource_tags([{}]) is None
assert generate_json_asff_resource_tags([{"key1": "value1"}]) == {
"key1": "value1"
}
assert generate_json_asff_resource_tags(
[{"Key": "key1", "Value": "value1"}]
) == {"key1": "value1"}
def test_generate_json_ocsf_status(self): def test_generate_json_ocsf_status(self):
assert generate_json_ocsf_status("PASS") == "Success" assert generate_json_ocsf_status("PASS") == "Success"
assert generate_json_ocsf_status("FAIL") == "Failure" assert generate_json_ocsf_status("FAIL") == "Failure"