Skip to content

Commit cda0314

Browse files
committed
Fix EPSS tab to show latest score by published date
Signed-off-by: abhey8 <abheyabhey842@gmail.com>
1 parent 0e7adc6 commit cda0314

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

vulnerabilities/tests/test_view.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
import os
1111
import time
12+
from datetime import datetime
13+
from datetime import timezone as dt_timezone
1214

1315
import pytest
1416
from django.test import Client
@@ -182,6 +184,33 @@ def test_vulnerabilties_search_view_can_find_alias(self):
182184
response = self.client.get(f"/vulnerabilities/search/?search=TEST-2022")
183185
self.assertEqual(response.status_code, 200)
184186

187+
def test_vulnerability_details_epss_uses_latest_published_score(self):
188+
older_epss = VulnerabilitySeverity.objects.create(
189+
url="https://api.first.org/data/v1/epss?cve=CVE-2024-39689",
190+
scoring_system="epss",
191+
value="0.00045",
192+
scoring_elements="0.16709",
193+
published_at=datetime(2024, 11, 1, tzinfo=dt_timezone.utc),
194+
)
195+
latest_epss = VulnerabilitySeverity.objects.create(
196+
url="https://api.first.org/data/v1/epss?cve=CVE-2024-39689",
197+
scoring_system="epss",
198+
value="0.21233",
199+
scoring_elements="0.95432",
200+
published_at=datetime(2025, 8, 14, tzinfo=dt_timezone.utc),
201+
)
202+
203+
self.vulnerability.severities.add(older_epss)
204+
self.vulnerability.severities.add(latest_epss)
205+
206+
response = self.client.get(f"/vulnerabilities/{self.vulnerability.vulnerability_id}")
207+
self.assertEqual(response.status_code, 200)
208+
209+
epss_data = response.context["epss_data"]
210+
self.assertEqual(epss_data["score"], "0.21233")
211+
self.assertEqual(epss_data["percentile"], "0.95432")
212+
self.assertEqual(epss_data["published_at"], datetime(2025, 8, 14, tzinfo=dt_timezone.utc))
213+
185214

186215
class CheckRobotsTxtTestCase(TestCase):
187216
def test_robots_txt(self):

vulnerabilities/views.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@
4949
PAGE_SIZE = 20
5050

5151

52+
def get_latest_epss_severity(severities):
53+
"""
54+
Return the latest EPSS severity by publication date.
55+
"""
56+
return (
57+
severities.filter(scoring_system=EPSS.identifier)
58+
.order_by(
59+
F("published_at").desc(nulls_last=True),
60+
F("id").desc(),
61+
)
62+
.first()
63+
)
64+
65+
5266
class PackageSearch(ListView):
5367
model = models.Package
5468
template_name = "packages.html"
@@ -386,7 +400,7 @@ def get_context_data(self, **kwargs):
386400
):
387401
logging.error(f"CVSSMalformedError for {severity.scoring_elements}")
388402

389-
epss_severity = vulnerability.severities.filter(scoring_system="epss").first()
403+
epss_severity = get_latest_epss_severity(vulnerability.severities)
390404
epss_data = None
391405
if epss_severity:
392406
epss_data = {
@@ -502,7 +516,7 @@ def get_context_data(self, **kwargs):
502516
.exclude(scoring_elements="")
503517
)
504518

505-
epss_severity = advisory.severities.filter(scoring_system="epss").first()
519+
epss_severity = get_latest_epss_severity(advisory.severities)
506520
epss_data = None
507521
epss_advisory = None
508522
if not epss_severity:
@@ -514,7 +528,7 @@ def get_context_data(self, **kwargs):
514528
.first()
515529
)
516530
if epss_advisory:
517-
epss_severity = epss_advisory.severities.filter(scoring_system="epss").first()
531+
epss_severity = get_latest_epss_severity(epss_advisory.severities)
518532
if epss_severity:
519533
# If the advisory itself does not have EPSS severity, but has a related advisory with EPSS severity, we use the related advisory's EPSS severity and URL as the source of EPSS data.
520534
epss_data = {

0 commit comments

Comments
 (0)