Skip to content

Commit d3edb13

Browse files
committed
Add tests for cvelistv5-data importer
Add tests for parse_cve_v5_advisory function using vulnrichmentv2-data and cvelistv5-data Signed-off-by: ziad hany <ziadhany2016@gmail.com>
1 parent 6b850b3 commit d3edb13

16 files changed

+1603
-298
lines changed

vulnerabilities/importers/vulnrichment.py

Lines changed: 1 addition & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from vulnerabilities.utils import get_advisory_url
1616
from vulnerabilities.utils import get_cwe_id
1717
from vulnerabilities.utils import get_reference_id
18+
from vulnerabilities.utils import ssvc_calculator
1819

1920
logger = logging.getLogger(__name__)
2021

@@ -184,117 +185,3 @@ def parse_cve_advisory(raw_data, advisory_url):
184185
weaknesses=sorted(weaknesses),
185186
url=advisory_url,
186187
)
187-
188-
189-
def ssvc_calculator(ssvc_data):
190-
"""
191-
Return the ssvc vector and the decision value
192-
"""
193-
options = ssvc_data.get("options", [])
194-
timestamp = ssvc_data.get("timestamp")
195-
196-
# Extract the options into a dictionary
197-
options_dict = {k: v.lower() for option in options for k, v in option.items()}
198-
199-
# We copied the table value from this link.
200-
# https://www.cisa.gov/sites/default/files/publications/cisa-ssvc-guide%20508c.pdf
201-
202-
# Determining Mission and Well-Being Impact Value
203-
mission_well_being_table = {
204-
# (Mission Prevalence, Public Well-being Impact) : "Mission & Well-being"
205-
("minimal", "minimal"): "low",
206-
("minimal", "material"): "medium",
207-
("minimal", "irreversible"): "high",
208-
("support", "minimal"): "medium",
209-
("support", "material"): "medium",
210-
("support", "irreversible"): "high",
211-
("essential", "minimal"): "high",
212-
("essential", "material"): "high",
213-
("essential", "irreversible"): "high",
214-
}
215-
216-
if "Mission Prevalence" not in options_dict:
217-
options_dict["Mission Prevalence"] = "minimal"
218-
219-
if "Public Well-being Impact" not in options_dict:
220-
options_dict["Public Well-being Impact"] = "material"
221-
222-
options_dict["Mission & Well-being"] = mission_well_being_table[
223-
(options_dict["Mission Prevalence"], options_dict["Public Well-being Impact"])
224-
]
225-
226-
decision_key = (
227-
options_dict.get("Exploitation"),
228-
options_dict.get("Automatable"),
229-
options_dict.get("Technical Impact"),
230-
options_dict.get("Mission & Well-being"),
231-
)
232-
233-
decision_points = {
234-
"Exploitation": {"E": {"none": "N", "poc": "P", "active": "A"}},
235-
"Automatable": {"A": {"no": "N", "yes": "Y"}},
236-
"Technical Impact": {"T": {"partial": "P", "total": "T"}},
237-
"Public Well-being Impact": {"B": {"minimal": "M", "material": "A", "irreversible": "I"}},
238-
"Mission Prevalence": {"P": {"minimal": "M", "support": "S", "essential": "E"}},
239-
"Mission & Well-being": {"M": {"low": "L", "medium": "M", "high": "H"}},
240-
}
241-
242-
# Create the SSVC vector
243-
ssvc_vector = "SSVCv2/"
244-
for key, value_map in options_dict.items():
245-
options_key = decision_points.get(key)
246-
for lhs, rhs_map in options_key.items():
247-
ssvc_vector += f"{lhs}:{rhs_map.get(value_map)}/"
248-
249-
# "Decision": {"D": {"Track": "T", "Track*": "R", "Attend": "A", "Act": "C"}},
250-
decision_values = {"Track": "T", "Track*": "R", "Attend": "A", "Act": "C"}
251-
252-
decision_lookup = {
253-
("none", "no", "partial", "low"): "Track",
254-
("none", "no", "partial", "medium"): "Track",
255-
("none", "no", "partial", "high"): "Track",
256-
("none", "no", "total", "low"): "Track",
257-
("none", "no", "total", "medium"): "Track",
258-
("none", "no", "total", "high"): "Track*",
259-
("none", "yes", "partial", "low"): "Track",
260-
("none", "yes", "partial", "medium"): "Track",
261-
("none", "yes", "partial", "high"): "Attend",
262-
("none", "yes", "total", "low"): "Track",
263-
("none", "yes", "total", "medium"): "Track",
264-
("none", "yes", "total", "high"): "Attend",
265-
("poc", "no", "partial", "low"): "Track",
266-
("poc", "no", "partial", "medium"): "Track",
267-
("poc", "no", "partial", "high"): "Track*",
268-
("poc", "no", "total", "low"): "Track",
269-
("poc", "no", "total", "medium"): "Track*",
270-
("poc", "no", "total", "high"): "Attend",
271-
("poc", "yes", "partial", "low"): "Track",
272-
("poc", "yes", "partial", "medium"): "Track",
273-
("poc", "yes", "partial", "high"): "Attend",
274-
("poc", "yes", "total", "low"): "Track",
275-
("poc", "yes", "total", "medium"): "Track*",
276-
("poc", "yes", "total", "high"): "Attend",
277-
("active", "no", "partial", "low"): "Track",
278-
("active", "no", "partial", "medium"): "Track",
279-
("active", "no", "partial", "high"): "Attend",
280-
("active", "no", "total", "low"): "Track",
281-
("active", "no", "total", "medium"): "Attend",
282-
("active", "no", "total", "high"): "Act",
283-
("active", "yes", "partial", "low"): "Attend",
284-
("active", "yes", "partial", "medium"): "Attend",
285-
("active", "yes", "partial", "high"): "Act",
286-
("active", "yes", "total", "low"): "Attend",
287-
("active", "yes", "total", "medium"): "Act",
288-
("active", "yes", "total", "high"): "Act",
289-
}
290-
291-
decision = decision_lookup.get(decision_key, "")
292-
293-
if decision:
294-
ssvc_vector += f"D:{decision_values.get(decision)}/"
295-
296-
if timestamp:
297-
timestamp_formatted = dateparser.parse(timestamp).strftime("%Y-%m-%dT%H:%M:%SZ")
298-
299-
ssvc_vector += f"{timestamp_formatted}/"
300-
return ssvc_vector, decision
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#
2+
# Copyright (c) nexB Inc. and others. All rights reserved.
3+
# VulnerableCode is a trademark of nexB Inc.
4+
# SPDX-License-Identifier: Apache-2.0
5+
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
6+
# See https://github.com/aboutcode-org/vulnerablecode for support or download.
7+
# See https://aboutcode.org for more information about nexB OSS projects.
8+
#
9+
10+
import json
11+
import os
12+
from unittest import TestCase
13+
14+
from vulnerabilities.importers.cve_schema import parse_cve_v5_advisory
15+
from vulnerabilities.tests import util_tests
16+
17+
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
18+
TEST_DATA = os.path.join(BASE_DIR, "test_data/cve_schema")
19+
20+
21+
class TestCVESchemaV5(TestCase):
22+
def test_to_advisories1(self):
23+
with open(os.path.join(TEST_DATA, "vulnrichment-data1.json")) as f:
24+
mock_response = json.load(f)
25+
expected_file = os.path.join(TEST_DATA, "vulnrichment-data1-expected.json")
26+
imported_data = parse_cve_v5_advisory(mock_response, advisory_url="https://test.com")
27+
result = imported_data.to_dict()
28+
util_tests.check_results_against_json(result, expected_file)
29+
30+
def test_to_advisorie2(self):
31+
with open(os.path.join(TEST_DATA, "vulnrichment-data2.json")) as f:
32+
mock_response = json.load(f)
33+
expected_file = os.path.join(TEST_DATA, "vulnrichment-data2-expected.json")
34+
imported_data = parse_cve_v5_advisory(mock_response, advisory_url="https://test.com")
35+
result = imported_data.to_dict()
36+
util_tests.check_results_against_json(result, expected_file)
37+
38+
def test_to_advisorie3(self):
39+
with open(os.path.join(TEST_DATA, "vulnrichment-data3.json")) as f:
40+
mock_response = json.load(f)
41+
expected_file = os.path.join(TEST_DATA, "vulnrichment-data3-expected.json")
42+
imported_data = parse_cve_v5_advisory(mock_response, advisory_url="https://test.com")
43+
result = imported_data.to_dict()
44+
util_tests.check_results_against_json(result, expected_file)
45+
46+
def test_to_advisories4(self):
47+
with open(os.path.join(TEST_DATA, "cvelistv5-data1.json")) as f:
48+
mock_response = json.load(f)
49+
expected_file = os.path.join(TEST_DATA, "cvelistv5-data1-expected.json")
50+
imported_data = parse_cve_v5_advisory(mock_response, advisory_url="https://test.com")
51+
result = imported_data.to_dict()
52+
util_tests.check_results_against_json(result, expected_file)
53+
54+
def test_to_advisorie5(self):
55+
with open(os.path.join(TEST_DATA, "cvelistv5-data2.json")) as f:
56+
mock_response = json.load(f)
57+
expected_file = os.path.join(TEST_DATA, "cvelistv5-data2-expected.json")
58+
imported_data = parse_cve_v5_advisory(mock_response, advisory_url="https://test.com")
59+
result = imported_data.to_dict()
60+
util_tests.check_results_against_json(result, expected_file)
61+
62+
def test_to_advisorie6(self):
63+
with open(os.path.join(TEST_DATA, "cvelistv5-data3.json")) as f:
64+
mock_response = json.load(f)
65+
expected_file = os.path.join(TEST_DATA, "cvelistv5-data3-expected.json")
66+
imported_data = parse_cve_v5_advisory(mock_response, advisory_url="https://test.com")
67+
result = imported_data.to_dict()
68+
util_tests.check_results_against_json(result, expected_file)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"advisory_id": "CVE-2025-0950",
3+
"aliases": [],
4+
"summary": "A vulnerability was found in itsourcecode Tailoring Management System 1.0 and classified as critical. This issue affects some unknown processing of the file staffview.php. The manipulation of the argument staffid leads to sql injection. The attack may be initiated remotely. The exploit has been disclosed to the public and may be used.",
5+
"affected_packages": [],
6+
"references_v2": [
7+
{
8+
"reference_id": "?id.294305",
9+
"reference_type": "advisory",
10+
"url": "https://vuldb.com/?id.294305"
11+
},
12+
{
13+
"reference_id": "?ctiid.294305",
14+
"reference_type": "other",
15+
"url": "https://vuldb.com/?ctiid.294305"
16+
},
17+
{
18+
"reference_id": "7",
19+
"reference_type": "bug",
20+
"url": "https://github.com/magic2353112890/cve/issues/7"
21+
},
22+
{
23+
"reference_id": "itsourcecode.com",
24+
"reference_type": "other",
25+
"url": "https://itsourcecode.com/"
26+
}
27+
],
28+
"severities": [
29+
{
30+
"system": "cvssv4",
31+
"value": 5.3,
32+
"scoring_elements": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N"
33+
},
34+
{
35+
"system": "cvssv3.1",
36+
"value": 6.3,
37+
"scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L"
38+
},
39+
{
40+
"system": "cvssv3",
41+
"value": 6.3,
42+
"scoring_elements": "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L"
43+
},
44+
{
45+
"system": "cvssv2",
46+
"value": 6.5,
47+
"scoring_elements": "AV:N/AC:L/Au:S/C:P/I:P/A:P"
48+
},
49+
{
50+
"system": "ssvc",
51+
"value": "Track",
52+
"scoring_elements": "SSVCv2/E:P/A:N/T:P/P:M/B:A/M:M/D:T/2025-02-03T17:14:26Z/"
53+
}
54+
],
55+
"date_published": "2025-02-01T20:00:12.431000+00:00",
56+
"weaknesses": [
57+
74,
58+
89
59+
],
60+
"url": "https://test.com"
61+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"advisory_id": "CVE-2024-0906",
3+
"aliases": [],
4+
"summary": "The f(x) Private Site plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 1.2.1 via the API. This makes it possible for unauthenticated attackers to obtain page and post contents of a site protected with this plugin.",
5+
"affected_packages": [],
6+
"references_v2": [
7+
{
8+
"reference_id": "79c3abc6-68fa-4c51-88fa-03ab7d26cc4c?source=cve",
9+
"reference_type": "other",
10+
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/79c3abc6-68fa-4c51-88fa-03ab7d26cc4c?source=cve"
11+
},
12+
{
13+
"reference_id": "fx-private-site",
14+
"reference_type": "other",
15+
"url": "https://wordpress.org/plugins/fx-private-site/"
16+
}
17+
],
18+
"severities": [
19+
{
20+
"system": "cvssv3.1",
21+
"value": 5.3,
22+
"scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N"
23+
},
24+
{
25+
"system": "ssvc",
26+
"value": "Track",
27+
"scoring_elements": "SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2024-03-12T18:42:41Z/"
28+
}
29+
],
30+
"date_published": "2024-03-12T08:34:17.481000+00:00",
31+
"weaknesses": [
32+
200
33+
],
34+
"url": "https://test.com"
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"advisory_id": "CVE-2023-0710",
3+
"aliases": [],
4+
"summary": "The Metform Elementor Contact Form Builder for WordPress is vulnerable to Cross-Site Scripting by using the 'fname' attribute of the 'mf_thankyou' shortcode to echo unescaped form submissions in versions up to, and including, 3.3.0. This allows authenticated attackers, with contributor-level permissions or above, to inject arbitrary web scripts in pages that will execute when the victim visits a a page containing the shortcode when the submission id is present in the query string. Note that getting the JavaScript to execute requires user interaction as the victim must visit a crafted link with the form entry id, but the script itself is stored in the site database. Additionally this requires successful payment, increasing the complexity.",
5+
"affected_packages": [],
6+
"references_v2": [
7+
{
8+
"reference_id": "89a98053-33c7-4e75-87a1-0f483a990641?source=cve",
9+
"reference_type": "other",
10+
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/89a98053-33c7-4e75-87a1-0f483a990641?source=cve"
11+
},
12+
{
13+
"reference_id": "shortcode.php?rev=2845078",
14+
"reference_type": "other",
15+
"url": "https://plugins.trac.wordpress.org/browser/metform/trunk/base/shortcode.php?rev=2845078"
16+
}
17+
],
18+
"severities": [
19+
{
20+
"system": "cvssv3.1",
21+
"value": 4.9,
22+
"scoring_elements": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:N"
23+
},
24+
{
25+
"system": "ssvc",
26+
"value": "Track",
27+
"scoring_elements": "SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2024-11-23T13:13:32Z/"
28+
}
29+
],
30+
"date_published": "2023-06-09T05:33:23.543000+00:00",
31+
"weaknesses": [
32+
79
33+
],
34+
"url": "https://test.com"
35+
}
Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,35 @@
11
{
2-
"aliases": [
3-
"CVE-2024-3018"
4-
],
2+
"advisory_id": "CVE-2024-3018",
3+
"aliases": [],
54
"summary": "The Essential Addons for Elementor plugin for WordPress is vulnerable to PHP Object Injection in all versions up to, and including, 5.9.13 via deserialization of untrusted input from the 'error_resetpassword' attribute of the \"Login | Register Form\" widget (disabled by default). This makes it possible for authenticated attackers, with author-level access and above, to inject a PHP Object. If a POP chain is present via an additional plugin or theme installed on the target system, it could allow the attacker to delete arbitrary files, retrieve sensitive data, or execute code.",
65
"affected_packages": [],
7-
"references": [
6+
"references_v2": [
87
{
98
"reference_id": "342049e5-834e-4867-8174-01ca7bb0caa2?source=cve",
109
"reference_type": "other",
11-
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/342049e5-834e-4867-8174-01ca7bb0caa2?source=cve",
12-
"severities": [
13-
{
14-
"system": "cvssv3.1",
15-
"value": 8.8,
16-
"scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
17-
},
18-
{
19-
"system": "ssvc",
20-
"value": "Track",
21-
"scoring_elements": "SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2024-04-01T17:33:59Z/"
22-
}
23-
]
10+
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/342049e5-834e-4867-8174-01ca7bb0caa2?source=cve"
2411
},
2512
{
2613
"reference_id": "essential-addons-for-elementor-lite",
2714
"reference_type": "other",
28-
"url": "https://plugins.trac.wordpress.org/changeset/3060417/essential-addons-for-elementor-lite",
29-
"severities": [
30-
{
31-
"system": "cvssv3.1",
32-
"value": 8.8,
33-
"scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
34-
},
35-
{
36-
"system": "ssvc",
37-
"value": "Track",
38-
"scoring_elements": "SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2024-04-01T17:33:59Z/"
39-
}
40-
]
15+
"url": "https://plugins.trac.wordpress.org/changeset/3060417/essential-addons-for-elementor-lite"
16+
}
17+
],
18+
"severities": [
19+
{
20+
"system": "cvssv3.1",
21+
"value": 8.8,
22+
"scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
23+
},
24+
{
25+
"system": "ssvc",
26+
"value": "Track",
27+
"scoring_elements": "SSVCv2/E:N/A:N/T:P/P:M/B:A/M:M/D:T/2024-04-01T17:33:59Z/"
4128
}
4229
],
4330
"date_published": "2024-03-30T11:17:25.675000+00:00",
4431
"weaknesses": [
4532
502
4633
],
47-
"url": "http://test.com"
34+
"url": "https://test.com"
4835
}

0 commit comments

Comments
 (0)