Skip to content

Improve display of the Severity table of the Essentials screen #1976

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 2 commits 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
140 changes: 85 additions & 55 deletions vulnerabilities/templates/vulnerability_details.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
<li data-tab="epss">
<a>
<span>
EPSS
EPSS ({{ epss_severities|length }})
</span>
</a>
</li>
Expand Down Expand Up @@ -501,13 +501,15 @@
</tr>
{% endfor %}
</div>



<div class="tab-div content" data-content="epss">
{% if epss_data %}

{% if epss_severities %}
<div class="has-text-weight-bold tab-nested-div ml-1 mb-1 mt-1">
Exploit Prediction Scoring System (EPSS)
</div>

{% with first=epss_severities.0 %}
<table class="table vcio-table width-100-pct mt-2">
<tbody>
<tr>
Expand All @@ -517,7 +519,7 @@
Percentile
</span>
</td>
<td class="two-col-right">{{ epss_data.percentile }}</td>
<td class="two-col-right">{{ first.scoring_elements }}</td>
</tr>
<tr>
<td class="two-col-left">
Expand All @@ -526,71 +528,99 @@
EPSS Score
</span>
</td>
<td class="two-col-right">{{ epss_data.score }}</td>
<td class="two-col-right">{{ first.value }}</td>
</tr>
{% if epss_data.published_at %}
<tr>
<td class="two-col-left">
<span class="has-tooltip-multiline has-tooltip-black has-tooltip-arrow has-tooltip-text-left"
data-tooltip="Date when the EPSS score was published.">
Published At
</span>
</td>
<td class="two-col-right">{{ epss_data.published_at }}</td>
<td class="two-col-right">{{ first.published_at }}</td>
</tr>
{% endif %}
</tbody>
</table>
{% else %}
<p>No EPSS data available for this vulnerability.</p>
{% endif %}
</div>
{% endwith %}

<div class="tab-div content" data-content="history">
<table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth">
<thead>
<div class="has-text-weight-bold tab-nested-div ml-1 mb-1 mt-1">
EPSS History
</div>

<table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth gray-header-border">
<tr>
<th style="width: 100px;"> Score </th>
<th style="width: 100px;"> Percentile </th>
<th> Published At </th>
<th> Found at </th>
</tr>
{% for epss_severity in epss_severities %}
<tr>
<td class="wrap-strings">{{ epss_severity.value }}</td>
<td class="wrap-strings">{{ epss_severity.scoring_elements }}</td>
<td class="wrap-strings">{{ epss_severity.published_at }}</td>
<td class="wrap-strings">
<a href="{{ epss_severity.url }}" target="_blank">
{{ epss_severity.url }}
<i class="fa fa-external-link fa_link_custom"></i>
</a>
</td>
</tr>
{% endfor %}
</table>
{% else %}
<tr>
<th>
<span
class="has-tooltip-multiline has-tooltip-black has-tooltip-arrow has-tooltip-text-left"
data-tooltip="The date that the vulnerability was imported (collected) or improved.">
Date </span>
</th>
<th>
<span
class="has-tooltip-multiline has-tooltip-black has-tooltip-arrow has-tooltip-text-left"
data-tooltip="The process that created or updated the vulnerability."> Actor </span>
</th>
<th> <span
class="has-tooltip-multiline has-tooltip-black has-tooltip-arrow has-tooltip-text-left"
data-tooltip="Imported or Improved"> Action </span> </th>
<th> <span
class="has-tooltip-multiline has-tooltip-black has-tooltip-arrow has-tooltip-text-left"
data-tooltip="The public service that published the advisory or related information."> Source </span> </th>
<th> <span
class="has-tooltip-multiline has-tooltip-black has-tooltip-arrow has-tooltip-text-left"
data-tooltip="The version of VulnerableCode that performed the action. ">
VulnerableCode Version
</span> </th>
<td colspan="2">
No EPSS data available for this vulnerability.
</td>
</tr>
</thead>
{% for log in history %}
<tr>
<td class="is-break-word wrap-strings">{{ log.get_iso_time }}</td>
<td class="is-break-word wrap-strings">{{ log.actor_name }}</td>
<td class="is-break-word wrap-strings">{{ log.get_action_type_label }}</td>
<td class="is-break-word wrap-strings"> <a href="{{ log.source_url }}" target="_blank">{{log.source_url }}</a></td>
<td class="is-break-word wrap-strings"> {{ log.software_version }} </td>
</tr>
{% empty %}
<tr>
<td colspan="5">
There are no relevant records.
</td>
</tr>
{% endfor %}
</table>
{% endif %}
</div>
<div class="tab-div content" data-content="history">
<table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth">
<thead>
<tr>
<th>
<span
class="has-tooltip-multiline has-tooltip-black has-tooltip-arrow has-tooltip-text-left"
data-tooltip="The date that the vulnerability was imported (collected) or improved.">
Date </span>
</th>
<th>
<span
class="has-tooltip-multiline has-tooltip-black has-tooltip-arrow has-tooltip-text-left"
data-tooltip="The process that created or updated the vulnerability."> Actor </span>
</th>
<th> <span
class="has-tooltip-multiline has-tooltip-black has-tooltip-arrow has-tooltip-text-left"
data-tooltip="Imported or Improved"> Action </span> </th>
<th> <span
class="has-tooltip-multiline has-tooltip-black has-tooltip-arrow has-tooltip-text-left"
data-tooltip="The public service that published the advisory or related information."> Source </span> </th>
<th> <span
class="has-tooltip-multiline has-tooltip-black has-tooltip-arrow has-tooltip-text-left"
data-tooltip="The version of VulnerableCode that performed the action. ">
VulnerableCode Version
</span> </th>
</tr>
</thead>
{% for log in history %}
<tr>
<td class="is-break-word wrap-strings">{{ log.get_iso_time }}</td>
<td class="is-break-word wrap-strings">{{ log.actor_name }}</td>
<td class="is-break-word wrap-strings">{{ log.get_action_type_label }}</td>
<td class="is-break-word wrap-strings"> <a href="{{ log.source_url }}" target="_blank">{{log.source_url }}</a></td>
<td class="is-break-word wrap-strings"> {{ log.software_version }} </td>
</tr>
{% empty %}
<tr>
<td colspan="5">
There are no relevant records.
</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
</section>
Expand Down
29 changes: 14 additions & 15 deletions vulnerabilities/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# See https://aboutcode.org for more information about nexB OSS projects.
#
import logging
from datetime import datetime

from cvss.exceptions import CVSS2MalformedError
from cvss.exceptions import CVSS3MalformedError
Expand Down Expand Up @@ -305,12 +306,19 @@ def get_context_data(self, **kwargs):
if weakness_object.weakness
]

valid_severities = self.object.severities.exclude(scoring_system=EPSS.identifier).filter(
scoring_elements__isnull=False, scoring_system__in=SCORING_SYSTEMS.keys()
)
all_severities = list(self.object.severities.all().order_by("-published_at"))

severity_vectors = []
valid_severities = [
s
for s in all_severities
if s.scoring_system != EPSS.identifier
and s.scoring_elements is not None
and s.scoring_system in SCORING_SYSTEMS
]

epss_severities = [s for s in all_severities if s.scoring_system == EPSS.identifier]

severity_vectors = []
for severity in valid_severities:
try:
vector_values_system = SCORING_SYSTEMS[severity.scoring_system]
Expand All @@ -328,27 +336,18 @@ def get_context_data(self, **kwargs):
):
logging.error(f"CVSSMalformedError for {severity.scoring_elements}")

epss_severity = vulnerability.severities.filter(scoring_system="epss").first()
epss_data = None
if epss_severity:
epss_data = {
"percentile": epss_severity.scoring_elements,
"score": epss_severity.value,
"published_at": epss_severity.published_at,
}

context.update(
{
"vulnerability": vulnerability,
"vulnerability_search_form": VulnerabilitySearchForm(self.request.GET),
"severities": list(vulnerability.severities.all()),
"severities": list(self.object.severities.exclude(scoring_system=EPSS.identifier)),
"severity_vectors": severity_vectors,
"epss_severities": epss_severities,
"references": list(vulnerability.references.all()),
"aliases": list(vulnerability.aliases.all()),
"weaknesses": weaknesses_present_in_db,
"status": vulnerability.get_status_label,
"history": vulnerability.history,
"epss_data": epss_data,
}
)
return context
Expand Down