From 1bd041a26cc9cbd086015ac94151c116e36efb20 Mon Sep 17 00:00:00 2001 From: tdruez Date: Fri, 15 Nov 2024 10:30:50 +0400 Subject: [PATCH] Refine the DecimalField and exploitability label system #98 Signed-off-by: tdruez --- ...ent_risk_score_alter_package_risk_score.py | 23 ++++++++++++ .../tabs/tab_vulnerabilities.html | 2 +- product_portfolio/filters.py | 4 +-- .../tabs/tab_vulnerabilities.html | 2 +- vulnerabilities/filters.py | 12 +------ ...remove_vulnerability_max_score_and_more.py | 36 +++++++++++++++++++ ...2_vulnerability_exploitability_and_more.py | 36 ------------------- .../0003_to_delete_temp_fake_values.py | 2 +- ...r_vulnerability_exploitability_and_more.py | 28 --------------- vulnerabilities/models.py | 32 ++++++++++------- .../tables/vulnerability_list_table.html | 2 +- 11 files changed, 85 insertions(+), 94 deletions(-) create mode 100644 component_catalog/migrations/0013_alter_component_risk_score_alter_package_risk_score.py create mode 100644 vulnerabilities/migrations/0002_remove_vulnerability_max_score_and_more.py delete mode 100644 vulnerabilities/migrations/0002_vulnerability_exploitability_and_more.py delete mode 100644 vulnerabilities/migrations/0004_alter_vulnerability_exploitability_and_more.py diff --git a/component_catalog/migrations/0013_alter_component_risk_score_alter_package_risk_score.py b/component_catalog/migrations/0013_alter_component_risk_score_alter_package_risk_score.py new file mode 100644 index 00000000..bca35e6e --- /dev/null +++ b/component_catalog/migrations/0013_alter_component_risk_score_alter_package_risk_score.py @@ -0,0 +1,23 @@ +# Generated by Django 5.0.9 on 2024-11-15 06:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('component_catalog', '0012_alter_component_risk_score_alter_package_risk_score'), + ] + + operations = [ + migrations.AlterField( + model_name='component', + name='risk_score', + field=models.DecimalField(blank=True, decimal_places=1, help_text='Risk score between 0.00 and 10.00, where higher values indicate greater vulnerability risk for the package.', max_digits=3, null=True), + ), + migrations.AlterField( + model_name='package', + name='risk_score', + field=models.DecimalField(blank=True, decimal_places=1, help_text='Risk score between 0.00 and 10.00, where higher values indicate greater vulnerability risk for the package.', max_digits=3, null=True), + ), + ] diff --git a/component_catalog/templates/component_catalog/tabs/tab_vulnerabilities.html b/component_catalog/templates/component_catalog/tabs/tab_vulnerabilities.html index 37a54a8a..379957a2 100644 --- a/component_catalog/templates/component_catalog/tabs/tab_vulnerabilities.html +++ b/component_catalog/templates/component_catalog/tabs/tab_vulnerabilities.html @@ -75,7 +75,7 @@ {% endif %} - {{ vulnerability.exploitability|default_if_none:"" }} + {{ vulnerability.get_exploitability_display }} {{ vulnerability.weighted_severity|default_if_none:"" }} diff --git a/product_portfolio/filters.py b/product_portfolio/filters.py index 7a5035dc..9764c6b7 100644 --- a/product_portfolio/filters.py +++ b/product_portfolio/filters.py @@ -31,9 +31,9 @@ from product_portfolio.models import ProductDependency from product_portfolio.models import ProductPackage from product_portfolio.models import ProductStatus -from vulnerabilities.filters import EXPLOITABILITY_CHOICES from vulnerabilities.filters import RISK_SCORE_RANGES from vulnerabilities.filters import ScoreRangeFilter +from vulnerabilities.models import Vulnerability class ProductFilterSet(DataspacedFilterSet): @@ -149,7 +149,7 @@ class BaseProductRelationFilterSet(DataspacedFilterSet): exploitability = django_filters.ChoiceFilter( label=_("Exploitability"), field_name="package__exploitability", - choices=EXPLOITABILITY_CHOICES, + choices=Vulnerability.EXPLOITABILITY_CHOICES, ) weighted_severity = ScoreRangeFilter( label=_("Severity"), diff --git a/product_portfolio/templates/product_portfolio/tabs/tab_vulnerabilities.html b/product_portfolio/templates/product_portfolio/tabs/tab_vulnerabilities.html index 32ba9964..d7860ced 100644 --- a/product_portfolio/templates/product_portfolio/tabs/tab_vulnerabilities.html +++ b/product_portfolio/templates/product_portfolio/tabs/tab_vulnerabilities.html @@ -31,7 +31,7 @@ - {{ vulnerability.exploitability|default_if_none:"" }} + {{ vulnerability.get_exploitability_display }} {{ vulnerability.weighted_severity|default_if_none:"" }} diff --git a/vulnerabilities/filters.py b/vulnerabilities/filters.py index 763e33d2..e6f627fd 100644 --- a/vulnerabilities/filters.py +++ b/vulnerabilities/filters.py @@ -17,13 +17,6 @@ from dje.widgets import SortDropDownWidget from vulnerabilities.models import Vulnerability -EXPLOITABILITY_CHOICES = [ - (0.5, _("No exploit known (0.5)")), - (1.0, _("Exploit script published (1.0)")), - (2.0, _("High exploitability (2.0)")), -] - - RISK_SCORE_RANGES = { "low": (0.1, 2.9), "medium": (3.0, 5.9), @@ -97,10 +90,6 @@ class VulnerabilityFilterSet(DataspacedFilterSet): ], widget=SortDropDownWidget, ) - exploitability = django_filters.ChoiceFilter( - label=_("Exploitability"), - choices=EXPLOITABILITY_CHOICES, - ) weighted_severity = ScoreRangeFilter( label=_("Severity"), score_ranges=RISK_SCORE_RANGES, @@ -114,6 +103,7 @@ class Meta: model = Vulnerability fields = [ "q", + "exploitability", ] def __init__(self, *args, **kwargs): diff --git a/vulnerabilities/migrations/0002_remove_vulnerability_max_score_and_more.py b/vulnerabilities/migrations/0002_remove_vulnerability_max_score_and_more.py new file mode 100644 index 00000000..e70208a3 --- /dev/null +++ b/vulnerabilities/migrations/0002_remove_vulnerability_max_score_and_more.py @@ -0,0 +1,36 @@ +# Generated by Django 5.0.9 on 2024-11-15 06:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('vulnerabilities', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='vulnerability', + name='max_score', + ), + migrations.RemoveField( + model_name='vulnerability', + name='min_score', + ), + migrations.AddField( + model_name='vulnerability', + name='exploitability', + field=models.DecimalField(blank=True, choices=[(0.5, 'No exploits known'), (1.0, 'Potential exploits'), (2.0, 'Known exploits')], decimal_places=1, help_text='Exploitability refers to the potential or probability of a software package vulnerability being exploited by malicious actors to compromise systems, applications, or networks. It is determined automatically by discovery of exploits.', max_digits=3, null=True), + ), + migrations.AddField( + model_name='vulnerability', + name='risk_score', + field=models.DecimalField(blank=True, decimal_places=1, help_text='Risk score from 0.0 to 10.0, with higher values indicating greater vulnerability risk. This score is the maximum of the weighted severity multiplied by exploitability, capped at 10.', max_digits=3, null=True), + ), + migrations.AddField( + model_name='vulnerability', + name='weighted_severity', + field=models.DecimalField(blank=True, decimal_places=1, help_text='Weighted severity is the highest value calculated by multiplying each severity by its corresponding weight, divided by 10.', max_digits=3, null=True), + ), + ] diff --git a/vulnerabilities/migrations/0002_vulnerability_exploitability_and_more.py b/vulnerabilities/migrations/0002_vulnerability_exploitability_and_more.py deleted file mode 100644 index cb769202..00000000 --- a/vulnerabilities/migrations/0002_vulnerability_exploitability_and_more.py +++ /dev/null @@ -1,36 +0,0 @@ -# Generated by Django 5.0.9 on 2024-11-12 08:02 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('vulnerabilities', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='vulnerability', - name='exploitability', - field=models.DecimalField(decimal_places=2, help_text='Exploitability indicates the likelihood that a vulnerability in a software package could be used by malicious actors to compromise systems, applications, or networks. This metric is determined automatically based on the discovery of known exploits.', max_digits=4, null=True), - ), - migrations.AddField( - model_name='vulnerability', - name='risk_score', - field=models.DecimalField(decimal_places=2, help_text='Risk score from 0.00 to 10.00, with higher values indicating greater vulnerability risk. This score is the maximum of the weighted severity multiplied by exploitability, capped at 10.', max_digits=4, null=True), - ), - migrations.AddField( - model_name='vulnerability', - name='weighted_severity', - field=models.DecimalField(decimal_places=2, help_text='Weighted severity is the highest value calculated by multiplying each severity by its corresponding weight, divided by 10.', max_digits=4, null=True), - ), - migrations.RemoveField( - model_name='vulnerability', - name='max_score', - ), - migrations.RemoveField( - model_name='vulnerability', - name='min_score', - ), - ] diff --git a/vulnerabilities/migrations/0003_to_delete_temp_fake_values.py b/vulnerabilities/migrations/0003_to_delete_temp_fake_values.py index 8ff2cdfc..f8eb82b8 100644 --- a/vulnerabilities/migrations/0003_to_delete_temp_fake_values.py +++ b/vulnerabilities/migrations/0003_to_delete_temp_fake_values.py @@ -24,7 +24,7 @@ def set_random_risk_score(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('vulnerabilities', '0002_vulnerability_exploitability_and_more'), + ('vulnerabilities', '0002_remove_vulnerability_max_score_and_more'), ] operations = [ diff --git a/vulnerabilities/migrations/0004_alter_vulnerability_exploitability_and_more.py b/vulnerabilities/migrations/0004_alter_vulnerability_exploitability_and_more.py deleted file mode 100644 index 87070fe0..00000000 --- a/vulnerabilities/migrations/0004_alter_vulnerability_exploitability_and_more.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 5.0.9 on 2024-11-14 12:08 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('vulnerabilities', '0003_to_delete_temp_fake_values'), - ] - - operations = [ - migrations.AlterField( - model_name='vulnerability', - name='exploitability', - field=models.DecimalField(blank=True, decimal_places=2, help_text='Exploitability indicates the likelihood that a vulnerability in a software package could be used by malicious actors to compromise systems, applications, or networks. This metric is determined automatically based on the discovery of known exploits.', max_digits=4, null=True), - ), - migrations.AlterField( - model_name='vulnerability', - name='risk_score', - field=models.DecimalField(blank=True, decimal_places=2, help_text='Risk score from 0.00 to 10.00, with higher values indicating greater vulnerability risk. This score is the maximum of the weighted severity multiplied by exploitability, capped at 10.', max_digits=4, null=True), - ), - migrations.AlterField( - model_name='vulnerability', - name='weighted_severity', - field=models.DecimalField(blank=True, decimal_places=2, help_text='Weighted severity is the highest value calculated by multiplying each severity by its corresponding weight, divided by 10.', max_digits=4, null=True), - ), - ] diff --git a/vulnerabilities/models.py b/vulnerabilities/models.py index af17b1ad..264763af 100644 --- a/vulnerabilities/models.py +++ b/vulnerabilities/models.py @@ -101,23 +101,29 @@ class Vulnerability(HistoryDateFieldsMixin, DataspacedModel): output_field=models.IntegerField(), db_persist=True, ) + EXPLOITABILITY_CHOICES = [ + (0.5, _("No exploits known")), + (1.0, _("Potential exploits")), + (2.0, _("Known exploits")), + ] exploitability = models.DecimalField( null=True, blank=True, - max_digits=4, - decimal_places=2, + max_digits=3, + decimal_places=1, + choices=EXPLOITABILITY_CHOICES, help_text=_( - "Exploitability indicates the likelihood that a vulnerability in a " - "software package could be used by malicious actors to compromise systems, " - "applications, or networks. This metric is determined automatically based " - "on the discovery of known exploits." + "Exploitability refers to the potential or probability of a software " + "package vulnerability being exploited by malicious actors to compromise " + "systems, applications, or networks. " + "It is determined automatically by discovery of exploits." ), ) weighted_severity = models.DecimalField( null=True, blank=True, - max_digits=4, - decimal_places=2, + max_digits=3, + decimal_places=1, help_text=_( "Weighted severity is the highest value calculated by multiplying each " "severity by its corresponding weight, divided by 10." @@ -126,10 +132,10 @@ class Vulnerability(HistoryDateFieldsMixin, DataspacedModel): risk_score = models.DecimalField( null=True, blank=True, - max_digits=4, - decimal_places=2, + max_digits=3, + decimal_places=1, help_text=_( - "Risk score from 0.00 to 10.00, with higher values indicating greater " + "Risk score from 0.0 to 10.0, with higher values indicating greater " "vulnerability risk. " "This score is the maximum of the weighted severity multiplied by " "exploitability, capped at 10." @@ -367,8 +373,8 @@ class AffectedByVulnerabilityMixin(models.Model): risk_score = models.DecimalField( null=True, blank=True, - max_digits=4, - decimal_places=2, + max_digits=3, + decimal_places=1, help_text=_( "Risk score between 0.00 and 10.00, where higher values " "indicate greater vulnerability risk for the package." diff --git a/vulnerabilities/templates/vulnerabilities/tables/vulnerability_list_table.html b/vulnerabilities/templates/vulnerabilities/tables/vulnerability_list_table.html index 4163a641..31ce7a20 100644 --- a/vulnerabilities/templates/vulnerabilities/tables/vulnerability_list_table.html +++ b/vulnerabilities/templates/vulnerabilities/tables/vulnerability_list_table.html @@ -36,7 +36,7 @@ {% endif %} - {{ vulnerability.exploitability|default_if_none:"" }} + {{ vulnerability.get_exploitability_display }} {{ vulnerability.weighted_severity|default_if_none:"" }}