Skip to content

Commit 76428da

Browse files
authored
Merge pull request #1567 from aboutcode-org/fix-severity-range
Add severity range score in API
2 parents d62f377 + e0c073d commit 76428da

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

vulnerabilities/api.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99

1010
from urllib.parse import unquote
1111

12+
from cvss.exceptions import CVSS2MalformedError
13+
from cvss.exceptions import CVSS3MalformedError
14+
from cvss.exceptions import CVSS4MalformedError
1215
from django.db.models import Prefetch
1316
from django_filters import rest_framework as filters
1417
from drf_spectacular.utils import extend_schema
15-
from drf_spectacular.utils import inline_serializer
1618
from packageurl import PackageURL
1719
from packageurl import normalize_qualifiers
1820
from rest_framework import serializers
@@ -32,7 +34,10 @@
3234
from vulnerabilities.models import VulnerabilitySeverity
3335
from vulnerabilities.models import Weakness
3436
from vulnerabilities.models import get_purl_query_lookups
37+
from vulnerabilities.severity_systems import EPSS
38+
from vulnerabilities.severity_systems import SCORING_SYSTEMS
3539
from vulnerabilities.throttling import StaffUserRateThrottle
40+
from vulnerabilities.utils import get_severity_range
3641

3742

3843
class VulnerabilitySeveritySerializer(serializers.ModelSerializer):
@@ -193,6 +198,7 @@ class VulnerabilitySerializer(BaseResourceSerializer):
193198
aliases = AliasSerializer(many=True, source="alias")
194199
kev = KEVSerializer(read_only=True)
195200
weaknesses = WeaknessSerializer(many=True)
201+
severity_range_score = serializers.SerializerMethodField()
196202

197203
def to_representation(self, instance):
198204
data = super().to_representation(instance)
@@ -206,6 +212,30 @@ def to_representation(self, instance):
206212

207213
return data
208214

215+
def get_severity_range_score(self, instance):
216+
severity_vectors = []
217+
severity_values = set()
218+
for s in instance.severities:
219+
if s.scoring_system == EPSS.identifier:
220+
continue
221+
222+
if s.scoring_elements and s.scoring_system in SCORING_SYSTEMS:
223+
try:
224+
vector_values = SCORING_SYSTEMS[s.scoring_system].get(s.scoring_elements)
225+
severity_vectors.append(vector_values)
226+
except (
227+
CVSS2MalformedError,
228+
CVSS3MalformedError,
229+
CVSS4MalformedError,
230+
NotImplementedError,
231+
):
232+
pass
233+
234+
if s.value:
235+
severity_values.add(s.value)
236+
severity_range = get_severity_range(severity_values)
237+
return severity_range
238+
209239
class Meta:
210240
model = Vulnerability
211241
fields = [
@@ -218,6 +248,7 @@ class Meta:
218248
"references",
219249
"weaknesses",
220250
"kev",
251+
"severity_range_score",
221252
]
222253

223254

vulnerabilities/tests/test_api.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ def test_api_with_single_vulnerability(self):
256256
"url": f"http://testserver/api/vulnerabilities/{self.vulnerability.id}",
257257
"vulnerability_id": self.vulnerability.vulnerability_id,
258258
"summary": "test",
259+
"severity_range_score": None,
259260
"aliases": [],
260261
"resource_url": f"http://testserver/vulnerabilities/{self.vulnerability.vulnerability_id}",
261262
"fixed_packages": [
@@ -307,6 +308,7 @@ def test_api_with_single_vulnerability_with_filters(self):
307308
"url": f"http://testserver/api/vulnerabilities/{self.vulnerability.id}",
308309
"vulnerability_id": self.vulnerability.vulnerability_id,
309310
"summary": "test",
311+
"severity_range_score": None,
310312
"aliases": [],
311313
"resource_url": f"http://testserver/vulnerabilities/{self.vulnerability.vulnerability_id}",
312314
"fixed_packages": [

0 commit comments

Comments
 (0)