From 930f5c714b4dd462813f4ae7b17d2b3b7af469ff Mon Sep 17 00:00:00 2001 From: Josep Lluis Ferrer Date: Fri, 30 Jan 2026 11:01:07 +0100 Subject: [PATCH] config update: Add severity_modification_type option Allow to select the vulnerabilites to be imported to the NAVI DB based on the recast done by the user. Default behaviour continues to export all vulnerabilities. The --severity-modification-type option in the `navi config update` command allows to select the vulnerabilities based on the user recast action: - NONE: No modification to the severity has been made. - RECASTED: A user has recast the risk associated with the vulnerability. - ACCEPTED: A user has accepted the risk associated with the vulnerability. This can be used in cases where users are syncing the exports with external ticketing systems (e.g. github, jira,...), considering only the ones to be fixed and not accepted. Signed-off-by: Josep Lluis Ferrer --- navi/plugins/config.py | 25 +++++++++++++++++-------- navi/plugins/th_vuln_export.py | 4 +++- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/navi/plugins/config.py b/navi/plugins/config.py index c059b57..4d4580c 100644 --- a/navi/plugins/config.py +++ b/navi/plugins/config.py @@ -654,7 +654,7 @@ def search_for_path(): create_vuln_path_table() pattern = r'''(?ix) - (?: + (?: [a-zA-Z]:\\(?:[\w\s().-]+\\)*[\w\s().-]{3,} # Windows path with spaces, parentheses | (?:\.{1,2}/|/)(?:[\w.-]+/)*[\w.-]{3,} # Unix-style paths @@ -814,8 +814,8 @@ def smtp(server, port, email, password): create_smtp_table = """CREATE TABLE IF NOT EXISTS smtp ( server text, port text, - email text, - password text + email text, + password text );""" create_table(conn, create_smtp_table) @@ -1268,7 +1268,10 @@ def update(): @click.option('--severity', multiple=True, default=["critical", "high", "medium", "low", "info"], type=click.Choice(["critical", "high", "medium", "low", "info"]), help='Isolate your update to a particular finding severity') -def full(threads, days, c, v, state, severity): +@click.option('--severity-modification-type', multiple=True, default=["NONE", "RECASTED", "ACCEPTED"], + type=click.Choice(["NONE", "RECASTED", "ACCEPTED"]), + help="Modify severity types to include.") +def full(threads, days, c, v, state, severity, severity_modification_type): if threads: threads_check(threads) @@ -1276,11 +1279,13 @@ def full(threads, days, c, v, state, severity): if days is None: vuln_export(30, exid, threads, c, v, list(state), list(severity), - operator="gte", vpr_score=None, plugins=None) + operator="gte", vpr_score=None, plugins=None, + severity_modification_type=list(severity_modification_type)) asset_export(90, exid, threads, c, v) else: vuln_export(days, exid, threads, c, v, list(state), list(severity), - operator="gte", vpr_score=None, plugins=None) + operator="gte", vpr_score=None, plugins=None, + severity_modification_type=list(severity_modification_type)) asset_export(days, exid, threads, c, v) @@ -1326,14 +1331,18 @@ def agents(): help="VPR operator") @click.option("--plugin_id", multiple=True, type=click.INT, default=None, help="Plugin ID(s) that you want downloaded. Use multiple values for multiple plugins") -def vulns(threads, days, exid, c, v, state, severity, vpr_score, operator, plugin_id): +@click.option('--severity-modification-type', multiple=True, default=["NONE", "RECASTED", "ACCEPTED"], + type=click.Choice(["NONE", "RECASTED", "ACCEPTED"]), + help="Modify severity types to include.") +def vulns(threads, days, exid, c, v, state, severity, vpr_score, operator, plugin_id, severity_modification_type): if threads: threads_check(threads) if exid == ' ': exid = '0' - vuln_export(days, exid, threads, c, v, list(state), list(severity), vpr_score, operator, list(plugin_id)) + vuln_export(days, exid, threads, c, v, list(state), list(severity), vpr_score, operator, list(plugin_id), + severity_modification_type=severity_modification_type)) @update.command(help="Update the Compliance data") diff --git a/navi/plugins/th_vuln_export.py b/navi/plugins/th_vuln_export.py index 7602a50..96e838d 100644 --- a/navi/plugins/th_vuln_export.py +++ b/navi/plugins/th_vuln_export.py @@ -454,7 +454,7 @@ def parse_data(chunk_data, chunk_number): vuln_conn.close() -def vuln_export(days, ex_uuid, threads, category, value, state, severity, vpr_score, operator, plugins): +def vuln_export(days, ex_uuid, threads, category, value, state, severity, vpr_score, operator, plugins, severity_modification_type=None): start = time.time() database = r"navi.db" @@ -513,6 +513,8 @@ def vuln_export(days, ex_uuid, threads, category, value, state, severity, vpr_sc pay_load = {"num_assets": 50, "filters": {'last_found': int(day_limit), "state": state, "severity": severity, "tag.{}".format(category): "[\"{}\"]".format(value)}} + if severity_modification_type: + pay_load['filters']['severity_modification_type'] = severity_modification_type try: