Skip to content

Commit

Permalink
chore(osv): Improve mapping from OSV to ORT vulnerability references
Browse files Browse the repository at this point in the history
Signed-off-by: Sebastian Schuberth <sebastian@doubleopen.org>
  • Loading branch information
sschuberth committed Sep 13, 2024
1 parent ed3661d commit 29d3513
Showing 1 changed file with 35 additions and 30 deletions.
65 changes: 35 additions & 30 deletions plugins/advisors/osv/src/main/kotlin/Osv.kt
Original file line number Diff line number Diff line change
Expand Up @@ -182,43 +182,48 @@ private fun createRequest(pkg: Package): VulnerabilitiesForPackageRequest? {
}

private fun Vulnerability.toOrtVulnerability(): org.ossreviewtoolkit.model.vulnerabilities.Vulnerability {
// OSV uses a list in order to support multiple representations of the severity using different scoring systems.
// However, only one representation is actually possible currently, because the enum 'Severity.Type' contains just a
// single element / scoring system. So, picking first severity is fine, in particular because ORT only supports a
// single severity representation.
val (scoringSystem, severity) = severity.firstOrNull()?.let {
// The ORT and OSV vulnerability data models are different in that ORT uses a severity for each reference (assuming
// that different references could use different severities), whereas OSV manages severities and references on the
// same level, which means it is not possible to identify whether a reference belongs to a specific severity.
// To map between these different model, simply use the "cartesian product" to create an ORT reference for each
// combination of an OSV severity and reference.
val ortReferences = mutableListOf<VulnerabilityReference>()

severity.map {
it.type.name to it.score
} ?: (null to null)

val references = references.mapNotNull { reference ->
val url = reference.url.trim().let { if (it.startsWith("://")) "https$it" else it }

url.toUri().onFailure {
logger.debug { "Could not parse reference URL for vulnerability '$id': ${it.collectMessages()}." }
}.map {
// Use the 'severity' property of the unspecified 'databaseSpecific' object.
// See also https://github.com/google/osv.dev/issues/484.
val specificSeverity = databaseSpecific?.get("severity")

// Note that the CVSS Calculator does not support CVSS 4.0 yet:
// https://github.com/stevespringett/cvss-calculator/issues/78
val baseScore = runCatching {
Cvss.fromVector(severity)?.calculateScore()?.baseScore?.toFloat()
}.onFailure {
logger.debug { "Unable to parse CVSS vector '$severity': ${it.collectMessages()}." }
}.ifEmpty {
listOf(null to null)
}.forEach { (scoringSystem, severity) ->
references.mapNotNullTo(ortReferences) { reference ->
val url = reference.url.trim().let { if (it.startsWith("://")) "https$it" else it }

url.toUri().onFailure {
logger.debug { "Could not parse reference URL for vulnerability '$id': ${it.collectMessages()}." }
}.map {
// Use the 'severity' property of the unspecified 'databaseSpecific' object.
// See also https://github.com/google/osv.dev/issues/484.
val specificSeverity = databaseSpecific?.get("severity")

// Note that the CVSS Calculator does not support CVSS 4.0 yet:
// https://github.com/stevespringett/cvss-calculator/issues/78
val baseScore = runCatching {
Cvss.fromVector(severity)?.calculateScore()?.baseScore?.toFloat()
}.onFailure {
logger.debug { "Unable to parse CVSS vector '$severity': ${it.collectMessages()}." }
}.getOrNull()

val severityRating = (specificSeverity as? JsonPrimitive)?.contentOrNull
?: VulnerabilityReference.getSeverityRating(scoringSystem, baseScore)

VulnerabilityReference(it, scoringSystem, severityRating, baseScore, severity)
}.getOrNull()

val severityRating = (specificSeverity as? JsonPrimitive)?.contentOrNull
?: VulnerabilityReference.getSeverityRating(scoringSystem, baseScore)

VulnerabilityReference(it, scoringSystem, severityRating, baseScore, severity)
}.getOrNull()
}
}

return org.ossreviewtoolkit.model.vulnerabilities.Vulnerability(
id = id,
summary = summary,
description = details,
references = references
references = ortReferences
)
}

0 comments on commit 29d3513

Please sign in to comment.