Skip to content

Commit 94550ee

Browse files
committed
Add code commit for VCS URLs that we support (github, bitbucket anf gitlab) for unsupported store them as references.
Add a test for OSV Signed-off-by: ziad hany <[email protected]>
1 parent 5c35342 commit 94550ee

16 files changed

+751
-19
lines changed

vulnerabilities/importer.py

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ def __post_init__(self):
210210
raise ValueError("Commit must have a non-empty commit_hash.")
211211

212212
if not is_commit(self.commit_hash):
213-
raise ValueError("Commit must be a valid a commit_hash.")
213+
raise ValueError(f"Commit must be a valid a commit_hash: {self.commit_hash}.")
214214

215215
if not self.vcs_url:
216216
raise ValueError("Commit must have a non-empty vcs_url.")
@@ -426,8 +426,8 @@ def __post_init__(self):
426426
or self.fixed_by_commits
427427
):
428428
raise ValueError(
429-
f"Affected Package {self.package!r} should have either fixed version range or an "
430-
"affected version range."
429+
f"Affected package {self.package!r} must have either a fixed version range, "
430+
"an affected version range, affected commits, or fixed commits."
431431
)
432432

433433
def __lt__(self, other):
@@ -456,12 +456,8 @@ def to_dict(self):
456456
"package": purl_to_dict(self.package),
457457
"affected_version_range": affected_version_range,
458458
"fixed_version_range": fixed_version_range,
459-
"affected_by_commits": [
460-
affected_by_commit.to_dict() for affected_by_commit in self.affected_by_commits
461-
],
462-
"fixed_by_commits": [
463-
fixed_by_commit.to_dict() for fixed_by_commit in self.fixed_by_commits
464-
],
459+
"affected_by_commits": [commit.to_dict() for commit in self.affected_by_commits],
460+
"fixed_by_commits": [commit.to_dict() for commit in self.fixed_by_commits],
465461
}
466462

467463
@classmethod
@@ -497,12 +493,9 @@ def from_dict(cls, affected_pkg: dict):
497493
affected_version_range=affected_version_range,
498494
fixed_version_range=fixed_version_range,
499495
affected_by_commits=[
500-
CodeCommitData.from_dict(affected_by_commit)
501-
for affected_by_commit in affected_by_commits
502-
],
503-
fixed_by_commits=[
504-
CodeCommitData.from_dict(fixed_by_commit) for fixed_by_commit in fixed_by_commits
496+
CodeCommitData.from_dict(commit) for commit in affected_by_commits
505497
],
498+
fixed_by_commits=[CodeCommitData.from_dict(commit) for commit in fixed_by_commits],
506499
)
507500

508501

vulnerabilities/importers/osv.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import json
1111
import logging
1212
from typing import Iterable
13+
from typing import Iterator
1314
from typing import List
1415
from typing import Optional
1516
from typing import Tuple
@@ -18,10 +19,12 @@
1819
from cvss.exceptions import CVSS3MalformedError
1920
from cvss.exceptions import CVSS4MalformedError
2021
from packageurl import PackageURL
22+
from packageurl.contrib.url2purl import url2purl
2123
from univers.version_range import RANGE_CLASS_BY_SCHEMES
2224
from univers.versions import InvalidVersion
2325
from univers.versions import SemverVersion
2426
from univers.versions import Version
27+
from websockets.version import commit
2528

2629
from vulnerabilities.importer import AdvisoryData
2730
from vulnerabilities.importer import AffectedPackage
@@ -49,6 +52,8 @@
4952
"cargo": "cargo",
5053
}
5154

55+
SUPPORTED_VCS_TYPES = {"github", "bitbucket", "gitlab"}
56+
5257

5358
def parse_advisory_data(
5459
raw_data: dict, supported_ecosystems, advisory_url: str
@@ -164,11 +169,30 @@ def parse_advisory_data_v2(
164169
get_fixed_version_range(fixed_versions, purl.type) if fixed_versions else None
165170
)
166171

172+
if not purl and (affected_by_commits or fixed_by_commits):
173+
for code_commit in affected_by_commits + fixed_by_commits:
174+
purl = url2purl(code_commit.vcs_url)
175+
if purl.type not in SUPPORTED_VCS_TYPES:
176+
logger.error(
177+
f"Storing commit_hash:{code_commit.commit_hash}, code_commit:{code_commit.vcs_url} as reference, not creating CodeCommits."
178+
)
179+
ref = ReferenceV2(
180+
reference_id=code_commit.commit_hash,
181+
reference_type="commit",
182+
url=code_commit.vcs_url,
183+
)
184+
references.append(ref)
185+
186+
affected_by_commits, fixed_by_commits = [], []
187+
167188
if not purl or purl.type not in supported_ecosystems:
168189
logger.error(f"Unsupported package type: {purl!r} in OSV: {advisory_id!r}")
169-
continue
190+
# Ignore version ranges not associated with the same supported_ecosystems.
191+
fixed_version_range, affected_version_range = None, None
170192

171-
if fixed_version_range or affected_version_range or fixed_by_commits or affected_by_commits:
193+
if purl and (
194+
fixed_version_range or affected_version_range or fixed_by_commits or affected_by_commits
195+
):
172196
affected_packages.append(
173197
AffectedPackageV2(
174198
package=purl,
@@ -200,7 +224,7 @@ def parse_advisory_data_v2(
200224
)
201225

202226

203-
def extract_introduced_and_fixed(ranges) -> Tuple[List[str], List[str]]:
227+
def extract_introduced_and_fixed(ranges) -> Iterator[Tuple[Optional[str], Optional[str]]]:
204228
"""
205229
Return pairs of introduced and fixed versions or commit hashes given a ``ranges``
206230
mapping of OSV data.

vulnerabilities/tests/pipelines/v2_importers/test_oss_fuzz_v2.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@
66
# See https://github.com/aboutcode-org/vulnerablecode for support or download.
77
# See https://aboutcode.org for more information about nexB OSS projects.
88
#
9+
import os
910
from unittest import mock
1011

1112
import pytest
13+
import saneyaml
1214
import yaml
1315

14-
from vulnerabilities.importer import AdvisoryData
16+
from vulnerabilities.importers.osv import parse_advisory_data_v2
1517
from vulnerabilities.pipelines.v2_importers.oss_fuzz import OSSFuzzImporterPipeline
18+
from vulnerabilities.tests import util_tests
19+
20+
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
21+
TEST_DATA = os.path.join(BASE_DIR, "../../test_data/oss_fuzz/v2")
1622

1723

1824
@pytest.mark.django_db
@@ -49,3 +55,24 @@ def test_advisories_count(tmp_path):
4955
pipeline.vcs_response.dest_dir = tmp_path
5056

5157
assert pipeline.advisories_count() == 2
58+
59+
60+
class TestOSSFuzzImporter:
61+
@pytest.mark.parametrize(
62+
"input_file,expected_file",
63+
[
64+
("oss-fuzz-data1.yaml", "oss-fuzz-data-1.yaml-expected.json"),
65+
("oss-fuzz-data2.yaml", "oss-fuzz-data-2.yaml-expected.json"),
66+
("oss-fuzz-data3.yaml", "oss-fuzz-data-3.yaml-expected.json"),
67+
("oss-fuzz-data4.yaml", "oss-fuzz-data-4.yaml-expected.json"),
68+
],
69+
)
70+
def test_to_advisories1(self, input_file, expected_file):
71+
with open(os.path.join(TEST_DATA, input_file)) as f:
72+
mock_response = saneyaml.load(f)
73+
expected_file = os.path.join(TEST_DATA, expected_file)
74+
imported_data = parse_advisory_data_v2(
75+
mock_response, "oss-fuzz", advisory_url="https://test.com", advisory_text=mock_response
76+
)
77+
result = imported_data.to_dict()
78+
util_tests.check_results_against_json(result, expected_file)

vulnerabilities/tests/pipelines/v2_importers/test_pypa_importer_pipeline_v2.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@
66
# See https://github.com/aboutcode-org/vulnerablecode for support or download.
77
# See https://aboutcode.org for more information about nexB OSS projects.
88
#
9-
9+
import os
1010
from unittest.mock import MagicMock
1111
from unittest.mock import patch
1212

1313
import pytest
1414
import saneyaml
1515

1616
from vulnerabilities.importer import AdvisoryData
17+
from vulnerabilities.importers.osv import parse_advisory_data_v2
18+
from vulnerabilities.tests import util_tests
1719

1820

1921
@pytest.fixture
@@ -171,3 +173,26 @@ def test_advisories_count_empty(mock_vcs_response, mock_fetch_via_vcs):
171173
# Test that advisories_count returns 0 for an empty directory
172174
count = pipeline.advisories_count()
173175
assert count == 0
176+
177+
178+
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
179+
TEST_DATA = os.path.join(BASE_DIR, "../../test_data/pypa/v2")
180+
181+
182+
class TestOSSFuzzImporter:
183+
@pytest.mark.parametrize(
184+
"input_file,expected_file",
185+
[
186+
("pypa-1.yaml", "pypa-expected-1.json"),
187+
("pypa-2.yaml", "pypa-expected-2.json"),
188+
],
189+
)
190+
def test_to_advisories1(self, input_file, expected_file):
191+
with open(os.path.join(TEST_DATA, input_file)) as f:
192+
mock_response = saneyaml.load(f)
193+
expected_file = os.path.join(TEST_DATA, expected_file)
194+
imported_data = parse_advisory_data_v2(
195+
mock_response, "pypi", advisory_url="https://test.com", advisory_text=mock_response
196+
)
197+
result = imported_data.to_dict()
198+
util_tests.check_results_against_json(result, expected_file)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"advisory_id": "OSV-2021-933",
3+
"aliases": [],
4+
"summary": "Heap-buffer-overflow in print_mac\nOSS-Fuzz report: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=35887\n\n```\nCrash type: Heap-buffer-overflow WRITE 4\nCrash state:\nprint_mac\nlog_packet\ndhcp_reply\n```",
5+
"affected_packages": [],
6+
"references_v2": [
7+
{
8+
"reference_id": "",
9+
"reference_type": "",
10+
"url": "https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=35887"
11+
},
12+
{
13+
"reference_id": "96f6444958c29a670f4254722d787f328153605c",
14+
"reference_type": "commit",
15+
"url": "git://thekelleys.org.uk/dnsmasq.git"
16+
},
17+
{
18+
"reference_id": "d242cbffa4f20c9f7472f79b3a9e47008b6fe77c",
19+
"reference_type": "commit",
20+
"url": "git://thekelleys.org.uk/dnsmasq.git"
21+
}
22+
],
23+
"severities": [],
24+
"date_published": "2021-07-08T00:01:26.369555+00:00",
25+
"weaknesses": [],
26+
"url": "https://test.com"
27+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"advisory_id": "OSV-2022-145",
3+
"aliases": [],
4+
"summary": "Heap-buffer-overflow in print_mac\nOSS-Fuzz report: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=44581\n\n```\nCrash type: Heap-buffer-overflow WRITE 4\nCrash state:\nprint_mac\nlog_packet\ndhcp_reply\n```",
5+
"affected_packages": [
6+
{
7+
"package": {
8+
"type": "generic",
9+
"namespace": "",
10+
"name": "dnsmasq",
11+
"version": "",
12+
"qualifiers": "",
13+
"subpath": ""
14+
},
15+
"affected_version_range": null,
16+
"fixed_version_range": null,
17+
"affected_by_commits": [
18+
{
19+
"commit_hash": "e426c2d3bc182d790f83039b77a09d55230ca71f",
20+
"vcs_url": "git://thekelleys.org.uk/dnsmasq.git",
21+
"commit_author": null,
22+
"commit_message": null,
23+
"commit_diff": null,
24+
"commit_date": null
25+
}
26+
],
27+
"fixed_by_commits": [
28+
{
29+
"commit_hash": "03345ecefeb0d82e3c3a4c28f27c3554f0611b39",
30+
"vcs_url": "git://thekelleys.org.uk/dnsmasq.git",
31+
"commit_author": null,
32+
"commit_message": null,
33+
"commit_diff": null,
34+
"commit_date": null
35+
}
36+
]
37+
}
38+
],
39+
"references_v2": [
40+
{
41+
"reference_id": "",
42+
"reference_type": "",
43+
"url": "https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=44581"
44+
}
45+
],
46+
"severities": [],
47+
"date_published": "2022-02-13T00:01:27.883603+00:00",
48+
"weaknesses": [],
49+
"url": "https://test.com"
50+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"advisory_id": "OSV-2018-194",
3+
"aliases": [],
4+
"summary": "Heap-use-after-free in r_core_task_decref\nOSS-Fuzz report: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11359\n\n```\nCrash type: Heap-use-after-free READ 8\nCrash state:\nr_core_task_decref\nr_list_delete\nr_list_purge\n```",
5+
"affected_packages": [
6+
{
7+
"package": {
8+
"type": "github",
9+
"namespace": "radare",
10+
"name": "radare2",
11+
"version": "",
12+
"qualifiers": "",
13+
"subpath": ""
14+
},
15+
"affected_version_range": null,
16+
"fixed_version_range": null,
17+
"affected_by_commits": [
18+
{
19+
"commit_hash": "77d80106e65ed4ff3ba5faf568b078648faed94f",
20+
"vcs_url": "https://github.com/radare/radare2",
21+
"commit_author": null,
22+
"commit_message": null,
23+
"commit_diff": null,
24+
"commit_date": null
25+
}
26+
],
27+
"fixed_by_commits": [
28+
{
29+
"commit_hash": "5783cf42c40aaed9b9180ae7069c7a60ea86dc45",
30+
"vcs_url": "https://github.com/radare/radare2",
31+
"commit_author": null,
32+
"commit_message": null,
33+
"commit_diff": null,
34+
"commit_date": null
35+
}
36+
]
37+
}
38+
],
39+
"references_v2": [
40+
{
41+
"reference_id": "",
42+
"reference_type": "",
43+
"url": "https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11359"
44+
}
45+
],
46+
"severities": [],
47+
"date_published": "2021-01-13T00:01:20.948805+00:00",
48+
"weaknesses": [],
49+
"url": "https://test.com"
50+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"advisory_id": "OSV-2018-194",
3+
"aliases": [],
4+
"summary": "Heap-use-after-free in r_core_task_decref\nOSS-Fuzz report: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11359\n\n```\nCrash type: Heap-use-after-free READ 8\nCrash state:\nr_core_task_decref\nr_list_delete\nr_list_purge\n```",
5+
"affected_packages": [
6+
{
7+
"package": {
8+
"type": "github",
9+
"namespace": "radare",
10+
"name": "radare2",
11+
"version": "",
12+
"qualifiers": "",
13+
"subpath": ""
14+
},
15+
"affected_version_range": null,
16+
"fixed_version_range": null,
17+
"affected_by_commits": [
18+
{
19+
"commit_hash": "77d80106e65ed4ff3ba5faf568b078648faed94f",
20+
"vcs_url": "https://github.com/radare/radare2",
21+
"commit_author": null,
22+
"commit_message": null,
23+
"commit_diff": null,
24+
"commit_date": null
25+
}
26+
],
27+
"fixed_by_commits": [
28+
{
29+
"commit_hash": "5783cf42c40aaed9b9180ae7069c7a60ea86dc45",
30+
"vcs_url": "https://github.com/radare/radare2",
31+
"commit_author": null,
32+
"commit_message": null,
33+
"commit_diff": null,
34+
"commit_date": null
35+
}
36+
]
37+
}
38+
],
39+
"references_v2": [
40+
{
41+
"reference_id": "",
42+
"reference_type": "",
43+
"url": "https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11359"
44+
}
45+
],
46+
"severities": [],
47+
"date_published": "2021-01-13T00:01:20.948805+00:00",
48+
"weaknesses": [],
49+
"url": "https://test.com"
50+
}

0 commit comments

Comments
 (0)