diff --git a/lib/check/check.py b/lib/check/check.py
index 538a42f1..7ac29b26 100644
--- a/lib/check/check.py
+++ b/lib/check/check.py
@@ -140,25 +140,26 @@ def print_compliance_frameworks(
def print_compliance_requirements(
- bulk_compliance_frameworks: dict, compliance_framework: str
+ bulk_compliance_frameworks: dict, compliance_frameworks: list
):
- for compliance in bulk_compliance_frameworks.values():
- # Workaround until we have more Compliance Frameworks
- split_compliance = compliance_framework.split("_")
- framework = split_compliance[0].upper()
- version = split_compliance[1].upper()
- provider = split_compliance[2].upper()
- if compliance.Framework == framework and compliance.Version == version:
- print(
- f"Listing {framework} {version} {provider} Compliance Requirements:\n"
- )
- for requirement in compliance.Requirements:
- checks = ""
- for check in requirement.Checks:
- checks += f" {Fore.YELLOW}\t\t{check}\n{Style.RESET_ALL}"
+ for compliance_framework in compliance_frameworks:
+ for compliance in bulk_compliance_frameworks.values():
+ # Workaround until we have more Compliance Frameworks
+ split_compliance = compliance_framework.split("_")
+ framework = split_compliance[0].upper()
+ version = split_compliance[1].upper()
+ provider = split_compliance[2].upper()
+ if framework in compliance.Framework and compliance.Version == version:
print(
- f"Requirement Id: {Fore.MAGENTA}{requirement.Id}{Style.RESET_ALL}\n\t- Description: {requirement.Description}\n\t- Checks:\n{checks}"
+ f"Listing {framework} {version} {provider} Compliance Requirements:\n"
)
+ for requirement in compliance.Requirements:
+ checks = ""
+ for check in requirement.Checks:
+ checks += f" {Fore.YELLOW}\t\t{check}\n{Style.RESET_ALL}"
+ print(
+ f"Requirement Id: {Fore.MAGENTA}{requirement.Id}{Style.RESET_ALL}\n\t- Description: {requirement.Description}\n\t- Checks:\n{checks}"
+ )
def print_checks(
diff --git a/lib/outputs/outputs.py b/lib/outputs/outputs.py
index ecae3d67..0171ded6 100644
--- a/lib/outputs/outputs.py
+++ b/lib/outputs/outputs.py
@@ -16,7 +16,6 @@ from config.config import (
json_asff_file_suffix,
json_file_suffix,
orange_color,
- output_file_timestamp,
prowler_version,
timestamp,
timestamp_iso,
@@ -304,7 +303,6 @@ def initialize_file_descriptor(
if output_mode in ("json", "json-asff"):
file_descriptor.write("[")
-
if "html" in output_mode:
add_html_header(file_descriptor, audit_info)
except Exception as error:
@@ -463,34 +461,6 @@ def fill_json_asff(finding_output, audit_info, finding):
return finding_output
-def fill_html(file_descriptor, audit_info, finding):
- row_class = "p-3 mb-2 bg-success-custom"
- if finding.status == "INFO":
- row_class = "table-info"
- elif finding.status == "FAIL":
- row_class = "table-danger"
- elif finding.status == "WARNING":
- row_class = "table-warning"
- file_descriptor.write(
- f"""
-
- | {finding.status} |
- {finding.check_metadata.Severity} |
- {audit_info.audited_account} |
- {finding.region} |
- {finding.check_metadata.ServiceName} |
- {finding.check_metadata.CheckID} |
- {finding.check_metadata.CheckTitle} |
- {finding.status_extended} |
- {finding.check_metadata.Risk} |
- {finding.check_metadata.Remediation.Recommendation.Text} |
- |
- {finding.resource_id} |
-
- """
- )
-
-
def close_json(output_filename, output_directory, mode):
try:
suffix = json_file_suffix
@@ -638,8 +608,10 @@ def display_summary_table(
print(f" - HTML: {output_directory}/{output_filename}.html")
if "json-asff" in output_options.output_modes:
print(f" - JSON-ASFF: {output_directory}/{output_filename}.asff.json")
- print(f" - CSV: {output_directory}/{output_filename}.csv")
- print(f" - JSON: {output_directory}/{output_filename}.json")
+ if "csv" in output_options.output_modes:
+ print(f" - CSV: {output_directory}/{output_filename}.csv")
+ if "json" in output_options.output_modes:
+ print(f" - JSON: {output_directory}/{output_filename}.json")
else:
print(
@@ -887,8 +859,12 @@ def display_compliance_table(
def add_html_header(file_descriptor, audit_info):
try:
+ if not audit_info.profile:
+ audit_info.profile = "ENV"
if isinstance(audit_info.audited_regions, list):
audited_regions = " ".join(audit_info.audited_regions)
+ elif not audit_info.audited_regions:
+ audited_regions = "All Regions"
else:
audited_regions = audit_info.audited_regions
file_descriptor.write(
@@ -901,7 +877,8 @@ def add_html_header(file_descriptor, audit_info):
@@ -913,12 +890,9 @@ def add_html_header(file_descriptor, audit_info):
display: none;
}
- Prowler - AWS Security Assessments
+ Prowler - The Handy Cloud Security Tool
-
@@ -927,6 +901,14 @@ def add_html_header(file_descriptor, audit_info):
Report Information:
+ -
+
+
-
@@ -943,17 +925,9 @@ def add_html_header(file_descriptor, audit_info):
-
Date: """
- + output_file_timestamp
+ + timestamp.isoformat()
+ """
-
-
-
-
@@ -998,16 +972,16 @@ def add_html_header(file_descriptor, audit_info):
| Status |
Severity |
- Account ID |
+ Service Name |
Region |
- Service |
- Check ID |
Check Title |
- Check Output |
- Risk |
- Remediation |
- Related URL |
Resource ID |
+ Check Description |
+ Check ID |
+ Status Extended |
+ Risk |
+ Recomendation |
+ Recomendation URL |
@@ -1019,6 +993,34 @@ def add_html_header(file_descriptor, audit_info):
)
+def fill_html(file_descriptor, audit_info, finding):
+ row_class = "p-3 mb-2 bg-success-custom"
+ if finding.status == "INFO":
+ row_class = "table-info"
+ elif finding.status == "FAIL":
+ row_class = "table-danger"
+ elif finding.status == "WARNING":
+ row_class = "table-warning"
+ file_descriptor.write(
+ f"""
+
+ | {finding.status} |
+ {finding.check_metadata.Severity} |
+ {finding.check_metadata.ServiceName} |
+ {finding.region} |
+ {finding.check_metadata.CheckTitle} |
+ {finding.resource_id} |
+ {finding.check_metadata.Description} |
+ {finding.check_metadata.CheckID} |
+ {finding.status_extended} |
+ {finding.check_metadata.Risk} |
+ {finding.check_metadata.Remediation.Recommendation.Text} |
+ |
+
+ """
+ )
+
+
def add_html_footer(output_filename, output_directory):
try:
filename = f"{output_directory}/{output_filename}{html_file_suffix}"
@@ -1045,6 +1047,8 @@ def add_html_footer(output_filename, output_directory):
$(document).ready(function(){
// Initialise the table with 50 rows, and some search/filtering panes
$('#findingsTable').DataTable( {
+ lengthChange: true,
+ buttons: [ 'copy', 'excel', 'pdf' ],
lengthMenu: [ [50, 100, -1], [50, 100, "All"] ],
searchPanes: {
cascadePanes: true,
@@ -1054,10 +1058,11 @@ def add_html_footer(output_filename, output_directory):
columnDefs: [
{
searchPanes: {
- show: false
+ show: true,
+ pagingType: 'numbers',
+ searching: true
},
- // Hide Compliance, Check ID (in favour of Check Title), CAF Epic, Risk, Remediation, Link
- targets: [4, 6, 9, 10, 11, 12]
+ targets: [0, 1, 2, 3, 4]
}
]
});
diff --git a/prowler b/prowler
index 941bbedb..e73d6dea 100755
--- a/prowler
+++ b/prowler
@@ -102,9 +102,9 @@ if __name__ == "__main__":
)
list_group.add_argument(
"--list-compliance-requirements",
- nargs="?",
+ nargs="+",
help="List compliance requirements for a given requirement",
- choices=["ens_rd2022_aws"],
+ choices=["ens_rd2022_aws", "cis_1.4_aws", "cis_1.5_aws"],
)
list_group.add_argument(
"--list-categories",
@@ -174,8 +174,8 @@ if __name__ == "__main__":
"-M",
"--output-modes",
nargs="+",
- help="Output mode, by default csv and json",
- default=["csv", "json"],
+ help="Output modes, by default csv, html and json",
+ default=["csv", "json", "html"],
choices=["csv", "json", "json-asff", "html"],
)
parser.add_argument(