From 37be21c33fbf9beeb3640098776d41a0e5a0a5ef Mon Sep 17 00:00:00 2001 From: Sean Reid Date: Tue, 6 Feb 2024 12:23:03 -0500 Subject: [PATCH 01/13] sc-4117 Add initial support for EPSS: score, percentile fields on Finding model (and associated migration); add to API serializers; show in finding display --- dojo/api_v2/serializers.py | 13 ++++++++ ...00_finding_epss_score_percentile_fields.py | 31 +++++++++++++++++++ dojo/finding/helper.py | 6 ++++ dojo/models.py | 21 +++++++++++++ dojo/templates/dojo/view_finding.html | 8 +++++ 5 files changed, 79 insertions(+) create mode 100644 dojo/db_migrations/0200_finding_epss_score_percentile_fields.py diff --git a/dojo/api_v2/serializers.py b/dojo/api_v2/serializers.py index 49e3486fe2c..13b1858bddd 100644 --- a/dojo/api_v2/serializers.py +++ b/dojo/api_v2/serializers.py @@ -1656,6 +1656,8 @@ class FindingSerializer(TaggitSerializer, serializers.ModelSerializer): reporter = serializers.PrimaryKeyRelatedField( required=False, queryset=User.objects.all() ) + epss_score = serializers.FloatField(required=False, default=None) + epss_percentile = serializers.FloatField(required=False, default=None) class Meta: model = Finding @@ -1815,6 +1817,8 @@ class FindingCreateSerializer(TaggitSerializer, serializers.ModelSerializer): reporter = serializers.PrimaryKeyRelatedField( required=False, queryset=User.objects.all() ) + epss_score = serializers.FloatField(required=False, default=None) + epss_percentile = serializers.FloatField(required=False, default=None) class Meta: model = Finding @@ -1841,6 +1845,10 @@ def create(self, validated_data): else: vulnerability_id_set = None + # Pop these here; we'll set them later (the call to save_vulnerability_ids() blows them away) + epss_score = validated_data.pop("epss_score") + epss_percentile = validated_data.pop("epss_percentile") + # first save, so we have an instance to get push_all_to_jira from new_finding = super(TaggitSerializer, self).create(validated_data) @@ -1852,6 +1860,11 @@ def create(self, validated_data): save_vulnerability_ids(new_finding, vulnerability_ids) new_finding.save() + if epss_score or epss_percentile: + new_finding.epss_score = epss_score + new_finding.epss_percentile = epss_percentile + new_finding.save() + # TODO: JIRA can we remove this is_push_all_issues, already checked in # apiv2 viewset? push_to_jira = push_to_jira or jira_helper.is_push_all_issues( diff --git a/dojo/db_migrations/0200_finding_epss_score_percentile_fields.py b/dojo/db_migrations/0200_finding_epss_score_percentile_fields.py new file mode 100644 index 00000000000..3cfe49b80d5 --- /dev/null +++ b/dojo/db_migrations/0200_finding_epss_score_percentile_fields.py @@ -0,0 +1,31 @@ +# Generated by Django 4.1.13 on 2024-02-05 19:52 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dojo', '0199_whitesource_to_mend'), + ] + + operations = [ + migrations.AddField( + model_name='finding', + name='epss_percentile', + field=models.FloatField(blank=True, help_text='Percentile for the EPSS score: the proportion of all scored vulnerabilities with the same or a lower EPSS score.', null=True, verbose_name='EPSS percentile'), + ), + migrations.AddField( + model_name='finding', + name='epss_score', + field=models.FloatField(blank=True, help_text='EPSS score representing the probability [0-1] of exploitation in the wild in the 30 days following score publication.', null=True, verbose_name='EPSS value'), + ), + migrations.AddIndex( + model_name='finding', + index=models.Index(fields=['epss_score'], name='dojo_findin_epss_sc_e40540_idx'), + ), + migrations.AddIndex( + model_name='finding', + index=models.Index(fields=['epss_percentile'], name='dojo_findin_epss_pe_567499_idx'), + ), + ] diff --git a/dojo/finding/helper.py b/dojo/finding/helper.py index d2d1bd4707b..6722da6304c 100644 --- a/dojo/finding/helper.py +++ b/dojo/finding/helper.py @@ -647,6 +647,9 @@ def save_vulnerability_ids(finding, vulnerability_ids): else: finding.cve = None + # Remove stored EPSS info + finding.epss_score = finding.epss_percentile = None + def save_vulnerability_ids_template(finding_template, vulnerability_ids): # Remove duplicates @@ -664,3 +667,6 @@ def save_vulnerability_ids_template(finding_template, vulnerability_ids): finding_template.cve = vulnerability_ids[0] else: finding_template.cve = None + + # Remove stored EPSS info + finding_template.epss_score = finding_template.epss_percentile = None diff --git a/dojo/models.py b/dojo/models.py index 64fc8137167..d9863296aaf 100755 --- a/dojo/models.py +++ b/dojo/models.py @@ -2422,6 +2422,15 @@ class Finding(models.Model): tags = TagField(blank=True, force_lowercase=True, help_text=_("Add tags that help describe this finding. Choose from the list or add new tags. Press Enter key to add.")) inherited_tags = TagField(blank=True, force_lowercase=True, help_text=_("Internal use tags sepcifically for maintaining parity with product. This field will be present as a subset in the tags field")) + epss_score = models.FloatField(null = True, + blank = True, + verbose_name = _('EPSS value'), + help_text = _("EPSS score representing the probability [0-1] of exploitation in the wild in the 30 days following score publication.")) + epss_percentile = models.FloatField(null = True, + blank = True, + verbose_name = _('EPSS percentile'), + help_text = _("Percentile for the EPSS score: the proportion of all scored vulnerabilities with the same or a lower EPSS score.")) + SEVERITIES = {'Info': 4, 'Low': 3, 'Medium': 2, 'High': 1, 'Critical': 0} @@ -2458,6 +2467,8 @@ class Meta: models.Index(fields=['duplicate']), models.Index(fields=['is_mitigated']), models.Index(fields=['duplicate_finding', 'id']), + models.Index(fields=['epss_score']), + models.Index(fields=['epss_percentile']), ] def __init__(self, *args, **kwargs): @@ -3195,6 +3206,16 @@ def violates_sla(self): days_remaining = self.sla_days_remaining() return days_remaining < 0 if days_remaining else False + @property + def epss_info(self): + return self._epss_info() + + def _epss_info(self): + """ + :return: A tuple of (EPSS score, score percentile) + """ + return self.epss_score, self.epss_percentile + class FindingAdmin(admin.ModelAdmin): # For efficiency with large databases, display many-to-many fields with raw diff --git a/dojo/templates/dojo/view_finding.html b/dojo/templates/dojo/view_finding.html index 5a49cbd5bbf..7c2e0d6ebf1 100755 --- a/dojo/templates/dojo/view_finding.html +++ b/dojo/templates/dojo/view_finding.html @@ -270,6 +270,7 @@

{% endif %} CWE Vulnerability Id + EPSS Score Found by {% if finding.vuln_id_from_tool %} Vuln ID from tool @@ -421,6 +422,13 @@

{% endif %} {% endif %} + + {% if finding.epss_info %} + {{ finding.epss_info.0|percentage:1.0 }} / {{ finding.epss_info.1|percentage:1.0 }} + {% else %} + n/a + {% endif %} + {% if found_by %} {% for scanner in found_by %} From 2b327d0d3bd4e3d176bcadcef59eec3fd03dff22 Mon Sep 17 00:00:00 2001 From: Sean Reid Date: Tue, 6 Feb 2024 14:38:26 -0500 Subject: [PATCH 02/13] sc-4117 Rework how epss info is passed to the template, change template a bit --- dojo/finding/views.py | 8 ++++++++ dojo/models.py | 10 ---------- dojo/templates/dojo/view_finding.html | 17 +++++++++++++---- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/dojo/finding/views.py b/dojo/finding/views.py index ad1128ba778..aa842fbdd6c 100644 --- a/dojo/finding/views.py +++ b/dojo/finding/views.py @@ -741,6 +741,12 @@ def get_initial_context(self, request: HttpRequest, finding: Finding, user: Dojo def get_template(self): return "dojo/view_finding.html" + def get_epss_data(self, finding): + return { + "epss_score": finding.epss_score, + "epss_percentile": finding.epss_percentile, + } + def get(self, request: HttpRequest, finding_id: int): # Get the initial objects finding = self.get_finding(finding_id) @@ -758,6 +764,7 @@ def get(self, request: HttpRequest, finding_id: int): context |= self.get_similar_findings(request, finding) context |= self.get_test_import_data(request, finding) context |= self.get_jira_data(finding) + context |= self.get_epss_data(finding) # Render the form return render(request, self.get_template(), context) @@ -781,6 +788,7 @@ def post(self, request: HttpRequest, finding_id): context |= self.get_similar_findings(request, finding) context |= self.get_test_import_data(request, finding) context |= self.get_jira_data(finding) + context |= self.get_epss_data(finding) # Render the form return render(request, self.get_template(), context) diff --git a/dojo/models.py b/dojo/models.py index d9863296aaf..5cbe7d38fd1 100755 --- a/dojo/models.py +++ b/dojo/models.py @@ -3206,16 +3206,6 @@ def violates_sla(self): days_remaining = self.sla_days_remaining() return days_remaining < 0 if days_remaining else False - @property - def epss_info(self): - return self._epss_info() - - def _epss_info(self): - """ - :return: A tuple of (EPSS score, score percentile) - """ - return self.epss_score, self.epss_percentile - class FindingAdmin(admin.ModelAdmin): # For efficiency with large databases, display many-to-many fields with raw diff --git a/dojo/templates/dojo/view_finding.html b/dojo/templates/dojo/view_finding.html index 7c2e0d6ebf1..812c9d5e63d 100755 --- a/dojo/templates/dojo/view_finding.html +++ b/dojo/templates/dojo/view_finding.html @@ -270,7 +270,7 @@

{% endif %} CWE Vulnerability Id - EPSS Score + EPSS Score / Percentile Found by {% if finding.vuln_id_from_tool %} Vuln ID from tool @@ -423,10 +423,19 @@

{% endif %} - {% if finding.epss_info %} - {{ finding.epss_info.0|percentage:1.0 }} / {{ finding.epss_info.1|percentage:1.0 }} - {% else %} + {% if epss_score is None and epss_percentile is None %} n/a + {% else %} + {% if epss_score is not None %} + {{ epss_score|percentage:1.0 }} + {% else %} + n/a + {% endif %} + {% if epss_percentile is not None %} + [{{ epss_percentile|percentage:1.0 }}] + {% else %} + n/a + {% endif %} {% endif %} From d103d85c969f25bde4a10300423479b47dcf1134 Mon Sep 17 00:00:00 2001 From: Sean Reid Date: Tue, 6 Feb 2024 14:41:44 -0500 Subject: [PATCH 03/13] sc-4117 Remove setting of epps to None in finding template helper method --- dojo/finding/helper.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/dojo/finding/helper.py b/dojo/finding/helper.py index 6722da6304c..7196f19deea 100644 --- a/dojo/finding/helper.py +++ b/dojo/finding/helper.py @@ -667,6 +667,3 @@ def save_vulnerability_ids_template(finding_template, vulnerability_ids): finding_template.cve = vulnerability_ids[0] else: finding_template.cve = None - - # Remove stored EPSS info - finding_template.epss_score = finding_template.epss_percentile = None From 7e0a0dd952ff4f60cfdd3008adfbd62329751517 Mon Sep 17 00:00:00 2001 From: Sean Reid Date: Tue, 6 Feb 2024 15:43:00 -0500 Subject: [PATCH 04/13] sc-4117 Reformat EPSS info on finding template --- dojo/templates/dojo/view_finding.html | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/dojo/templates/dojo/view_finding.html b/dojo/templates/dojo/view_finding.html index 812c9d5e63d..2849ccbb858 100755 --- a/dojo/templates/dojo/view_finding.html +++ b/dojo/templates/dojo/view_finding.html @@ -423,19 +423,16 @@

{% endif %} - {% if epss_score is None and epss_percentile is None %} + {% if epss_score is not None %} + {{ epss_score|percentage:1.0 }} + {% else %} n/a + {% endif %} + / + {% if epss_percentile is not None %} + [{{ epss_percentile|percentage:1.0 }}] {% else %} - {% if epss_score is not None %} - {{ epss_score|percentage:1.0 }} - {% else %} - n/a - {% endif %} - {% if epss_percentile is not None %} - [{{ epss_percentile|percentage:1.0 }}] - {% else %} - n/a - {% endif %} + n/a {% endif %} From 44b98c5cc95eaa272c8d4b80ab9b8b12959ef814 Mon Sep 17 00:00:00 2001 From: Sean Reid Date: Tue, 6 Feb 2024 16:37:21 -0500 Subject: [PATCH 05/13] sc-4117 Remove square parens from around EPSS percentile --- dojo/templates/dojo/view_finding.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dojo/templates/dojo/view_finding.html b/dojo/templates/dojo/view_finding.html index 2849ccbb858..ed7e1910ac8 100755 --- a/dojo/templates/dojo/view_finding.html +++ b/dojo/templates/dojo/view_finding.html @@ -430,7 +430,7 @@

{% endif %} / {% if epss_percentile is not None %} - [{{ epss_percentile|percentage:1.0 }}] + {{ epss_percentile|percentage:1.0 }} {% else %} n/a {% endif %} From cdd97971e2edcb2ae091ef03b4ccc35290413d3e Mon Sep 17 00:00:00 2001 From: Sean Reid Date: Thu, 8 Feb 2024 14:09:12 -0500 Subject: [PATCH 06/13] sc-4117 Don't clear out stored epss info when saving vuln ids --- dojo/finding/helper.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/dojo/finding/helper.py b/dojo/finding/helper.py index 7196f19deea..d2d1bd4707b 100644 --- a/dojo/finding/helper.py +++ b/dojo/finding/helper.py @@ -647,9 +647,6 @@ def save_vulnerability_ids(finding, vulnerability_ids): else: finding.cve = None - # Remove stored EPSS info - finding.epss_score = finding.epss_percentile = None - def save_vulnerability_ids_template(finding_template, vulnerability_ids): # Remove duplicates From 5c5b8ff315e958922049b40cf50e963cc52330ea Mon Sep 17 00:00:00 2001 From: Sean Reid Date: Thu, 8 Feb 2024 14:09:55 -0500 Subject: [PATCH 07/13] sc-4117 Update single Finding view to capitalize "N/A" displayed when epss info is blank --- dojo/templates/dojo/view_finding.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dojo/templates/dojo/view_finding.html b/dojo/templates/dojo/view_finding.html index ed7e1910ac8..03d809d114a 100755 --- a/dojo/templates/dojo/view_finding.html +++ b/dojo/templates/dojo/view_finding.html @@ -426,13 +426,13 @@

{% if epss_score is not None %} {{ epss_score|percentage:1.0 }} {% else %} - n/a + N/A {% endif %} / {% if epss_percentile is not None %} {{ epss_percentile|percentage:1.0 }} {% else %} - n/a + N/A {% endif %} From 597e89bda994df8b529446ae66d0b9484c2dc9e7 Mon Sep 17 00:00:00 2001 From: Sean Reid Date: Thu, 8 Feb 2024 14:38:42 -0500 Subject: [PATCH 08/13] sc-4117 Add min/max validation on Finding model for EPSS values --- .../0200_finding_epss_score_percentile_fields.py | 5 +++-- dojo/models.py | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/dojo/db_migrations/0200_finding_epss_score_percentile_fields.py b/dojo/db_migrations/0200_finding_epss_score_percentile_fields.py index 3cfe49b80d5..ceecef08306 100644 --- a/dojo/db_migrations/0200_finding_epss_score_percentile_fields.py +++ b/dojo/db_migrations/0200_finding_epss_score_percentile_fields.py @@ -1,5 +1,6 @@ # Generated by Django 4.1.13 on 2024-02-05 19:52 +import django.core.validators from django.db import migrations, models @@ -13,12 +14,12 @@ class Migration(migrations.Migration): migrations.AddField( model_name='finding', name='epss_percentile', - field=models.FloatField(blank=True, help_text='Percentile for the EPSS score: the proportion of all scored vulnerabilities with the same or a lower EPSS score.', null=True, verbose_name='EPSS percentile'), + field=models.FloatField(blank=True, help_text='Percentile for the EPSS score: the proportion of all scored vulnerabilities with the same or a lower EPSS score.', null=True, validators=[django.core.validators.MinValueValidator(0.0), django.core.validators.MaxValueValidator(1.0)], verbose_name='EPSS percentile'), ), migrations.AddField( model_name='finding', name='epss_score', - field=models.FloatField(blank=True, help_text='EPSS score representing the probability [0-1] of exploitation in the wild in the 30 days following score publication.', null=True, verbose_name='EPSS value'), + field=models.FloatField(blank=True, help_text='EPSS score representing the probability [0-1] of exploitation in the wild in the 30 days following score publication.', null=True, validators=[django.core.validators.MinValueValidator(0.0), django.core.validators.MaxValueValidator(1.0)], verbose_name='EPSS value'), ), migrations.AddIndex( model_name='finding', diff --git a/dojo/models.py b/dojo/models.py index 5cbe7d38fd1..8d6b515cdc9 100755 --- a/dojo/models.py +++ b/dojo/models.py @@ -13,7 +13,7 @@ from django.contrib.auth.models import Group from django.db.models.expressions import Case, When from django.urls import reverse -from django.core.validators import RegexValidator, validate_ipv46_address +from django.core.validators import RegexValidator, validate_ipv46_address, MinValueValidator, MaxValueValidator from django.core.files.base import ContentFile from django.core.exceptions import ValidationError from django.db import models, connection @@ -2425,11 +2425,13 @@ class Finding(models.Model): epss_score = models.FloatField(null = True, blank = True, verbose_name = _('EPSS value'), - help_text = _("EPSS score representing the probability [0-1] of exploitation in the wild in the 30 days following score publication.")) + help_text = _("EPSS score representing the probability [0-1] of exploitation in the wild in the 30 days following score publication."), + validators=[MinValueValidator(0.0), MaxValueValidator(1.0)],) epss_percentile = models.FloatField(null = True, blank = True, verbose_name = _('EPSS percentile'), - help_text = _("Percentile for the EPSS score: the proportion of all scored vulnerabilities with the same or a lower EPSS score.")) + help_text = _("Percentile for the EPSS score: the proportion of all scored vulnerabilities with the same or a lower EPSS score."), + validators=[MinValueValidator(0.0), MaxValueValidator(1.0)],) SEVERITIES = {'Info': 4, 'Low': 3, 'Medium': 2, 'High': 1, 'Critical': 0} From f650a64c2660702606c9c406fc36b0331fe8f552 Mon Sep 17 00:00:00 2001 From: Sean Reid Date: Thu, 8 Feb 2024 16:54:08 -0500 Subject: [PATCH 09/13] sc-4117 remove inclusion of epss info on ViewFinding#post --- dojo/finding/views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/dojo/finding/views.py b/dojo/finding/views.py index aa842fbdd6c..e5da0569f9f 100644 --- a/dojo/finding/views.py +++ b/dojo/finding/views.py @@ -788,7 +788,6 @@ def post(self, request: HttpRequest, finding_id): context |= self.get_similar_findings(request, finding) context |= self.get_test_import_data(request, finding) context |= self.get_jira_data(finding) - context |= self.get_epss_data(finding) # Render the form return render(request, self.get_template(), context) From 08a89892aa02d676481bc2e82831f29e07576a5c Mon Sep 17 00:00:00 2001 From: Sean Reid Date: Thu, 8 Feb 2024 17:50:13 -0500 Subject: [PATCH 10/13] sc-4117 Update api_v2 serializers for Finding to enforce min/max range for epss scores and percentiles --- dojo/api_v2/serializers.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dojo/api_v2/serializers.py b/dojo/api_v2/serializers.py index 13b1858bddd..fe580ce5d28 100644 --- a/dojo/api_v2/serializers.py +++ b/dojo/api_v2/serializers.py @@ -1656,8 +1656,9 @@ class FindingSerializer(TaggitSerializer, serializers.ModelSerializer): reporter = serializers.PrimaryKeyRelatedField( required=False, queryset=User.objects.all() ) - epss_score = serializers.FloatField(required=False, default=None) - epss_percentile = serializers.FloatField(required=False, default=None) + epss_score = serializers.FloatField(required=False, allow_null=True, min_value=0.0, max_value=1.0, default=None) + epss_percentile = serializers.FloatField(required=False, allow_null=True, min_value=0.0, max_value=1.0, + default=None) class Meta: model = Finding @@ -1817,8 +1818,9 @@ class FindingCreateSerializer(TaggitSerializer, serializers.ModelSerializer): reporter = serializers.PrimaryKeyRelatedField( required=False, queryset=User.objects.all() ) - epss_score = serializers.FloatField(required=False, default=None) - epss_percentile = serializers.FloatField(required=False, default=None) + epss_score = serializers.FloatField(required=False, allow_null=True, min_value=0.0, max_value=1.0, default=None) + epss_percentile = serializers.FloatField(required=False, allow_null=True, min_value=0.0, max_value=1.0, + default=None) class Meta: model = Finding From 33c5c304aef3fc52b2cbad331701badd04b27bb7 Mon Sep 17 00:00:00 2001 From: Sean Reid Date: Fri, 9 Feb 2024 11:07:01 -0500 Subject: [PATCH 11/13] sc-4117 remove get_epss_data from ViewFinding, just use the Finding context object in the template --- dojo/finding/views.py | 7 ------- dojo/templates/dojo/view_finding.html | 8 ++++---- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/dojo/finding/views.py b/dojo/finding/views.py index e5da0569f9f..ad1128ba778 100644 --- a/dojo/finding/views.py +++ b/dojo/finding/views.py @@ -741,12 +741,6 @@ def get_initial_context(self, request: HttpRequest, finding: Finding, user: Dojo def get_template(self): return "dojo/view_finding.html" - def get_epss_data(self, finding): - return { - "epss_score": finding.epss_score, - "epss_percentile": finding.epss_percentile, - } - def get(self, request: HttpRequest, finding_id: int): # Get the initial objects finding = self.get_finding(finding_id) @@ -764,7 +758,6 @@ def get(self, request: HttpRequest, finding_id: int): context |= self.get_similar_findings(request, finding) context |= self.get_test_import_data(request, finding) context |= self.get_jira_data(finding) - context |= self.get_epss_data(finding) # Render the form return render(request, self.get_template(), context) diff --git a/dojo/templates/dojo/view_finding.html b/dojo/templates/dojo/view_finding.html index 03d809d114a..cff057abba0 100755 --- a/dojo/templates/dojo/view_finding.html +++ b/dojo/templates/dojo/view_finding.html @@ -423,14 +423,14 @@

{% endif %} - {% if epss_score is not None %} - {{ epss_score|percentage:1.0 }} + {% if finding.epss_score is not None %} + {{ finding.epss_score|percentage:1.0 }} {% else %} N/A {% endif %} / - {% if epss_percentile is not None %} - {{ epss_percentile|percentage:1.0 }} + {% if finding.epss_percentile is not None %} + {{ finding.epss_percentile|percentage:1.0 }} {% else %} N/A {% endif %} From dcc37ae276e72ff775d05304c66b07f99f51bd81 Mon Sep 17 00:00:00 2001 From: Sean Reid Date: Fri, 9 Feb 2024 15:53:16 -0500 Subject: [PATCH 12/13] sc-4117 remove serializer stuff; handled by underlying model validation --- dojo/api_v2/serializers.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/dojo/api_v2/serializers.py b/dojo/api_v2/serializers.py index fe580ce5d28..49e3486fe2c 100644 --- a/dojo/api_v2/serializers.py +++ b/dojo/api_v2/serializers.py @@ -1656,9 +1656,6 @@ class FindingSerializer(TaggitSerializer, serializers.ModelSerializer): reporter = serializers.PrimaryKeyRelatedField( required=False, queryset=User.objects.all() ) - epss_score = serializers.FloatField(required=False, allow_null=True, min_value=0.0, max_value=1.0, default=None) - epss_percentile = serializers.FloatField(required=False, allow_null=True, min_value=0.0, max_value=1.0, - default=None) class Meta: model = Finding @@ -1818,9 +1815,6 @@ class FindingCreateSerializer(TaggitSerializer, serializers.ModelSerializer): reporter = serializers.PrimaryKeyRelatedField( required=False, queryset=User.objects.all() ) - epss_score = serializers.FloatField(required=False, allow_null=True, min_value=0.0, max_value=1.0, default=None) - epss_percentile = serializers.FloatField(required=False, allow_null=True, min_value=0.0, max_value=1.0, - default=None) class Meta: model = Finding @@ -1847,10 +1841,6 @@ def create(self, validated_data): else: vulnerability_id_set = None - # Pop these here; we'll set them later (the call to save_vulnerability_ids() blows them away) - epss_score = validated_data.pop("epss_score") - epss_percentile = validated_data.pop("epss_percentile") - # first save, so we have an instance to get push_all_to_jira from new_finding = super(TaggitSerializer, self).create(validated_data) @@ -1862,11 +1852,6 @@ def create(self, validated_data): save_vulnerability_ids(new_finding, vulnerability_ids) new_finding.save() - if epss_score or epss_percentile: - new_finding.epss_score = epss_score - new_finding.epss_percentile = epss_percentile - new_finding.save() - # TODO: JIRA can we remove this is_push_all_issues, already checked in # apiv2 viewset? push_to_jira = push_to_jira or jira_helper.is_push_all_issues( From 785e004539926a58e6bbb8b9672e7a3e41725edd Mon Sep 17 00:00:00 2001 From: Sean Reid Date: Fri, 9 Feb 2024 16:51:36 -0500 Subject: [PATCH 13/13] sc-4117 Add EPSS Score/Percentile columns to finding listing page --- .../templates/dojo/findings_list_snippet.html | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/dojo/templates/dojo/findings_list_snippet.html b/dojo/templates/dojo/findings_list_snippet.html index 248b7491942..14bf921a3bb 100644 --- a/dojo/templates/dojo/findings_list_snippet.html +++ b/dojo/templates/dojo/findings_list_snippet.html @@ -322,6 +322,12 @@

{% trans "Vulnerability Id" %} + + {% trans "EPSS Score" %} + + + {% trans "EPSS Percentile" %} + {% if filter_name == 'Closed' %} {% comment %} The display field is translated in the function. No need to translate here as well{% endcomment %} @@ -593,6 +599,20 @@

{% endif %} {% endwith %} + + {% if finding.epss_score is not None %} + {{ finding.epss_score|percentage:1.0 }} + {% else %} + N/A + {% endif %} + + + {% if finding.epss_percentile is not None %} + {{ finding.epss_percentile|percentage:1.0 }} + {% else %} + N/A + {% endif %} + {% if filter_name == 'Closed' %} {{ finding.mitigated|date }} @@ -721,6 +741,8 @@

}}, { "data": "cwe" }, { "data": "cve" }, + { "data": "epss_score" }, + { "data": "epss_percentile" }, { "data": "found_date" }, { "data": "finding_age" }, {% if system_settings.enable_finding_sla %}