Skip to content
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

Fix : Improved Severity table of the Essentials screen #1816

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 97 additions & 58 deletions vulnerabilities/templates/vulnerability_details.html
Original file line number Diff line number Diff line change
Expand Up @@ -197,64 +197,103 @@

<!-- New Severities Tab -->
<div class="tab-div content" data-content="severities">
<table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth gray-header-border">
<tr>
<th style="width: 160px;"> System </th>
<th style="width: 100px;"> Score </th>
<th> Found at </th>
</tr>
{% for severity in severities %}
<tr>
<td class="wrap-strings">{{ severity.scoring_system }}</td>
<td class="wrap-strings">{{ severity.value }}</td>
<td class="wrap-strings"><a href="{{ severity.url }}" target="_blank">
{{ severity.url }}<i class="fa fa-external-link fa_link_custom"></i></a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="3">
There are no known severity scores.
</td>
</tr>
{% endfor %}
</table>
</div>

<div class="tab-div content" data-content="references">
<table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth">
<thead>
<tr>
<th style="width: 250px;"> Reference id </th>
<th style="width: 250px;"> Reference type </th>
<th> URL </th>
</tr>
</thead>
{% for ref in references %}
<tr>
{% if ref.reference_id %}
<td class="wrap-strings">{{ ref.reference_id }}</td>
{% else %}
<td></td>
{% endif %}

{% if ref.reference_type %}
<td class="wrap-strings">{{ ref.get_reference_type_display }}</td>
{% else %}
<td></td>
{% endif %}

<td class="wrap-strings"><a href="{{ ref.url }}" target="_blank">{{ ref.url }}<i
class="fa fa-external-link fa_link_custom"></i></a></td>
</tr>
{% empty %}
<tr>
<td colspan="2">
There are no known references.
</td>
</tr>
{% endfor %}
</table>
<h3 class="title is-5">Severity Scores by Source</h3>

{% regroup severities|dictsort:"url" by url as severities_by_url %}

{% for url_group in severities_by_url %}
<div class="box mb-4">
<h5 class="title is-6">
<a href="{{ url_group.grouper }}" target="_blank" class="has-text-link">
{{ url_group.grouper|default:"Unknown Source" }}
<i class="fa fa-external-link fa_link_custom"></i>
</a>
</h5>

<!-- CVSS scores section -->
<div class="mb-3">
<h6 class="title is-7">CVSS Scores</h6>
<table class="table is-bordered is-narrow is-hoverable is-fullwidth">
<thead>
<tr>
<th>Source</th>
<th>CVSS Version</th>
<th>Score</th>
<th>Textual Severity</th>
</tr>
</thead>
<tbody>
{% for entry in cvss_entries %}
<tr>
<td>
<a href="{{ entry.reference }}" title="{{ entry.reference }}">
{{ entry.reference|truncatechars:40 }}
</a>
</td>
<td>{{ entry.version }}</td>
<td>{{ entry.score|default:"-" }}</td>
<td>{{ entry.text|default:"-" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

<!-- EPSS scores section -->
{% if epss_entries %}
<div class="mb-3">
<h6 class="title is-7">EPSS Scores</h6>
<table class="table is-bordered is-narrow is-hoverable is-fullwidth">
<thead>
<tr>
<th>Source</th>
<th>Score</th>
</tr>
</thead>
<tbody>
{% for entry in epss_entries %}
<tr>
<td>
<a href="{{ entry.reference }}" title="{{ entry.reference }}">
{{ entry.reference|truncatechars:40 }}
</a>
</td>
<td>{{ entry.score }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}

<!-- Other scores section -->
<div class="mb-3">
<h6 class="title is-7">Other Scores</h6>
<table class="table is-bordered is-narrow is-hoverable is-fullwidth">
<thead>
<tr>
<th>Scoring System</th>
<th>Score</th>
</tr>
</thead>
<tbody>
{% for severity in url_group.list %}
{% if "cvss" not in severity.scoring_system and severity.scoring_system != "epss" %}
<tr>
<td>{{ severity.scoring_system }}</td>
<td>{{ severity.value }}</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div>
{% empty %}
<div class="notification">
There are no known severity scores.
</div>
{% endfor %}
</div>

<div class="tab-div content" data-content="exploits">
Expand Down
43 changes: 43 additions & 0 deletions vulnerabilities/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,49 @@
PAGE_SIZE = 20


def vulnerability_details(request, vulnerability_id):
vulnerability = get_object_or_404(Vulnerability, pk=vulnerability_id)
severities = vulnerability.severities.all()

# Process CVSS entries
cvss_entries = {}
for sev in severities:
system_lower = sev.system.lower()
if system_lower.startswith("cvss"):
version = system_lower.replace("cvssv", "").upper()
key = (sev.reference, version)
if key not in cvss_entries:
cvss_entries[key] = {"score": None, "text": None}
# Check if value is numerical or textual
try:
float(sev.value)
cvss_entries[key]["score"] = sev.value
except ValueError:
cvss_entries[key]["text"] = sev.value

cvss_list = [
{"reference": key[0], "version": key[1], "score": entry["score"], "text": entry["text"]}
for key, entry in cvss_entries.items()
]

# Process EPSS entries, deduplicate
epss_entries = {}
for sev in severities:
if sev.system.lower() == "epss":
key = (sev.reference, sev.value)
if key not in epss_entries:
epss_entries[key] = sev.value

epss_list = [{"reference": key[0], "score": key[1]} for key in epss_entries]

context = {
"vulnerability": vulnerability,
"cvss_entries": cvss_list,
"epss_entries": epss_list,
}
return render(request, "vulnerability_details.html", context)


class PackageSearch(ListView):
model = models.Package
template_name = "packages.html"
Expand Down