Skip to content

Commit 11137de

Browse files
authored
Merge pull request #11144 from DefectDojo/release/2.39.3
Release: Merge release into master from: release/2.39.3
2 parents 84ac4a0 + c603db2 commit 11137de

15 files changed

Lines changed: 156 additions & 30 deletions

File tree

.github/ISSUE_TEMPLATE/support_request.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ assignees: ''
77

88
---
99
**Slack us first!**
10-
The easiest and fastest way to help you is via Slack. There's a free and easy signup to join our #defectdojo channel in the OWASP Slack workspace: [Get Access.](https://owasp-slack.herokuapp.com/)
10+
The easiest and fastest way to help you is via Slack. There's a free and easy signup to join our #defectdojo channel in the OWASP Slack workspace: [Get Access.](https://owasp.org/slack/invite)
1111
If you're confident you've found a bug, or are allergic to Slack, you can submit an issue anyway.
1212

1313
**Be informative**

components/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "defectdojo",
3-
"version": "2.39.2",
3+
"version": "2.39.3",
44
"license" : "BSD-3-Clause",
55
"private": true,
66
"dependencies": {

dojo/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
# Django starts so that shared_task will use this app.
55
from .celery import app as celery_app # noqa: F401
66

7-
__version__ = "2.39.2"
7+
__version__ = "2.39.3"
88
__url__ = "https://github.com/DefectDojo/django-DefectDojo"
99
__docs__ = "https://documentation.defectdojo.com"

dojo/engagement/views.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from django.db import DEFAULT_DB_ALIAS
1818
from django.db.models import Count, Q
1919
from django.db.models.query import Prefetch, QuerySet
20-
from django.http import FileResponse, HttpRequest, HttpResponse, HttpResponseRedirect, QueryDict, StreamingHttpResponse
20+
from django.http import HttpRequest, HttpResponse, HttpResponseRedirect, QueryDict, StreamingHttpResponse
2121
from django.shortcuts import get_object_or_404, render
2222
from django.urls import Resolver404, reverse
2323
from django.utils import timezone
@@ -100,6 +100,7 @@
100100
add_success_message_to_response,
101101
async_delete,
102102
calculate_grade,
103+
generate_file_response_from_file_path,
103104
get_cal_event,
104105
get_page_items,
105106
get_return_url,
@@ -1516,7 +1517,7 @@ def upload_threatmodel(request, eid):
15161517
@user_is_authorized(Engagement, Permissions.Engagement_View, "eid")
15171518
def view_threatmodel(request, eid):
15181519
eng = get_object_or_404(Engagement, pk=eid)
1519-
return FileResponse(open(eng.tmodel_path, "rb"))
1520+
return generate_file_response_from_file_path(eng.tmodel_path)
15201521

15211522

15221523
@user_is_authorized(Engagement, Permissions.Engagement_View, "eid")

dojo/forms.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,23 @@ class UploadThreatForm(forms.Form):
752752
attrs={"accept": ".jpg,.png,.pdf"}),
753753
label="Select Threat Model")
754754

755+
def clean(self):
756+
if (file := self.cleaned_data.get("file", None)) is not None:
757+
ext = os.path.splitext(file.name)[1] # [0] returns path+filename
758+
valid_extensions = [".jpg", ".png", ".pdf"]
759+
if ext.lower() not in valid_extensions:
760+
if accepted_extensions := f"{', '.join(valid_extensions)}":
761+
msg = (
762+
"Unsupported extension. Supported extensions are as "
763+
f"follows: {accepted_extensions}"
764+
)
765+
else:
766+
msg = (
767+
"File uploads are prohibited due to the list of acceptable "
768+
"file extensions being empty"
769+
)
770+
raise ValidationError(msg)
771+
755772

756773
class MergeFindings(forms.ModelForm):
757774
FINDING_ACTION = (("", "Select an Action"), ("inactive", "Inactive"), ("delete", "Delete"))

dojo/jira_link/helper.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,13 @@ def can_be_pushed_to_jira(obj, form=None):
159159
elif isinstance(obj, Finding_Group):
160160
if not obj.findings.all():
161161
return False, f"{to_str_typed(obj)} cannot be pushed to jira as it is empty.", "error_empty"
162-
if "Active" not in obj.status():
162+
# Accommodating a strange behavior where a finding group sometimes prefers `obj.status` rather than `obj.status()`
163+
try:
164+
not_active = "Active" not in obj.status()
165+
except TypeError: # TypeError: 'str' object is not callable
166+
not_active = "Active" not in obj.status
167+
# Determine if the finding group is not active
168+
if not_active:
163169
return False, f"{to_str_typed(obj)} cannot be pushed to jira as it is not active.", "error_inactive"
164170

165171
else:
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
42026ac47884ee26fe742e59fb7dc621b5f927ee6ee3c92daf09b97f2a740163
1+
002b28325f11793c5aa9f09326c2d5cc66de518cce51b2cb4cb681a920b89909

dojo/settings/settings.dist.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,6 +1736,7 @@ def saml2_attrib_map_format(dict):
17361736
"USN": "https://ubuntu.com/security/notices/", # e.g. https://ubuntu.com/security/notices/USN-6642-1
17371737
"DLA": "https://security-tracker.debian.org/tracker/", # e.g. https://security-tracker.debian.org/tracker/DLA-3917-1
17381738
"ELSA": "https://linux.oracle.com/errata/&&.html", # e.g. https://linux.oracle.com/errata/ELSA-2024-12714.html
1739+
"RXSA": "https://errata.rockylinux.org/", # e.g. https://errata.rockylinux.org/RXSA-2024:4928
17391740
}
17401741
# List of acceptable file types that can be uploaded to a given object via arbitrary file upload
17411742
FILE_UPLOAD_TYPES = env("DD_FILE_UPLOAD_TYPES")

dojo/tools/osv_scanner/parser.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,34 @@ def get_findings(self, file, test):
3030
except json.decoder.JSONDecodeError:
3131
return []
3232
findings = []
33-
for result in data["results"]:
34-
source_path = result["source"]["path"]
35-
source_type = result["source"]["type"]
36-
for package in result["packages"]:
37-
package_name = package["package"]["name"]
38-
package_version = package["package"]["version"]
39-
package_ecosystem = package["package"]["ecosystem"]
40-
for vulnerability in package["vulnerabilities"]:
33+
for result in data.get("results", []):
34+
# Extract source locations if present
35+
source_path = result.get("source", {}).get("path", "")
36+
source_type = result.get("source", {}).get("type", "")
37+
for package in result.get("packages", []):
38+
package_name = package.get("package", {}).get("name")
39+
package_version = package.get("package", {}).get("version")
40+
package_ecosystem = package.get("package", {}).get("ecosystem", "")
41+
for vulnerability in package.get("vulnerabilities", []):
4142
vulnerabilityid = vulnerability.get("id", "")
4243
vulnerabilitysummary = vulnerability.get("summary", "")
43-
vulnerabilitydetails = vulnerability["details"]
44-
vulnerabilitypackagepurl = vulnerability["affected"][0].get("package", "")
45-
if vulnerabilitypackagepurl != "":
46-
vulnerabilitypackagepurl = vulnerabilitypackagepurl["purl"]
47-
cwe = vulnerability["affected"][0]["database_specific"].get("cwes", None)
48-
if cwe is not None:
49-
cwe = cwe[0]["cweId"]
44+
vulnerabilitydetails = vulnerability.get("details", "")
45+
vulnerabilitypackagepurl = ""
46+
cwe = None
47+
# Make sure we have an affected section to work with
48+
if (affected := vulnerability.get("affected")) is not None:
49+
if len(affected) > 0:
50+
# Pull the package purl if present
51+
if (vulnerabilitypackage := affected[0].get("package", "")) != "":
52+
vulnerabilitypackagepurl = vulnerabilitypackage.get("purl", "")
53+
# Extract the CWE
54+
if (cwe := affected[0].get("database_specific", {}).get("cwes", None)) is not None:
55+
cwe = cwe[0]["cweId"]
56+
# Create some references
5057
reference = ""
5158
for ref in vulnerability.get("references"):
5259
reference += ref.get("url") + "\n"
60+
# Define the description
5361
description = vulnerabilitysummary + "\n"
5462
description += "**source_type**: " + source_type + "\n"
5563
description += "**package_ecosystem**: " + package_ecosystem + "\n"

dojo/tools/redhatsatellite/parser.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@ def get_findings(self, filename, test):
6262
description += "**hosts_applicable_count:** " + str(hosts_applicable_count) + "\n"
6363
description += "**installable:** " + str(installable) + "\n"
6464
if bugs != []:
65-
description += "**bugs:** " + str(bugs) + "\n"
65+
description += "**bugs:** "
66+
for bug in bugs[:-1]:
67+
description += "[" + bug.get("bug_id") + "](" + bug.get("href") + ")" + ", "
68+
description += "[" + bugs[-1].get("bug_id") + "](" + bugs[-1].get("href") + ")" + "\n"
6669
if module_streams != []:
6770
description += "**module_streams:** " + str(module_streams) + "\n"
6871
description += "**packages:** " + ", ".join(packages)

0 commit comments

Comments
 (0)