Skip to content

Commit d1686db

Browse files
authored
Merge pull request #748 from TG1999/first_patched_version_github
Add firstPatchedVersion in github API
2 parents 6ec2e9e + 0f3404b commit d1686db

File tree

16 files changed

+89
-51
lines changed

16 files changed

+89
-51
lines changed

vulnerabilities/importers/github.py

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from dateutil import parser as dateparser
3131
from django.db.models.query import QuerySet
3232
from packageurl import PackageURL
33+
from univers.version_range import RANGE_CLASS_BY_SCHEMES
3334
from univers.version_range import build_range_from_github_advisory_constraint
3435

3536
from vulnerabilities import severity_systems
@@ -48,6 +49,7 @@
4849
from vulnerabilities.package_managers import VersionAPI
4950
from vulnerabilities.package_managers import get_api_package_name
5051
from vulnerabilities.utils import AffectedPackage as LegacyAffectedPackage
52+
from vulnerabilities.utils import dedupe
5153
from vulnerabilities.utils import get_affected_packages_by_patched_package
5254
from vulnerabilities.utils import get_item
5355
from vulnerabilities.utils import nearest_patched_package
@@ -153,6 +155,9 @@
153155
severity
154156
publishedAt
155157
}
158+
firstPatchedVersion{
159+
identifier
160+
}
156161
package {
157162
name
158163
}
@@ -236,60 +241,64 @@ def process_response(resp: dict, package_type: str) -> Iterable[AdvisoryData]:
236241
return
237242

238243
for vulnerability in vulnerabilities:
244+
aliases = []
239245
affected_packages = []
240-
aliases = set()
241246
github_advisory = get_item(vulnerability, "node")
242247
if not github_advisory:
243248
logger.error(f"No node found in {vulnerability!r}")
244249
continue
245250

246-
name = get_item(github_advisory, "package", "name")
247-
if not name:
248-
logger.error(f"No name found in {github_advisory!r}")
249-
continue
250-
251-
purl = get_purl(pkg_type=package_type, github_name=name)
252-
if not purl:
253-
continue
254-
255-
vulnerable_range = get_item(github_advisory, "vulnerableVersionRange")
256-
if not vulnerable_range:
257-
logger.error(f"No affected range found in {github_advisory!r}")
258-
continue
259-
260-
affected_range = None
261-
try:
262-
affected_range = build_range_from_github_advisory_constraint(
263-
package_type, vulnerable_range
264-
)
265-
except InvalidVersionRange:
266-
logger.error(f"Could not parse affected range {vulnerable_range!r}")
267-
continue
268-
269-
if affected_range != NotImplementedError:
270-
affected_packages.append(
271-
AffectedPackage(
272-
package=purl,
273-
affected_version_range=affected_range,
274-
)
275-
)
276-
277251
advisory = get_item(github_advisory, "advisory")
278252
if not advisory:
279253
logger.error(f"No advisory found in {github_advisory!r}")
280254
continue
281255

256+
summary = get_item(advisory, "summary") or ""
257+
282258
references = get_item(advisory, "references") or []
283259
if references:
284260
urls = (ref["url"] for ref in references)
285261
references = [Reference.from_url(u) for u in urls]
286262

287-
summary = get_item(advisory, "summary")
263+
date_published = get_item(advisory, "publishedAt")
264+
if date_published:
265+
date_published = dateparser.parse(date_published)
266+
267+
name = get_item(github_advisory, "package", "name")
268+
if name:
269+
purl = get_purl(pkg_type=package_type, github_name=name)
270+
if purl:
271+
affected_range = get_item(github_advisory, "vulnerableVersionRange")
272+
fixed_version = get_item(github_advisory, "firstPatchedVersion", "identifier")
273+
if affected_range:
274+
try:
275+
affected_range = build_range_from_github_advisory_constraint(
276+
package_type, affected_range
277+
)
278+
except InvalidVersionRange as e:
279+
logger.error(f"Could not parse affected range {affected_range!r} {e!r}")
280+
affected_range = None
281+
if fixed_version:
282+
try:
283+
fixed_version = RANGE_CLASS_BY_SCHEMES[package_type].version_class(
284+
fixed_version
285+
)
286+
except Exception as e:
287+
logger.error(f"Invalid fixed version {fixed_version!r} {e!r}")
288+
fixed_version = None
289+
if affected_range or fixed_version:
290+
affected_packages.append(
291+
AffectedPackage(
292+
package=purl,
293+
affected_version_range=affected_range,
294+
fixed_version=fixed_version,
295+
)
296+
)
288297
identifiers = get_item(advisory, "identifiers") or []
289298
for identifier in identifiers:
290299
value = identifier["value"]
291300
identifier_type = identifier["type"]
292-
aliases.add(value)
301+
aliases.append(value)
293302
# attach the GHSA with severity score
294303
if identifier_type == "GHSA":
295304
# Each Node has only one GHSA, hence exit after attaching
@@ -310,12 +319,8 @@ def process_response(resp: dict, package_type: str) -> Iterable[AdvisoryData]:
310319
else:
311320
logger.error(f"Unknown identifier type {identifier_type!r} and value {value!r}")
312321

313-
date_published = get_item(advisory, "publishedAt")
314-
if date_published:
315-
date_published = dateparser.parse(date_published)
316-
317322
yield AdvisoryData(
318-
aliases=sorted(list(aliases)),
323+
aliases=sorted(dedupe(aliases)),
319324
summary=summary,
320325
references=references,
321326
affected_packages=affected_packages,

vulnerabilities/package_managers.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -395,9 +395,6 @@ class ComposerVersionAPI(VersionAPI):
395395
package_type = "composer"
396396

397397
def fetch(self, pkg: str) -> Iterable[PackageVersion]:
398-
if "/" not in pkg:
399-
raise Exception(f"Composer package: {pkg!r} does not have a vendor/name structure.")
400-
401398
response = get_response(url=f"https://repo.packagist.org/p/{pkg}.json")
402399
if response:
403400
yield from self.extract_versions(response, pkg)

vulnerabilities/tests/test_data/github_api/composer-expected.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@
163163
"subpath": null
164164
},
165165
"affected_version_range": "vers:composer/<22.1.0",
166-
"fixed_version": null
166+
"fixed_version": "22.1.0"
167167
}
168168
],
169169
"references": [

vulnerabilities/tests/test_data/github_api/composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@
150150
"package": {
151151
"name": "librenms/librenms"
152152
},
153+
"firstPatchedVersion": {
154+
"identifier" :"22.1.0"
155+
},
153156
"vulnerableVersionRange": "< 22.1.0"
154157
}
155158
}

vulnerabilities/tests/test_data/github_api/gem-expected.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"subpath": null
1717
},
1818
"affected_version_range": "vers:gem/<=1.3.1",
19-
"fixed_version": null
19+
"fixed_version": "1.3.2"
2020
}
2121
],
2222
"references": [

vulnerabilities/tests/test_data/github_api/gem.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@
5757
"package": {
5858
"name": "webrick"
5959
},
60+
"firstPatchedVersion": {
61+
"identifier" :"1.3.2"
62+
},
6063
"vulnerableVersionRange": "<= 1.3.1"
6164
}
6265
},

vulnerabilities/tests/test_data/github_api/golang-expected.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"subpath": null
1717
},
1818
"affected_version_range": "vers:golang/<1.3.3",
19-
"fixed_version": null
19+
"fixed_version": "1.3.3"
2020
}
2121
],
2222
"references": [

vulnerabilities/tests/test_data/github_api/golang.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@
4545
"package": {
4646
"name": "github.com/moby/moby"
4747
},
48+
"firstPatchedVersion": {
49+
"identifier" :"1.3.3"
50+
},
4851
"vulnerableVersionRange": "< 1.3.3"
4952
}
5053
},

vulnerabilities/tests/test_data/github_api/maven-expected.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
"subpath": null
153153
},
154154
"affected_version_range": "vers:maven/>=9.0.0|<9.0.31",
155-
"fixed_version": null
155+
"fixed_version": "9.0.1"
156156
}
157157
],
158158
"references": [

vulnerabilities/tests/test_data/github_api/maven.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@
139139
"package": {
140140
"name": "org.apache.tomcat.embed:tomcat-embed-core"
141141
},
142+
"firstPatchedVersion": {
143+
"identifier" :"9.0.1"
144+
},
142145
"vulnerableVersionRange": ">= 9.0.0, < 9.0.31"
143146
}
144147
}

0 commit comments

Comments
 (0)