From 5ee0c4f926377fc655bc1675af103d06db62540b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= Date: Fri, 3 Nov 2023 15:31:34 +0100 Subject: [PATCH] Present references in a table We will sort and show the references grouped by reference target. The well-known references will be labeled. This makes the "References" section of rule detail actually useful. Fixes: https://github.com/OpenSCAP/openscap-report/issues/154 --- .../html_templates/rule_detail.html | 25 +++++------ .../data_structures/reference.py | 3 +- .../parsers/rule_parser.py | 41 +++++++++++++++++-- 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/openscap_report/report_generators/html_templates/rule_detail.html b/openscap_report/report_generators/html_templates/rule_detail.html index a774103e..3ae5087e 100644 --- a/openscap_report/report_generators/html_templates/rule_detail.html +++ b/openscap_report/report_generators/html_templates/rule_detail.html @@ -136,20 +136,21 @@

References:

-
-

-

+ {%- for reference in rule.references -%} - {%- if reference.href -%} - {{ reference.text }} - {%- else -%} - {{ reference.text }} - {%- endif -%} - {{- ", " if not loop.last else "" -}} + + + + {%- endfor -%} - -

- +
+ {{ reference.name }}: + + {%- for ref_id in reference.ref_ids -%} + {{ ref_id }} + {{- ", " if not loop.last else "" -}} + {%- endfor -%} +
{% endif %} diff --git a/openscap_report/scap_results_parser/data_structures/reference.py b/openscap_report/scap_results_parser/data_structures/reference.py index 64952b54..7419216d 100644 --- a/openscap_report/scap_results_parser/data_structures/reference.py +++ b/openscap_report/scap_results_parser/data_structures/reference.py @@ -11,8 +11,9 @@ @dataclass class Reference: + name: str href: str - text: str + ref_ids: list[str] def as_dict(self): return asdict(self) diff --git a/openscap_report/scap_results_parser/parsers/rule_parser.py b/openscap_report/scap_results_parser/parsers/rule_parser.py index 05a031b7..2677d3c9 100644 --- a/openscap_report/scap_results_parser/parsers/rule_parser.py +++ b/openscap_report/scap_results_parser/parsers/rule_parser.py @@ -1,6 +1,8 @@ # Copyright 2022, Red Hat, Inc. # SPDX-License-Identifier: LGPL-2.1-or-later +import collections + from dataclasses import replace from ..data_structures import Identifier, Reference, Rule, RuleWarning @@ -8,6 +10,33 @@ from .full_text_parser import FullTextParser from .remediation_parser import RemediationParser +KNOWN_REFERENCES = { + "http://www.ssi.gouv.fr/administration/bonnes-pratiques/" : "ANSSI", + "https://public.cyber.mil/stigs/cci/": "CCI", + "https://www.ccn-cert.cni.es/pdf/guias/series-ccn-stic/guias-de-acceso-publico-ccn-stic/6768-ccn-stic-610a22-perfilado-de-seguridad-red-hat-enterprise-linux-9-0/file.html": "CCN for RHEL 9", + "https://www.cisecurity.org/controls/": "CIS", + "https://www.cisecurity.org/benchmark/red_hat_linux/": "CIS for RHEL", + "https://www.fbi.gov/file-repository/cjis-security-policy-v5_5_20160601-2-1.pdf": "CJIS", + "http://www.cnss.gov/Assets/pdf/CNSSI-1253.pdf": "CNSS", + "https://www.isaca.org/resources/cobit": "COBIT", + "http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-171.pdf": "CUI", + "https://www.gpo.gov/fdsys/pkg/CFR-2007-title45-vol1/pdf/CFR-2007-title45-vol1-chapA-subchapC.pdf": "HIPAA", + "https://www.isa.org/products/ansi-isa-62443-3-3-99-03-03-2013-security-for-indu": "ISA-62443-2013", + "https://www.isa.org/products/isa-62443-2-1-2009-security-for-industrial-automat": "ISA-62443-2009", + "https://www.cyber.gov.au/acsc/view-all-content/ism": "ISM", + "https://www.iso.org/standard/54534.html": "ISO 27001-2013", + "https://www.nerc.com/pa/Stand/Standard%20Purpose%20Statement%20DL/US_Standard_One-Stop-Shop.xlsx": "NERC-CIP", + "http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-53r4.pdf": "NIST 800-53", + "https://nvlpubs.nist.gov/nistpubs/CSWP/NIST.CSWP.04162018.pdf": "NIST CSF", + "https://www.niap-ccevs.org/Profile/PP.cfm": "OSPP", + "https://www.pcisecuritystandards.org/documents/PCI_DSS_v3-2-1.pdf": "PCI-DSS v3", + "https://docs-prv.pcisecuritystandards.org/PCI%20DSS/Standard/PCI-DSS-v4_0.pdf": "PCI-DSS v4", + "https://public.cyber.mil/stigs/downloads/?_dl_facet_stigs=application-servers": "SRG-APP", + "https://public.cyber.mil/stigs/downloads/?_dl_facet_stigs=operating-systems%2Cgeneral-purpose-os": "SRG-OS", + "https://public.cyber.mil/stigs/downloads/?_dl_facet_stigs=operating-systems%2Cunix-linux": "STIG ID", + "https://public.cyber.mil/stigs/srg-stig-tools/": "STIG ref", +} + class RuleParser(): def __init__(self, root, test_results, ref_values): @@ -20,10 +49,16 @@ def __init__(self, root, test_results, ref_values): @staticmethod def _get_references(rule): + url_to_ref_ids = collections.defaultdict(list) + for reference_el in rule.findall(".//xccdf:reference", NAMESPACES): + url = reference_el.get("href") + ref_id = reference_el.text + url_to_ref_ids[url].append(ref_id) references = [] - for referenc in rule.findall(".//xccdf:reference", NAMESPACES): - references.append(Reference(referenc.get("href"), referenc.text)) - return references + for url, ref_ids in url_to_ref_ids.items(): + name = KNOWN_REFERENCES.get(url, url) + references.append(Reference(name, url, sorted(ref_ids))) + return sorted(references, key=lambda x: x.name) @staticmethod def _get_identifiers(rule):