Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
4770db2
new parser Jfrog Xray on Demand Binary Scan
renejal Nov 16, 2023
7c645ac
new parser Jfrog Xray on Demand Binary Scan
renejal Nov 16, 2023
c477ed3
Merge branch 'feature/parser_jfrog_xray_binary_scan' of https://githu…
renejal Nov 16, 2023
77572a4
Merge branch 'feature/parser_jfrog_xray_binary_scan' of https://githu…
renejal Nov 16, 2023
4eefc39
Merge branch 'feature/parser_jfrog_xray_binary_scan' of https://githu…
renejal Nov 16, 2023
5364a6a
Merge branch 'feature/parser_jfrog_xray_binary_scan' of https://githu…
renejal Nov 16, 2023
259a808
Merge branch 'feature/parser_jfrog_xray_binary_scan' of https://githu…
renejal Nov 16, 2023
0dff403
delete blank line at end of file
renejal Nov 17, 2023
83aefa5
rename function
renejal Nov 17, 2023
7781ef8
More sample reports
kiblik Nov 17, 2023
9591890
Update docs/content/en/integrations/parsers/file/jfrog_xray_on_demand…
renejal Nov 18, 2023
5c10366
Update docs/content/en/integrations/parsers/file/jfrog_xray_on_demand…
renejal Nov 18, 2023
7a139f3
Update docs/content/en/integrations/parsers/file/jfrog_xray_on_demand…
renejal Nov 18, 2023
2f01430
Update dojo/settings/settings.dist.py
renejal Nov 18, 2023
3ba1a15
Update dojo/settings/settings.dist.py
renejal Nov 18, 2023
8b7c29c
Update dojo/tools/jfrog_xray_on_demand_binary_scan/parser.py
renejal Nov 18, 2023
8bd9320
Update dojo/tools/jfrog_xray_on_demand_binary_scan/parser.py
renejal Nov 18, 2023
165084a
Update dojo/tools/jfrog_xray_on_demand_binary_scan/parser.py
renejal Nov 18, 2023
f9419a9
Update dojo/tools/jfrog_xray_on_demand_binary_scan/parser.py
renejal Nov 18, 2023
adde828
Update dojo/tools/jfrog_xray_on_demand_binary_scan/parser.py
renejal Nov 18, 2023
c186480
Update dojo/tools/jfrog_xray_on_demand_binary_scan/parser.py
renejal Nov 18, 2023
56f1ec9
Update dojo/tools/jfrog_xray_on_demand_binary_scan/parser.py
renejal Nov 18, 2023
1b8d10f
Merge pull request #80 from kiblik/feature/parser_jfrog_xray_binary_s…
renejal Nov 19, 2023
2471106
First round of Improvements
kiblik Nov 20, 2023
b257771
Drop duplicates in component_id and full_path
kiblik Nov 20, 2023
0dc2ea7
Process per component
kiblik Nov 20, 2023
241e29d
Visual improvements
kiblik Nov 20, 2023
ce10533
Use+clean summary in Title, fix dedup, parse version, drop useless fu…
kiblik Nov 20, 2023
bcb0ecc
Update dojo/tools/jfrog_xray_on_demand_binary_scan/parser.py
renejal Nov 21, 2023
7e03894
Update dojo/tools/jfrog_xray_on_demand_binary_scan/parser.py
renejal Nov 21, 2023
57c2a83
Update dojo/tools/jfrog_xray_on_demand_binary_scan/parser.py
renejal Nov 21, 2023
65ab485
Update dojo/tools/jfrog_xray_on_demand_binary_scan/parser.py
renejal Nov 21, 2023
f49f0d1
Update dojo/tools/jfrog_xray_on_demand_binary_scan/parser.py
renejal Nov 21, 2023
73a4ba3
Update dojo/tools/jfrog_xray_on_demand_binary_scan/parser.py
renejal Nov 21, 2023
26fce7a
Merge branch 'feature/parser_jfrog_xray_binary_scan' into jfrog_more_…
renejal Nov 21, 2023
3c5a58c
Merge pull request #81 from kiblik/jfrog_more_tests
renejal Nov 21, 2023
c3347af
fix test rename class
renejal Nov 21, 2023
23b3087
Last Improvements and tests
kiblik Nov 22, 2023
9cb5893
Merge pull request #82 from kiblik/jfrog_more_tests
renejal Nov 23, 2023
ccae048
capitalization skills
renejal Nov 24, 2023
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: "JFrog Xray On Demand Binary Scan"
toc_hide: true
---
Import the JSON format for the \"JFrog Xray On Demand Binary Scan\" file. Use this importer for Xray version 3.X
--
JFrog file documentation:

https://jfrog.com/help/r/jfrog-cli/on-demand-binary-scan
10 changes: 10 additions & 0 deletions dojo/fixtures/defect_dojo_sample_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -8620,6 +8620,16 @@
}
},
{
"model": "dojo.test_type",
"pk": 149,
"fields": {
"name": "JFrog Xray On Demand Binary Scan",
"static_tool": false,
Comment thread
renejal marked this conversation as resolved.
"dynamic_tool": false,
"active": true
}
},
{
"model": "dojo.tagulous_product_tags",
"pk": 1,
"fields": {
Expand Down
2 changes: 2 additions & 0 deletions dojo/settings/settings.dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,7 @@ def saml2_attrib_map_format(dict):
'GitLab Dependency Scanning Report': ['title', 'vulnerability_ids', 'file_path', 'component_name', 'component_version'],
'SpotBugs Scan': ['cwe', 'severity', 'file_path', 'line'],
'JFrog Xray Unified Scan': ['vulnerability_ids', 'file_path', 'component_name', 'component_version'],
'JFrog Xray On Demand Binary Scan': ["title", "component_name", "component_version"],
'Scout Suite Scan': ['file_path', 'vuln_id_from_tool'], # for now we use file_path as there is no attribute for "service"
'AWS Security Hub Scan': ['unique_id_from_tool'],
'Meterian Scan': ['cwe', 'component_name', 'component_version', 'description', 'severity'],
Expand Down Expand Up @@ -1415,6 +1416,7 @@ def saml2_attrib_map_format(dict):
'Checkov Scan': DEDUPE_ALGO_HASH_CODE,
'SpotBugs Scan': DEDUPE_ALGO_HASH_CODE,
'JFrog Xray Unified Scan': DEDUPE_ALGO_HASH_CODE,
'JFrog Xray On Demand Binary Scan': DEDUPE_ALGO_HASH_CODE,
'Scout Suite Scan': DEDUPE_ALGO_HASH_CODE,
'AWS Security Hub Scan': DEDUPE_ALGO_UNIQUE_ID_FROM_TOOL,
'Meterian Scan': DEDUPE_ALGO_HASH_CODE,
Expand Down
Empty file.
190 changes: 190 additions & 0 deletions dojo/tools/jfrog_xray_on_demand_binary_scan/parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import json
import re

from cvss import CVSS3

from dojo.models import Finding


class JFrogXrayOnDemandBinaryScanParser(object):
"""jfrog_xray_scan JSON reports"""

def get_scan_types(self):
return ["JFrog Xray On Demand Binary Scan"]

def get_label_for_scan_types(self, scan_type):
return scan_type

def get_description_for_scan_types(self, scan_type):
return "Import Xray findings in JSON format."

def get_findings(self, json_output, test):
tree = json.load(json_output)
return self.get_items(tree)

def get_items(self, tree):
items = {}
for data in tree:
if "vulnerabilities" in data:
vulnerability_tree = data["vulnerabilities"]

for node in vulnerability_tree:
item_set = get_item_set(node)

for item in item_set:
unique_key = item.title + item.component_name + item.component_version
items[unique_key] = item

return list(items.values())


def get_component_name_version(name):
match = re.match(r"([a-z]+://[a-z\d\.:]+):([a-z\d\.\-]+)", name, re.IGNORECASE)
if match is None:
return name, ""
return match[1], match[2]


def get_severity(vulnerability):
if "severity" in vulnerability:
if vulnerability["severity"] == "Unknown":
severity = "Info"
else:
severity = vulnerability["severity"].title()
else:
severity = "Info"
return severity


def get_references(vulnerability):
if "references" in vulnerability:
ref = ""
references = vulnerability["references"]
for reference in references:
if reference[:2] == "- ":
ref += reference + "\n"
else:
ref += "- " + reference + "\n"
return ref
else:
return None


def get_remediation(extended_information):
remediation = ""
if "remediation" in extended_information:
remediation = "\n\n**Remediation**\n"
remediation += extended_information["remediation"] + "\n"
return remediation


def get_severity_justification(vulnerability):
severity_desc = ""
remediation = ""
extended_information = vulnerability.get("extended_information")
if extended_information:
remediation += get_remediation(extended_information)
if "short_description" in extended_information:
severity_desc += "**Short description**\n"
severity_desc += extended_information["short_description"] + "\n"
if "full_description" in extended_information:
severity_desc += "**Full description**\n"
severity_desc += extended_information["full_description"] + "\n"
if "jfrog_research_severity" in extended_information:
severity_desc += "**JFrog research severity**\n"
severity_desc += extended_information["jfrog_research_severity"] + "\n"
if "jfrog_research_severity_reasons" in extended_information:
severity_desc += "**JFrog research severity reasons**\n"
for item in extended_information["jfrog_research_severity_reasons"]:
severity_desc += item["name"] + "\n" if item.get("name") else ""
severity_desc += item["description"] + "\n" if item.get("description") else ""
Comment thread
renejal marked this conversation as resolved.
severity_desc += "_Is positive:_ " + str(item["is_positive"]).lower() + "\n" if item.get("is_positive") else ""
return severity_desc, remediation


def process_component(component):
mitigation = ""
impact = "**Impact paths**\n\n- "
fixed_versions = component.get("fixed_versions")
if fixed_versions:
mitigation = "**Versions containing a fix:**\n\n- "
mitigation = mitigation + "\n- ".join(fixed_versions)
if "impact_paths" in component:
refs = []
impact_paths_l1 = component["impact_paths"]
for impact_paths_l2 in impact_paths_l1:
for item in impact_paths_l2:
if "component_id" in item:
refs.append(item["component_id"])
if "full_path" in item:
refs.append(item["full_path"])
if refs:
impact += "\n- ".join(sorted(set(refs))) # deduplication
return mitigation, impact


def get_cve(vulnerability):
if "cves" in vulnerability:
cves = vulnerability["cves"]
return cves
return []


def get_vuln_id_from_tool(vulnerability):
if "issue_id" in vulnerability:
return vulnerability["issue_id"]
return None


def clean_title(title):
if title.startswith("Issue summary: "):
title = title[len("Issue summary: "):]
if '\n' in title:
title = title[:title.index('\n')]
return title


def get_item_set(vulnerability):
item_set = []
severity_justification, remediation = get_severity_justification(vulnerability)
severity = get_severity(vulnerability)
references = get_references(vulnerability)
vuln_id_from_tool = get_vuln_id_from_tool(vulnerability)
vulnerability_ids = list()
cvssv3 = None
cvss_v3 = "No CVSS v3 score."
# Some entries have no CVE entries, despite they exist. Example CVE-2017-1000502.
cves = get_cve(vulnerability)
if len(cves) > 0:
for item in cves:
if item.get("cve"):
vulnerability_ids.append(item.get("cve"))
if "cvss_v3_vector" in cves[0]:
cvss_v3 = cves[0]["cvss_v3_vector"]
cvssv3 = CVSS3(cvss_v3).clean_vector()

for component_name, component in vulnerability.get("components", {}).items():
component_name, component_version = get_component_name_version(component_name)
mitigation, impact = process_component(component)

title = clean_title(vulnerability["summary"])
# create the finding object
finding = Finding(
title=title,
severity_justification=severity_justification or None,
severity=severity,
description=(vulnerability["summary"]).strip(),
mitigation=(mitigation + remediation) or None,
component_name=component_name,
component_version=component_version,
impact=impact or None,
references=references or None,
static_finding=True,
dynamic_finding=False,
cvssv3=cvssv3,
vuln_id_from_tool=vuln_id_from_tool,
)
if vulnerability_ids:
finding.unsaved_vulnerability_ids = vulnerability_ids
item_set.append(finding)
return item_set
111 changes: 111 additions & 0 deletions unittests/scans/jfrog_xray_on_demand_binary_scan/many_vulns.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
[
{
"scan_id": "dd8f-4927-5db6-fb188ae8d984",
"vulnerabilities": [
{
"cves": [
{
"cve": "CVE-2017-8923",
"cvss_v2_score": "5.0",
"cvss_v2_vector": "CVSS:2.0/AV:N/AC:L/Au:N/C:N/I:N/A:P",
"cvss_v3_score": "7.5",
"cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
}
],
"summary": "Summary of test",
"severity": "High",
"components": {
"gav://org.yaml:snakeyaml:1.16": {
"fixed_versions": [
"[1.26]"
],
"impact_paths": [
[
{
"component_id": "gav://co.com.test.com"
},
{
"component_id": "gav://co.com.test.com",
"full_path": "lib/snakeyaml-1.16.jar"
}
]
]
}
},
"issue_id": "XRAY-92904",
Comment thread
renejal marked this conversation as resolved.
"references": [
"https://test.com.co"
]
},
{
"cves": [
{
"cve": "CVE-2014-0114",
"cvss_v2_score": "7.5",
"cvss_v2_vector": "CVSS:2.0/AV:N/AC:L/Au:N/C:P/I:P/A:P"
}
],
"summary": "Summary test",
"severity": "High",
"components": {
"gav://test": {
"fixed_versions": [
"[1.9.4]"
],
"impact_paths": [
[
{
"component_id": "gav://co.com.test.test:core:1.0.0-test"
},
{
"component_id": "gav://test",
"full_path": "lib/commons-beanutils-1.9.2.jar"
}
]
]
}
},
"issue_id": "XRAY-55616",
"references": [
"https://test.com.co"
]
},
{
"cves": [
{
"cvss_v2_score": "7.5",
"cvss_v2_vector": "CVSS:2.0/AV:N/AC:L/Au:N/C:P/I:P/A:P"
}
],
"summary": "Summary test",
"severity": "High",
"components": {
"test_item": {
"fixed_versions": [
"[1.2.8.RELEASE]",
"[1.3.1.RELEASE]"
],
"impact_paths": [
[
{
"component_id": "gav://co.com.test.test:core:1.0.0-test"
},
{
"component_id": "gav://test.com.co",
"full_path": "lib/test/libtest"
}
]
]
}
},
"issue_id": "XRAY-79870",
"references": [
"https://test.com.co"
]
}
],
"component_id": "gav://co.com.test.test:core:1.0.0-test",
"package_type": "Maven",
"status": "completed"
}
]
Loading