Skip to content

Add CVSS4 support #12751

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 25 commits into
base: dev
Choose a base branch
from
Open

Conversation

valentijnscholten
Copy link
Member

@valentijnscholten valentijnscholten commented Jul 6, 2025

Fixes #12445

  • add cvssv4 and cvss4_score fields to Finding model
  • add score calculation/sanitization similar to what was done for cvssv3 field
  • update UI to show both vectors when present
  • update auditjs parser + tests
  • update parse_cvss_data to accomodate more use cases
  • add links to external calculators to relevant forms
  • update how to write a parser guide
  • add system_settings to allow hiding of cvssv3 fields or cvssv4 fields

vectors

image

QUESTIONS:
- Is it right to have the fields separated so we can support v3 anv v4 in parallel?
- Or should we converge this into cvss, cvss_score and cvss_version and prefer v4 over v3 if both are provided? This could be a problem for companies still tied to v3 in their compliance asessments?
- We could do both. Leave the PR as is, but also add these "merged" fields where we take the values from v4 if present else from v3 (or None otherwise)
- Do we want to embed a JS calculator again? The First/RedHat calculator is Vue based. The metaeffekt calculator is standalone JS:
- https://www.first.org/cvss/calculator/4-0
- https://www.metaeffekt.com/security/cvss/calculator/

@github-actions github-actions bot added New Migration Adding a new migration file. Take care when merging. unittests parser docker settings_changes Needs changes to settings.py based on changes in settings.dist.py included in this PR docs integration_tests ui labels Jul 6, 2025
@github-actions github-actions bot removed docker settings_changes Needs changes to settings.py based on changes in settings.dist.py included in this PR docs integration_tests labels Jul 7, 2025
@Maffooch
Copy link
Contributor

Maffooch commented Jul 7, 2025

QUESTIONS:

  • Is it right to have the fields separated so we can support v3 anv v4 in parallel?
  • Or should we converge this into cvss, cvss_score and cvss_version and prefer v4 over v3 if both are provided? This could be a problem for companies still tied to v3 in their compliance asessments?
  • We could do both. Leave the PR as is, but also add these "merged" fields where we take the values from v4 if present else from v3 (or None otherwise)

I think it would best to keep the two fields separate for now. As you mentioned, there are likely some companies that are reliant on v3 for compliance purposes. We also want to avoid potentially breaking changes in existing automation.

Add UI calculator

While I don't love the idea of embedding another big snippet of html on the view finding page, it would be consistent with the current behavior of v3. Being consistent would be ideal, but I am not sure it is worth the cost. Another option would be to link out to that universal calculator for both calculators. @mtesauro what do you think?

@valentijnscholten
Copy link
Member Author

I also considered linking out, but some companies might not like some external services being accessed. We could also link out to our own copy of that UI calculator hosted from within Defect Dojo. We could get rid of the old ugly one and just open the new one in a window. We could start with that and then see if there is a need for more integration like auto transfer for vectors between screens and whatnot. That would be the easiest for the Pro UI as well.

@github-actions github-actions bot added the docs label Jul 7, 2025
@valentijnscholten valentijnscholten added this to the 2.49.0 milestone Jul 7, 2025
@mtesauro
Copy link
Contributor

mtesauro commented Jul 8, 2025

QUESTIONS:

  • Is it right to have the fields separated so we can support v3 anv v4 in parallel?
  • Or should we converge this into cvss, cvss_score and cvss_version and prefer v4 over v3 if both are provided? This could be a problem for companies still tied to v3 in their compliance asessments?
  • We could do both. Leave the PR as is, but also add these "merged" fields where we take the values from v4 if present else from v3 (or None otherwise)

I think it would best to keep the two fields separate for now. As you mentioned, there are likely some companies that are reliant on v3 for compliance purposes. We also want to avoid potentially breaking changes in existing automation.

I agree with this as well

Add UI calculator

While I don't love the idea of embedding another big snippet of html on the view finding page, it would be consistent with the current behavior of v3. Being consistent would be ideal, but I am not sure it is worth the cost. Another option would be to link out to that universal calculator for both calculators. @mtesauro what do you think?

It's probably best to include whatever we what displayed by default in DefectDojo in the source code aka shipped in our containers as we cannot rely on outbound connectivity for any default feature of DefectDojo.
So, I see the options as:

  1. Follow the same process as CVSSv3 and include the code for the calculator in our containers/source
  2. Default to no CVSSv4 calculator and have people opt-in to having it call out to an external resource. This resource would default to First's calculator but allow people to update to a different URL should they choose or need to because of network restrictions, policy, whatever.

Other thoughts on the CVSS calculators:

  • It makes sense to me to have both v3 and v4 be optionally displayed. As much we have plenty of System Settings, this makes sense to me especially as we start to deprecate v3. This is something we should do as we adopt v4.
  • In an ideal world, both calculators would be overlays/pop-out UIs that don't busy up the edit finding UI any more then they currently are but that's more of an 'icing on the cake' and maybe we bake the v4 cake first. That nicer UI could be some follow-on work that someone in the community with good UI foo can tackle.

@valentijnscholten valentijnscholten marked this pull request as ready for review July 9, 2025 20:06
Copy link

dryrunsecurity bot commented Jul 9, 2025

DryRun Security

🟡 Please give this pull request extra attention during review.

This pull request contains multiple security findings, including a potential ReDoS vulnerability in CVSS vector parsing, a command injection risk in a test script, an information disclosure issue with CVSS vector display, and a potential cross-site scripting (XSS) vulnerability in the BulletListDisplayWidget's render method, with varying risk levels but none currently blocking the merge.

🟡 Potential Cross-Site Scripting in dojo/forms.py
Vulnerability Potential Cross-Site Scripting
Description The code is potentially vulnerable to XSS in the BulletListDisplayWidget's render method. The method directly constructs HTML using f-strings with unsanitized user-controlled input (urls_dict). While mark_safe() is used, which can bypass escaping, the method does not validate or sanitize the URLs and text before inserting them into the HTML. An attacker could potentially provide malicious URLs or text containing script tags that would be rendered directly in the HTML. For example, a URL or text value containing '<script>alert("XSS")</script>' could be executed in the browser.

EFFORT_FOR_FIXING_INVALID_CHOICE = _("Select valid choice: Low,Medium,High")
class BulletListDisplayWidget(forms.Widget):
def __init__(self, urls_dict=None, *args, **kwargs):
self.urls_dict = urls_dict or {}
super().__init__(*args, **kwargs)
def render(self, name, value, attrs=None, renderer=None):
if not self.urls_dict:
return ""
html = '<ul style="margin: 0; padding-left: 20px;">'
for url, text in self.urls_dict.items():
html += f'<li style="list-style-type: disc;"><a href="{url}" target="_blank"><i class="fa fa-arrow-up-right-from-square" style="margin-right: 5px;"></i>{text}</a></li>'
html += "</ul>"
return mark_safe(html)
class MultipleSelectWithPop(forms.SelectMultiple):
def render(self, name, *args, **kwargs):
html = super().render(name, *args, **kwargs)

Potential ReDoS in CVSS Vector Parsing in dojo/utils.py
Vulnerability Potential ReDoS in CVSS Vector Parsing
Description The parse_cvss_from_text function uses a regular expression that could potentially be vulnerable to catastrophic backtracking, allowing an attacker to craft input that consumes excessive CPU resources.

import bleach
import crum
import hyperlink
import vobject
from asteval import Interpreter
from auditlog.models import LogEntry
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cvss import CVSS2, CVSS3, CVSS4, CVSSError
from dateutil.parser import parse
from dateutil.relativedelta import MO, SU, relativedelta
from django.conf import settings

Command Injection in Test Script in run-unittest.sh
Vulnerability Command Injection in Test Script
Description The unittest shell script allows arbitrary command injection through the TEST_CASE parameter. An attacker can execute shell commands within the Docker container by crafting a malicious test case input.

#!/usr/bin/env bash
unset TEST_CASE
unset FAIL_FAST
bash ./docker/docker-compose-check.sh
if [[ $? -eq 1 ]]; then exit 1; fi

Information Disclosure via CVSS Vector Display in dojo/templates/dojo/view_finding.html
Vulnerability Information Disclosure via CVSS Vector Display
Description The patch exposes detailed CVSS vector strings in tooltips, which could provide attackers with granular information about vulnerability details that might aid in further reconnaissance.

<td>
<span class="label severity severity-{{ finding.severity }}">
{% if finding.severity %}
{{ finding.severity_display }}
{% if system_settings.enable_cvss4_display and finding.cvssv4_score or system_settings.enable_cvss3_display and finding.cvssv3_score %}
<i class="no-italics has-popover" font-style="normal" data-toggle="tooltip" data-placement="bottom" data-container="body" data-html="true" title="" href="#"
data-content="{% if system_settings.enable_cvss4_display and finding.cvssv4 %}{{ finding.cvssv4 }} ({{ finding.cvssv4_score }}){% endif %}{% if system_settings.enable_cvss4_display and finding.cvssv4 and system_settings.enable_cvss3_display and finding.cvssv3 %}<br/>{% endif %}{% if system_settings.enable_cvss3_display and finding.cvssv3 %}{{ finding.cvssv3 }} ({{ finding.cvssv3_score }}){% endif %}">
({% if system_settings.enable_cvss4_display and finding.cvssv4_score %}{{ finding.cvssv4_score }}{% if system_settings.enable_cvss3_display and finding.cvssv3_score %}, {% endif %}{% endif %}{% if system_settings.enable_cvss3_display and finding.cvssv3_score %}{{ finding.cvssv3_score }}{% endif %})</i>
{% endif %}
{% else %}
Unknown


All finding details can be found in the DryRun Security Dashboard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs integration_tests New Migration Adding a new migration file. Take care when merging. parser ui unittests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants