Skip to content

Commit 519b52b

Browse files
committed
Migrate debian importer to v2
Signed-off-by: Tushar Goel <tushar.goel.dav@gmail.com>
1 parent 4a24324 commit 519b52b

File tree

3 files changed

+200
-4
lines changed

3 files changed

+200
-4
lines changed

vulnerabilities/importers/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
from vulnerabilities.pipelines.v2_importers import ruby_importer as ruby_importer_v2
7676
from vulnerabilities.pipelines.v2_importers import vulnrichment_importer as vulnrichment_importer_v2
7777
from vulnerabilities.pipelines.v2_importers import xen_importer as xen_importer_v2
78+
from vulnerabilities.pipelines.v2_importers import debian_importer as debian_importer_v2
7879
from vulnerabilities.utils import create_registry
7980

8081
IMPORTERS_REGISTRY = create_registry(
@@ -103,6 +104,7 @@
103104
ruby_importer_v2.RubyImporterPipeline,
104105
epss_importer_v2.EPSSImporterPipeline,
105106
nginx_importer_v2.NginxImporterPipeline,
107+
debian_importer_v2.DebianImporterPipeline,
106108
mattermost_importer_v2.MattermostImporterPipeline,
107109
apache_tomcat_v2.ApacheTomcatImporterPipeline,
108110
nvd_importer.NVDImporterPipeline,
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
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 re
11+
from typing import Any
12+
from typing import Iterable
13+
from typing import Mapping
14+
15+
from packageurl import PackageURL
16+
from univers.version_range import DebianVersionRange
17+
from univers.versions import DebianVersion
18+
19+
from vulnerabilities.importer import AdvisoryData
20+
from vulnerabilities.importer import AffectedPackageV2
21+
from vulnerabilities.importer import ReferenceV2
22+
from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipelineV2
23+
from vulnerabilities.utils import create_weaknesses_list
24+
from vulnerabilities.utils import dedupe
25+
from vulnerabilities.utils import fetch_response
26+
from vulnerabilities.utils import get_item
27+
28+
29+
class DebianImporterPipeline(VulnerableCodeBaseImporterPipelineV2):
30+
"""ArchLinux Importer Pipeline"""
31+
32+
pipeline_id = "debian_importer_v2"
33+
spdx_license_expression = "LicenseRef-scancode-other-permissive"
34+
license_url = "https://www.debian.org/license"
35+
notice = """
36+
From: Tushar Goel <tgoel@nexb.com>
37+
Date: Thu, May 12, 2022 at 11:42 PM +00:00
38+
Subject: Usage of Debian Security Data in VulnerableCode
39+
To: <team@security.debian.org>
40+
41+
Hey,
42+
43+
We would like to integrate the debian security data in vulnerablecode
44+
[1][2] which is a FOSS db of FOSS vulnerability data. We were not able
45+
to know under which license the debian security data comes. We would
46+
be grateful to have your acknowledgement over usage of the debian
47+
security data in vulnerablecode and have some kind of licensing
48+
declaration from your side.
49+
50+
[1] - https://github.com/nexB/vulnerablecode
51+
[2] - https://github.com/nexB/vulnerablecode/pull/723
52+
53+
Regards,
54+
55+
From: Moritz Mühlenhoff <jmm@inutil.org>
56+
Date: Wed, May 17, 2022, 19:12 PM +00:00
57+
Subject: Re: Usage of Debian Security Data in VulnerableCode
58+
To: Tushar Goel <tgoel@nexb.com>
59+
Cc: <team@security.debian.org>
60+
61+
62+
Am Thu, May 12, 2022 at 05:12:48PM +0530 schrieb Tushar Goel:
63+
> Hey,
64+
>
65+
> We would like to integrate the debian security data in vulnerablecode
66+
> [1][2] which is a FOSS db of FOSS vulnerability data. We were not able
67+
> to know under which license the debian security data comes. We would
68+
> be grateful to have your acknowledgement over usage of the debian
69+
> security data in vulnerablecode and have some kind of licensing
70+
> declaration from your side.
71+
72+
We don't have a specific license, but you have our endorsemen to
73+
reuse the data by all means :-)
74+
75+
Cheers,
76+
Moritz
77+
"""
78+
79+
api_url = "https://security-tracker.debian.org/tracker/data/json"
80+
response = None
81+
82+
@classmethod
83+
def steps(cls):
84+
return (cls.collect_and_store_advisories,)
85+
86+
def get_response(self):
87+
try:
88+
response = fetch_response(self.api_url)
89+
if response:
90+
return response.json()
91+
return {}
92+
except Exception as e:
93+
self.log(f"Error fetching data from {self.api_url!r}: {e}")
94+
return {}
95+
96+
def advisories_count(self) -> int:
97+
adv_count = 0
98+
if not self.response:
99+
self.response = self.get_response()
100+
for pkg in self.response:
101+
recs = len(self.response[pkg])
102+
adv_count += recs
103+
return adv_count
104+
105+
def collect_advisories(self) -> Iterable[AdvisoryData]:
106+
if not self.response:
107+
self.response = self.get_response()
108+
for pkg_name, records in self.response.items():
109+
yield from self.parse(pkg_name, records)
110+
111+
def parse(self, pkg_name: str, records: Mapping[str, Any]) -> Iterable[AdvisoryData]:
112+
113+
for record_identifier, record in records.items():
114+
affected_versions = []
115+
fixed_versions = []
116+
117+
releases = record["releases"].items()
118+
for release_name, release_record in releases:
119+
version = get_item(release_record, "repositories", release_name)
120+
121+
if not version:
122+
self.log(
123+
f"Version not found for {release_name} in {record} in package {pkg_name}"
124+
)
125+
continue
126+
127+
purl = PackageURL(
128+
name=pkg_name,
129+
type="deb",
130+
namespace="debian",
131+
qualifiers={"distro": release_name},
132+
)
133+
134+
if release_record.get("status", "") == "resolved":
135+
fixed_versions.append(version)
136+
else:
137+
affected_versions.append(version)
138+
139+
if release_record.get("fixed_version"):
140+
fixed_versions.append(release_record["fixed_version"])
141+
142+
references = []
143+
debianbug = record.get("debianbug")
144+
if debianbug:
145+
bug_url = f"https://bugs.debian.org/cgi-bin/bugreport.cgi?bug={debianbug}"
146+
references.append(ReferenceV2(url=bug_url, reference_id=str(debianbug)))
147+
affected_versions = dedupe(affected_versions)
148+
fixed_versions = dedupe(fixed_versions)
149+
if affected_versions:
150+
affected_version_range = DebianVersionRange.from_versions(affected_versions)
151+
else:
152+
affected_version_range = None
153+
affected_packages = []
154+
for fixed_version in fixed_versions:
155+
affected_packages.append(
156+
AffectedPackageV2(
157+
package=purl,
158+
affected_version_range=affected_version_range,
159+
fixed_version_range=DebianVersionRange.from_versions([fixed_version]),
160+
)
161+
)
162+
weaknesses = get_cwe_from_debian_advisory(record)
163+
164+
yield AdvisoryData(
165+
advisory_id=f"{pkg_name}/{record_identifier}",
166+
aliases=[record_identifier],
167+
summary=record.get("description", ""),
168+
affected_packages=affected_packages,
169+
references=references,
170+
weaknesses=weaknesses,
171+
url=f"https://security-tracker.debian.org/tracker/{record_identifier}",
172+
)
173+
174+
175+
def get_cwe_from_debian_advisory(record):
176+
"""
177+
Extracts CWE ID strings from the given raw_data and returns a list of CWE IDs.
178+
179+
>>> get_cwe_from_debian_advisory({"description":"PEAR HTML_QuickForm version 3.2.14 contains an eval injection (CWE-95) vulnerability in HTML_QuickForm's getSubmitValue method, HTML_QuickForm's validate method, HTML_QuickForm_hierselect's _setOptions method, HTML_QuickForm_element's _findValue method, HTML_QuickForm_element's _prepareValue method. that can result in Possible information disclosure, possible impact on data integrity and execution of arbitrary code. This attack appear to be exploitable via A specially crafted query string could be utilised, e.g. http://www.example.com/admin/add_practice_type_id[1]=fubar%27])%20OR%20die(%27OOK!%27);%20//&mode=live. This vulnerability appears to have been fixed in 3.2.15."})
180+
[95]
181+
>>> get_cwe_from_debian_advisory({"description":"There is no WEAKNESS DATA"})
182+
[]
183+
"""
184+
description = record.get("description") or ""
185+
pattern = r"CWE-\d+"
186+
cwe_strings = re.findall(pattern, description)
187+
weaknesses = create_weaknesses_list(cwe_strings)
188+
return weaknesses

vulnerabilities/utils.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -389,10 +389,16 @@ def fetch_response(url):
389389
"""
390390
Fetch and return `response` from the `url`
391391
"""
392-
response = requests.get(url)
393-
if response.status_code == HTTPStatus.OK:
394-
return response
395-
raise Exception(f"Failed to fetch data from {url!r} with status code: {response.status_code!r}")
392+
try:
393+
response = requests.get(url)
394+
if response.status_code == HTTPStatus.OK:
395+
return response
396+
raise Exception(
397+
f"Failed to fetch data from {url!r} with status code: {response.status_code!r}"
398+
)
399+
except Exception as e:
400+
logger.error(f"Error fetching data from {url!r}: {e}")
401+
return None
396402

397403

398404
# This should be a method on PackageURL

0 commit comments

Comments
 (0)