Skip to content

Wizcli improvements #12446

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

Open
wants to merge 31 commits into
base: bugfix
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
aeda530
severity mapping
OsamaMahmood May 14, 2025
0f6830e
extract reference link if present in scan output
OsamaMahmood May 14, 2025
d019619
improved parsing and implimented generation of unique id for deduplic…
OsamaMahmood May 14, 2025
f89d858
improved scan result parsers for dir, iac, img scan results
OsamaMahmood May 14, 2025
30ec0e2
improvements
OsamaMahmood May 14, 2025
f8dcca7
enabling dedup in settings.dist.py
OsamaMahmood May 14, 2025
2673b5a
Merge branch 'bugfix' into wizcli-improvements
OsamaMahmood May 14, 2025
58c5687
Merge branch 'DefectDojo:master' into wizcli-improvements
OsamaMahmood Jun 1, 2025
f7e40d3
updated unit test files
OsamaMahmood Jun 2, 2025
b135abf
updated unit test to reflect latest cahnges in the parser
OsamaMahmood Jun 2, 2025
974715f
switched dedp algo to HASH_CODE for wizcli
OsamaMahmood Jun 2, 2025
b5ea466
fixed ruff
OsamaMahmood Jun 2, 2025
dfb95f6
fixed unitests
OsamaMahmood Jun 2, 2025
8576a5f
fixed ruff
OsamaMahmood Jun 2, 2025
59fa30d
Fixed unit test and ruff issues
OsamaMahmood Jun 2, 2025
395fff4
fix to assertions
OsamaMahmood Jun 2, 2025
d78b537
fixed remaining assertions
OsamaMahmood Jun 2, 2025
6a21f00
fixes
OsamaMahmood Jun 2, 2025
a804dcc
updates
OsamaMahmood Jun 2, 2025
ae1cd2a
fixed img test
OsamaMahmood Jun 2, 2025
3d42de8
Update versions in application files
Jun 9, 2025
37d8af6
Merge pull request #12571 from DefectDojo/release/2.47.1
rossops Jun 9, 2025
c41158d
Merge branch 'DefectDojo:master' into wizcli-improvements
OsamaMahmood Jun 12, 2025
7ed4298
added HASHCODE_FIELDS_PER_SCANNER entries for these parser
OsamaMahmood Jun 12, 2025
f9c7365
removed unique id generation and use
OsamaMahmood Jun 12, 2025
16812ad
fixed ruff errors
OsamaMahmood Jun 12, 2025
8dd415e
updated hashcode logic for wizcli scans
OsamaMahmood Jun 13, 2025
1253ef1
type in wizcli iac parser name
OsamaMahmood Jun 13, 2025
8fcb8de
added relase notes
OsamaMahmood Jun 13, 2025
40ad1dd
rephrased to make it clrear to understand
OsamaMahmood Jun 14, 2025
715d098
added fallback value if fixedVersion not found
OsamaMahmood Jun 17, 2025
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
2 changes: 1 addition & 1 deletion components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "defectdojo",
"version": "2.48.0-dev",
"version": "2.47.1",
"license" : "BSD-3-Clause",
"private": true,
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion dojo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
# Django starts so that shared_task will use this app.
from .celery import app as celery_app # noqa: F401

__version__ = "2.47.0"
__version__ = "2.47.1"
__url__ = "https://github.com/DefectDojo/django-DefectDojo"
__docs__ = "https://documentation.defectdojo.com"
6 changes: 6 additions & 0 deletions dojo/settings/settings.dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,9 @@ def saml2_attrib_map_format(din):
"Red Hat Satellite": ["description", "severity"],
"Qualys Hacker Guardian Scan": ["title", "severity", "description"],
"Cyberwatch scan (Galeax)": ["title", "description", "severity"],
"Wizcli Img Scan": ["title", "description", "file_path", "line", "component_name", "component_version"],
"Wizcli Dir Scan": ["title", "description", "file_path", "line", "component_name", "component_version"],
"Wizcli IAC Scan": ["title", "description", "file_path", "line", "component_name"],
}

# Override the hardcoded settings here via the env var
Expand Down Expand Up @@ -1590,6 +1593,9 @@ def saml2_attrib_map_format(din):
"Kubescape JSON Importer": DEDUPE_ALGO_HASH_CODE,
"Kiuwan SCA Scan": DEDUPE_ALGO_HASH_CODE,
"Rapplex Scan": DEDUPE_ALGO_HASH_CODE,
"Wizcli Img Scan": DEDUPE_ALGO_HASH_CODE,
"Wizcli Dir Scan": DEDUPE_ALGO_HASH_CODE,
"Wizcli IAC Scan": DEDUPE_ALGO_HASH_CODE,
"AppCheck Web Application Scanner": DEDUPE_ALGO_HASH_CODE,
"AWS Inspector2 Scan": DEDUPE_ALGO_UNIQUE_ID_FROM_TOOL_OR_HASH_CODE,
"Legitify Scan": DEDUPE_ALGO_HASH_CODE,
Expand Down
537 changes: 371 additions & 166 deletions dojo/tools/wizcli_common_parsers/parsers.py

Large diffs are not rendered by default.

50 changes: 40 additions & 10 deletions dojo/tools/wizcli_dir/parser.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,66 @@
import json
import logging

from dojo.tools.wizcli_common_parsers.parsers import WizcliParsers

logger = logging.getLogger(__name__)


class WizcliDirParser:

"""Wizcli Dir Scan results in JSON file format."""
"""Wiz CLI Directory/IaC Scan results in JSON file format."""

def get_scan_types(self):
return ["Wizcli Dir Scan"]

def get_label_for_scan_types(self, scan_type):
return "Wizcli Dir Scan"
return "Wiz CLI Scan (Directory)"

def get_description_for_scan_types(self, scan_type):
return "Wizcli Dir Scan results in JSON file format."
return "Parses Wiz CLI Directory/IaC scan results in JSON format, creating granular findings for vulnerabilities and secrets."

def get_findings(self, filename, test):
scan_data = filename.read()
def get_findings(self, file, test):
"""Processes the JSON report and returns a list of DefectDojo Finding objects."""
try:
data = json.loads(scan_data.decode("utf-8"))
except Exception:
scan_data = file.read()
if isinstance(scan_data, bytes):
# Try decoding common encodings
try:
scan_data = scan_data.decode("utf-8-sig") # Handles BOM
except UnicodeDecodeError:
scan_data = scan_data.decode("utf-8") # Fallback
data = json.loads(scan_data)
except json.JSONDecodeError as e:
msg = f"Invalid JSON format: {e}"
logger.error(msg)
raise ValueError(msg) from e
except Exception as e:
msg = f"Error processing report file: {e}"
logger.error(msg)
raise ValueError(msg) from e

findings = []
results = data.get("result", {})
results_data = data.get("result", {})

if not results_data:
logger.warning("No 'result' key found in the Wiz report. Unable to parse findings.")
return findings

libraries = results.get("libraries", None)
# Parse Libraries (Vulnerabilities)
libraries = results_data.get("libraries")
if libraries:
logger.debug(f"Parsing {len(libraries)} library entries.")
findings.extend(WizcliParsers.parse_libraries(libraries, test))
else:
logger.debug("No 'libraries' data found in results.")

secrets = results.get("secrets", None)
# Parse Secrets
secrets = results_data.get("secrets")
if secrets:
logger.debug(f"Parsing {len(secrets)} secret entries.")
findings.extend(WizcliParsers.parse_secrets(secrets, test))
else:
logger.debug("No 'secrets' data found in results.")

logger.info(f"WizcliDirParser processed {len(findings)} findings.")
return findings
52 changes: 40 additions & 12 deletions dojo/tools/wizcli_iac/parser.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,64 @@
import json
import logging

from dojo.tools.wizcli_common_parsers.parsers import WizcliParsers
from dojo.tools.wizcli_common_parsers.parsers import WizcliParsers # Adjust import path

logger = logging.getLogger(__name__)

class WizcliIaCParser:

"""Wizcli IaC Scan results in JSON file format."""
class WizcliIacParser:

"""Wiz CLI IaC Scan results in JSON file format."""

def get_scan_types(self):
return ["Wizcli IaC Scan"]

def get_label_for_scan_types(self, scan_type):
return "Wizcli IaC Scan"
return "Wiz CLI Scan (IaC)"

def get_description_for_scan_types(self, scan_type):
return "Wizcli IaC Scan results in JSON file format."
return "Parses Wiz CLI Infrastructure as Code (IaC) scan results in JSON format."

def get_findings(self, filename, test):
scan_data = filename.read()
def get_findings(self, file, test):
try:
data = json.loads(scan_data.decode("utf-8"))
except Exception:
scan_data = file.read()
if isinstance(scan_data, bytes):
try:
scan_data = scan_data.decode("utf-8-sig")
except UnicodeDecodeError:
scan_data = scan_data.decode("utf-8")
data = json.loads(scan_data)
except json.JSONDecodeError as e:
msg = f"Invalid JSON format: {e}"
logger.error(msg)
raise ValueError(msg) from e
except Exception as e:
msg = f"Error processing report file: {e}"
logger.error(msg)
raise ValueError(msg) from e

findings = []
results = data.get("result", {})
results_data = data.get("result", {})

if not results_data:
logger.warning("No 'result' key found in the Wiz report.")
return findings

rule_matches = results.get("ruleMatches", None)
# Parse Rule Matches (IaC findings)
rule_matches = results_data.get("ruleMatches")
if rule_matches:
logger.debug(f"Parsing {len(rule_matches)} rule match entries.")
findings.extend(WizcliParsers.parse_rule_matches(rule_matches, test))
else:
logger.debug("No 'ruleMatches' data found in results.")

secrets = results.get("secrets", None)
# Parse Secrets (if present in IaC scans)
secrets = results_data.get("secrets")
if secrets:
logger.debug(f"Parsing {len(secrets)} secret entries.")
findings.extend(WizcliParsers.parse_secrets(secrets, test))
else:
logger.debug("No 'secrets' data found in results.")

logger.info(f"WizcliIacParser processed {len(findings)} findings.")
return findings
61 changes: 47 additions & 14 deletions dojo/tools/wizcli_img/parser.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,73 @@
import json
import logging

from dojo.tools.wizcli_common_parsers.parsers import WizcliParsers
from dojo.tools.wizcli_common_parsers.parsers import WizcliParsers # Adjust import path

logger = logging.getLogger(__name__)


class WizcliImgParser:

"""Wizcli Image Scan results in JSON file format."""
"""Wiz CLI Container Image Scan results in JSON file format."""

def get_scan_types(self):
# Use a distinct name for image scans
return ["Wizcli Img Scan"]

def get_label_for_scan_types(self, scan_type):
return "Wizcli Img Scan"
return "Wiz CLI Scan (Image)"

def get_description_for_scan_types(self, scan_type):
return "Wizcli Img report file can be imported in JSON format."
return "Parses Wiz CLI Container Image scan results in JSON format."

def get_findings(self, filename, test):
scan_data = filename.read()
def get_findings(self, file, test):
try:
data = json.loads(scan_data.decode("utf-8"))
except Exception:
scan_data = file.read()
if isinstance(scan_data, bytes):
try:
scan_data = scan_data.decode("utf-8-sig")
except UnicodeDecodeError:
scan_data = scan_data.decode("utf-8")
data = json.loads(scan_data)
except json.JSONDecodeError as e:
msg = f"Invalid JSON format: {e}"
logger.error(msg)
raise ValueError(msg) from e
except Exception as e:
msg = f"Error processing report file: {e}"
logger.error(msg)
raise ValueError(msg) from e

findings = []
results = data.get("result", {})
results_data = data.get("result", {})

if not results_data:
logger.warning("No 'result' key found in the Wiz report.")
return findings

osPackages = results.get("osPackages", None)
if osPackages:
findings.extend(WizcliParsers.parse_os_packages(osPackages, test))
# Parse OS Packages - Key difference for image scans
os_packages = results_data.get("osPackages")
if os_packages:
logger.debug(f"Parsing {len(os_packages)} OS package entries.")
findings.extend(WizcliParsers.parse_os_packages(os_packages, test))
else:
logger.debug("No 'osPackages' data found in results.")

libraries = results.get("libraries", None)
# Parse Libraries (if present in image scans)
libraries = results_data.get("libraries")
if libraries:
logger.debug(f"Parsing {len(libraries)} library entries.")
findings.extend(WizcliParsers.parse_libraries(libraries, test))
else:
logger.debug("No 'libraries' data found in results.")

secrets = results.get("secrets", None)
# Parse Secrets (if present in image scans)
secrets = results_data.get("secrets")
if secrets:
logger.debug(f"Parsing {len(secrets)} secret entries.")
findings.extend(WizcliParsers.parse_secrets(secrets, test))
else:
logger.debug("No 'secrets' data found in results.")

logger.info(f"WizcliImgParser processed {len(findings)} findings.")
return findings
4 changes: 2 additions & 2 deletions helm/defectdojo/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
apiVersion: v2
appVersion: "2.48.0-dev"
appVersion: "2.47.1"
description: A Helm chart for Kubernetes to install DefectDojo
name: defectdojo
version: 1.6.191-dev
version: 1.6.191
icon: https://www.defectdojo.org/img/favicon.ico
maintainers:
- name: madchap
Expand Down
Loading