Skip to content

Commit

Permalink
Update affected-fixed package matching #1228
Browse files Browse the repository at this point in the history
Reference: #1228

Signed-off-by: John M. Horan <johnmhoran@gmail.com>
  • Loading branch information
johnmhoran committed Aug 8, 2023
1 parent 945b811 commit 6497e90
Show file tree
Hide file tree
Showing 6 changed files with 929 additions and 50 deletions.
663 changes: 624 additions & 39 deletions vulnerabilities/models.py

Large diffs are not rendered by default.

140 changes: 132 additions & 8 deletions vulnerabilities/templates/package_details.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
</div>

<div class="content ml-3 mr-3">
<div style="font-size: 15px; margin-bottom: 20px; padding: 10px; border: solid 1px #999999; border-radius: 5px; box-shadow: #505050 0px 5px 15px; line-height: 18px; color: #000000;">During testing, <span style="color: #ff0000; font-weight: 500;">red</span> = all packages that fix the vulnerability (<span style="font-style: italic;">for pkg in vulnerability.fixed_by_packages</span>) and <span style="color: #009933; font-weight: 500;">green</span> = the closest fixing package whose version is greater than the affected package's version (<span style="font-style: italic;">if pkg in get_fixing_packages</span>).</div>
<div class="has-text-weight-bold ml-1 mb-0">
Affected by vulnerabilities ({{ affected_by_vulnerabilities|length }})
</div>
Expand All @@ -52,7 +51,7 @@
<th style="width: 175px;">Vulnerability</th>
<th>Summary</th>
<th style="width: 225px;">Aliases</th>
<th style="width: 300px;">Fixing Packages</th>
<th style="width: 300px;">Fixed by packages</th>
</tr>
</thead>

Expand All @@ -76,22 +75,147 @@
{% endif %}
{% endfor %}
</td>
<td style="color: #ff0000;">
<td style="color: #ff0000; word-wrap: break-word; word-break: break-all;">
<!-- <span class="dev_fixed_by_headers">START 'for pkg in vulnerability.fixed_by_packages'</span>
{% for pkg in vulnerability.fixed_by_packages %}
<div style="font-size: 13px; padding: 0px 0px 5px 0px; line-height: 18px;">
<div style="font-size: 13px; padding: 0px 0px 5px 0px; line-height: 17px;">
{{ pkg.purl }}
</div>
{% endfor %}
<span class="dev_fixed_by_headers">END 'for pkg in vulnerability.fixed_by_packages'</span>
<hr style="border-top: solid 1px #d8d8d8;">
<hr style="border-top: solid 1px #d8d8d8;"> -->

<!-- <span class="dev_fixed_by_headers">START 'get_closest_fixed_package' context</span>
{% for pkg in vulnerability.fixed_by_packages %}
{% if pkg in get_fixing_packages %}
<div style="font-size: 13px; padding: 0px 0px 5px 0px; line-height: 18px;">
{% if pkg in get_closest_fixed_package %}
<div style="font-size: 13px; padding: 0px 0px 5px 0px; line-height: 17px;">
<span style="color: #009933;">{{ pkg.purl }}</span>
</div>
{% endif %}
{% endfor %}
<br />
<span style="color: #cc0099; font-size: 13px; padding: 0px 0px 5px 0px; font-weight: none;">get_closest_fixed_package list:</span>
<br />
<div style="color: #cc0099; font-size: 13px; padding: 0px 0px 5px 0px;">{{ get_closest_fixed_package }}</div>
<br />
<div style="color: #996633; font-size: 13px; padding: 0px 0px 5px 0px;">
<span class="dev_fixed_by_headers">END 'get_closest_fixed_package' context</span>
<br /><br /> -->


<!-- <span class="dev_fixed_by_headers">START 'fixed_package_details' context</span> -->

{% if package.purl in fixed_package_details.purl %}
{% for key, value in fixed_package_details.items %}
{% if key == "vulnerabilities" %}
{% for abc in value %}
{% if abc.vulnerability == vulnerability.vulnerability_id %}
<ul class="fixed_by_bullet" style="color: #000000;">
<li>
<span style="font-weight: bold;">PURL:</span> {{ fixed_package_details.purl }}

<!-- <div class="dropdown is-hoverable has-text-weight-normal is-right">
<div class="dropdown-trigger">
<i class="fa fa-question-circle ml-2 fa-lg has-background-white has-text-link"></i>
</div>
<div class="dropdown-menu dropdown-vuln-dict-width" id="dropdown-menu4" role="menu">
<div class="dropdown-content dropdown-instructions-box-shadow">
<div class="dropdown-item">
<div style="max-height: 300px; overflow-y: auto;">
This is a dictionary created as part of this affected-fixed matching work:
<div style="padding-top: 5px;">
{% for key, value in fixed_package_details.items %}
{{ key }}: {{ value }}
<br />
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div> -->

</li>
<li>
<span style="font-weight: bold;">Vulnerability:</span> {{ abc.vulnerability }}
</li>
<li>
<span style="font-weight: bold;">Closest fixed-by PURL:</span>
<a href="{{ abc.closest_fixed_by_url }}?search={{ abc.closest_fixed_by_purl }}" target="_self">{{ abc.closest_fixed_by_purl }}</a>
</li>
<li>
<span style="font-weight: bold;">Closest fixed-by vulnerability count:</span> {{ abc.closest_fixed_by_vulnerabilities|length }}
{% if abc.closest_fixed_by_vulnerabilities|length != 0 %}
<div class="dropdown is-hoverable has-text-weight-normal is-right">
<div class="dropdown-trigger">
<i class="fa fa-question-circle ml-2 fa-lg has-background-white has-text-danger"></i>
</div>
<div class="dropdown-menu dropdown-vuln-list-width" id="dropdown-menu4" role="menu">
<div class="dropdown-content dropdown-instructions-box-shadow">
<div class="dropdown-item">
<div style="max-height: 300px; overflow-y: auto;">
The <strong>closest fixed-by PURL</strong> has {{ abc.closest_fixed_by_vulnerabilities|length }}
{% if abc.closest_fixed_by_vulnerabilities|length == 1 %}
vulnerability:
{% else %}
vulnerabilities:
{% endif %}
<div style="padding-top: 5px;">
<!-- ALERT: We're using the namedtuple here -- but a dict might be better because we need the values as keyt-value pairs in the purl_dict we create in models.py. ATM all we have is the 2 values as items in a list, e.g.,
"closest_fixed_by_vulnerabilities": [
[
"VCID-t7e4-g3fr-aaan",
"/vulnerabilities/VCID-t7e4-g3fr-aaan"
]
]
-->
{% for closest_vuln in abc.closest_fixed_by_vulnerabilities %}
<div>
<a href="{{ closest_vuln.vuln_get_absolute_url }}" target="_self">{{ closest_vuln.vuln_id }}</a>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endif %}
</li>
<li style="border-top: solid 1px #cccccc; margin-top: 10px; padding-top: 10px;">
<span style="font-weight: bold;">Closest non-vulnerable fix:</span>
<!-- <a href="{{ abc.closest_non_vulnerable_fix_url }}?search={{ abc.closest_non_vulnerable_fix }}" target="_self">{{ abc.closest_non_vulnerable_fix }}</a> -->
<!-- 2023-08-07 Monday 16:34:43. Replace with higher-level key-value pair -->
<a href="{{ fixed_package_details.closest_non_vulnerable_fix_url }}?search={{ fixed_package_details.closest_non_vulnerable_fix }}" target="_self">{{ fixed_package_details.closest_non_vulnerable_fix }}</a>
</li>
<li>
<span style="font-weight: bold;">Most recent non-vulnerable fix:</span>
<!-- <a href="{{ abc.most_recent_non_vulnerable_fix_url }}?search={{ abc.most_recent_non_vulnerable_fix }}" target="_self">{{ abc.most_recent_non_vulnerable_fix }}</a> -->
<!-- 2023-08-07 Monday 16:34:43. Replace with higher-level key-value pair -->
<a href="{{ fixed_package_details.most_recent_non_vulnerable_fix_url }}?search={{ fixed_package_details.most_recent_non_vulnerable_fix }}" target="_self">{{ fixed_package_details.most_recent_non_vulnerable_fix }}</a>
</li>
</ul>
{% endif %}
{% endfor %}


{% endif %}
{% endfor %}
{% else %}
NO-- {{ package.purl }}
{% endif %}


<!-- <span class="dev_fixed_by_headers">END 'fixed_package_details' context</span> -->


</div>

</td>
</tr>
Expand All @@ -109,7 +233,7 @@

<div class="content ml-3 mr-3">
<div class="has-text-weight-bold ml-1 mb-0">
Fixing vulnerabilities ({{ fixing_vulnerabilities|length }})
Fixed by vulnerabilities ({{ fixing_vulnerabilities|length }})
</div>

<table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth">
Expand Down
65 changes: 65 additions & 0 deletions vulnerabilities/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
# See https://aboutcode.org for more information about nexB OSS projects.
#

import urllib.parse
from datetime import datetime
from unittest import TestCase

import pytest
from django.db.utils import IntegrityError
from freezegun import freeze_time
from univers import versions

from vulnerabilities import models

Expand Down Expand Up @@ -88,3 +90,66 @@ def test_vulnerability_package(self):

assert v1.vulnerable_packages.all()[0] == p1
assert v1.patched_packages.all()[0] == p2


@pytest.mark.django_db
class TestPackageModel(TestCase):
def test_univers_version_comparisons(self):
assert versions.PypiVersion("1.2.3") < versions.PypiVersion("1.2.4")

assert versions.PypiVersion("0.9") < versions.PypiVersion("0.10")

# pkg:deb/debian/jackson-databind@2.12.1-1%2Bdeb11u1 is a real PURL in the DB
# But I get an error when I try to compare 2 PURLs with the same suffix --
# univers.versions.InvalidVersion: '2.12.1-1%2Bdeb11u1' is not a valid <class 'univers.versions.DebianVersion'>
# Do we need to replace/delete the "%"?
# assert versions.DebianVersion("2.12.1-1%2Bdeb11u1") < versions.DebianVersion(
# "2.13.1-1%2Bdeb11u1"
# )
# Test the error
with pytest.raises(versions.InvalidVersion):
assert versions.DebianVersion("2.12.1-1%2Bdeb11u1") < versions.DebianVersion(
"2.13.1-1%2Bdeb11u1"
)
# Decode the version and test.
assert versions.DebianVersion(
urllib.parse.unquote("2.12.1-1%2Bdeb11u1")
) < versions.DebianVersion(urllib.parse.unquote("2.13.1-1%2Bdeb11u1"))

with pytest.raises(TypeError):
assert versions.PypiVersion("0.9") < versions.DebianVersion("0.10")

# Using versions.Version does not correctly make this comparison!
assert not versions.Version("0.9") < versions.Version("0.10")
# Use SemverVersion instead as a default fallback version for comparisons.
assert versions.SemverVersion("0.9") < versions.SemverVersion("0.10")

def test_assign_and_compare_univers_versions(self):
deb01 = models.Package.objects.create(type="deb", name="git", version="2.30.1")
deb02 = models.Package.objects.create(type="deb", name="git", version="2.31.1")

immediate_fix01 = deb01.assign_and_compare_univers_versions(deb02)
print("\nimmediate_fix01 = {}\n".format(immediate_fix01))
# assert deb01.assign_and_compare_univers_versions(deb02) is True
assert deb01.assign_and_compare_univers_versions(deb02)

immediate_fix02 = deb02.assign_and_compare_univers_versions(deb01)
print("\nimmediate_fix02 = {}\n".format(immediate_fix02))
# assert deb02.assign_and_compare_univers_versions(deb01) is False
assert not deb02.assign_and_compare_univers_versions(deb01)

pypi01 = models.Package.objects.create(type="pypi", name="pyopenssl", version="0.9")
pypi02 = models.Package.objects.create(type="pypi", name="pyopenssl", version="0.10")

immediate_fix03 = pypi01.assign_and_compare_univers_versions(pypi02)
print("\nimmediate_fix03 = {}\n".format(immediate_fix03))
# assert pypi01.assign_and_compare_univers_versions(pypi02) is True
assert pypi01.assign_and_compare_univers_versions(pypi02)

gem01 = models.Package.objects.create(type="gem", name="sidekiq", version="0.9")
gem02 = models.Package.objects.create(type="gem", name="sidekiq", version="0.10")

immediate_fix04 = gem01.assign_and_compare_univers_versions(gem02)
print("\nimmediate_fix04 = {}\n".format(immediate_fix04))
# assert gem01.assign_and_compare_univers_versions(gem02) is True
assert gem01.assign_and_compare_univers_versions(gem02)
5 changes: 4 additions & 1 deletion vulnerabilities/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,10 @@ def get_context_data(self, **kwargs):
context["affected_by_vulnerabilities"] = package.affected_by.order_by("vulnerability_id")
context["fixing_vulnerabilities"] = package.fixing.order_by("vulnerability_id")
context["package_search_form"] = PackageSearchForm(self.request.GET)
context["get_fixing_packages"] = package.get_fixing_packages
# context["get_fixing_packages"] = package.get_fixing_packages
context["get_closest_fixed_package"] = package.get_closest_fixed_package
# context["test_property_01"] = package.test_property_01
context["fixed_package_details"] = package.fixed_package_details

return context

Expand Down
4 changes: 3 additions & 1 deletion vulnerablecode/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
CSRF_TRUSTED_ORIGINS = env.list("CSRF_TRUSTED_ORIGINS", default=[])

# SECURITY WARNING: do not run with debug turned on in production
DEBUG = env.bool("VULNERABLECODE_DEBUG", default=False)
# DEBUG = env.bool("VULNERABLECODE_DEBUG", default=False)
# DEBUG = "127.0.0.1"
DEBUG = True

# SECURITY WARNING: do not run with debug turned on in production
DEBUG_TOOLBAR = env.bool("VULNERABLECODE_DEBUG_TOOLBAR", default=False)
Expand Down
102 changes: 101 additions & 1 deletion vulnerablecode/static/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,14 @@ a.small_page_button {
box-shadow: 0px 8px 16px 0px #808080;
}

.dropdown-vuln-list-width {
width: 400px;
}

.dropdown-vuln-dict-width {
max-width: 600px;
}

.width-100-pct {
width: 100%;
}
Expand Down Expand Up @@ -368,4 +376,96 @@ a.small_page_button {

span.tag.custom {
margin: 0px 0px 6px 10px;
}
}

/* test bulleted list */

ul.fixed_by_bullet {
list-style-type: disc;
/*margin-top: 2px;
margin-bottom: 10px;*/
/*margin-left: -24px;*/
/*margin-left: -30px;*/
margin-top: 0.25em;
margin-left: 7px;
margin-bottom: 0.25em;
padding-left: 10px;
}

ul.fixed_by_bullet ul {
list-style-type: disc;
/*margin-top: 10px;*/
margin-top: 5px;
margin-top: 0px;
margin-bottom: 0px;
margin-left: 23px;
margin-left: 18px;
padding: 0;
border: none;
}



ul.fixed_by_bullet li {
margin-left: 0px;
font-family: Arial;
font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
font-size: 13px;
font-weight: normal;
/*margin-bottom: 10px;*/
margin-bottom: 2px;
}

ul.fixed_by_bullet li:last-child {
margin-left: 0px;
font-family: Arial;
font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
font-size: 13px;
font-weight: normal;
/*margin-bottom: 10px;*/
margin-bottom: 0px;
}

ul.fixed_by_bullet li li {
margin-left: 0px;
font-family: Arial;
font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
font-size: 13px;
font-weight: normal;
margin-top: 0px;
color: #000000;
}

/* 10/10/15 add 3rd-level bullets */
ul.fixed_by_bullet ul ul {
list-style-type: disc;
margin-top: 0px;
margin-bottom: 0px;
margin-left: 50px;
margin-left: 17px;
padding: 0;
border: none;
}

ul.fixed_by_bullet li li li {
margin-left: 0px;
font-family: Arial;
font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
font-size: 13px;
font-weight: normal;
margin-top: 0px;
color: #000000;
}

/* CSS for dev fixed by headers */
.dev_fixed_by_headers {
border: solid 1px #cccccc;
border-radius: 3px;
background-color: #f2f2f2;
color: #000000;
font-weight: bold;
font-size: 13px;
padding: 3px;
margin-bottom: 3px;
display: block;
}

0 comments on commit 6497e90

Please sign in to comment.