Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds components.properties filtering in bom #373

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ The full list of options is below:
usage: cli.py [-h] [--no-banner] [] [--csaf] [--sync] [--profile {appsec,research,operational,threat-modeling,license-compliance,generic}] [--no-suggest] [--risk-audit] [--private-ns PRIVATE_NS] [-t PROJECT_TYPE] [--bom BOM]
[-i SRC_DIR_IMAGE] [-o REPORT_FILE] [--reports-dir REPORTS_DIR] [--report-template REPORT_TEMPLATE] [--report-name REPORT_NAME] [--no-error] [--no-license-scan] [--deep] [--no-universal] [--no-vuln-table]
[--threatdb-server THREATDB_SERVER] [--threatdb-username THREATDB_USERNAME] [--threatdb-password THREATDB_PASSWORD] [--threatdb-token THREATDB_TOKEN] [--server] [--server-host SERVER_HOST] [--server-port SERVER_PORT]
[--cdxgen-server CDXGEN_SERVER] [--debug] [--explain] [--reachables-slices-file REACHABLES_SLICES_FILE] [-v]
[--cdxgen-server CDXGEN_SERVER] [--debug] [--explain] [--reachables-slices-file REACHABLES_SLICES_FILE] [--exclude-components-properties LIST_OF_PROPERTY_NAMES] [-v]

Fully open-source security and license audit for application dependencies and container images based on known vulnerabilities and advisories.

Expand Down Expand Up @@ -160,6 +160,10 @@ options:
--reachables-slices-file REACHABLES_SLICES_FILE
Path for the reachables slices file created by atom.
--purl SEARCH_PURL Scan a single package url.
--exclude-components-properties LIST_OF_PROPERTY_NAMES
Comma separated list of properties to exclude from the output VDR BOM (sbom-universal.vdr.json) by the property name (i.e. ImportedModules).
The property name is treated as a regular expression in searching.
The properties appear in the JSON structure under components.properties.
-v, --version Display the version
```

Expand Down
31 changes: 29 additions & 2 deletions depscan/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import os
import sys
import tempfile
import re

from custom_json_diff.lib.utils import json_load, json_dump, file_write
from defusedxml.ElementTree import parse
Expand Down Expand Up @@ -315,6 +316,13 @@ def build_parser():
action="version",
version="%(prog)s " + get_version(),
)
parser.add_argument(
"--exclude-components-properties",
dest="exclude_components_properties",
help="Comma separated list of properties to exclude from the output VDR BOM (sbom-universal.vdr.json) by the property name (i.e. ImportedModules)."
"The property name is treated as a regular expression in searching."
"The properties appear in the JSON structure under components.properties.",
)
return parser


Expand Down Expand Up @@ -347,6 +355,7 @@ def summarise(
scoped_pkgs,
report_file,
bom_file,
exclude_components_properties,
no_vuln_table=False,
direct_purls=None,
reached_purls=None,
Expand Down Expand Up @@ -382,7 +391,7 @@ def summarise(
vdr_file = bom_file.replace(".json", ".vdr.json") if bom_file else None
if pkg_vulnerabilities and bom_file:
if bom_data := json_load(bom_file, log=LOG):
export_bom(bom_data, pkg_vulnerabilities, vdr_file)
export_bom(bom_data, pkg_vulnerabilities, vdr_file, exclude_components_properties)
else:
LOG.warning("Unable to generate VDR file for this scan.")
summary = summary_stats(pkg_vulnerabilities)
Expand Down Expand Up @@ -413,7 +422,7 @@ def summarise_tools(tools, metadata, bom_data):
return bom_data


def export_bom(bom_data, pkg_vulnerabilities, vdr_file):
def export_bom(bom_data, pkg_vulnerabilities, vdr_file, exclude_components_properties):
"""
Exports the Bill of Materials (BOM) data along with package vulnerabilities
to a Vulnerability Data Report (VDR) file.
Expand All @@ -432,10 +441,27 @@ def export_bom(bom_data, pkg_vulnerabilities, vdr_file):
# Update the tools section
if isinstance(tools, dict):
bom_data = summarise_tools(tools, metadata, bom_data)
if exclude_components_properties and bom_data.get("components"):
bom_data = remove_extra_properties(exclude_components_properties, bom_data)
bom_data["vulnerabilities"] = pkg_vulnerabilities
json_dump(vdr_file, bom_data, error_msg=f"Unable to generate VDR file at {vdr_file}", log=LOG)


def remove_extra_properties(exclude_components_properties, bom_data):
exclude_properties = exclude_components_properties.split(",")
for i, component in enumerate(bom_data["components"]):
if properties := component.get("properties"):
bom_data["components"][i]["properties"] = [p for p in properties if not regex_matches_name(p.get("name"), exclude_properties)]
return bom_data


def regex_matches_name(name, list_of_regex):
for regex in list_of_regex:
if re.compile(regex).match(name):
return True
return False


def set_project_types(args, src_dir):
"""
Detects the project types and perform the right type of scan
Expand Down Expand Up @@ -1015,6 +1041,7 @@ def main(args):
scoped_pkgs=scoped_pkgs,
report_file=report_file,
bom_file=bom_file,
exclude_components_properties = args.exclude_components_properties,
no_vuln_table=args.no_vuln_table,
direct_purls=direct_purls,
reached_purls=reached_purls,
Expand Down