Skip to content

Commit 68f2ce9

Browse files
authored
Merge pull request #10602 from DefectDojo/release/2.36.4
Release: Merge release into master from: release/2.36.4
2 parents 1342043 + 8694b9c commit 68f2ce9

9 files changed

Lines changed: 156 additions & 17 deletions

File tree

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.36.3",
3+
"version": "2.36.4",
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.36.3'
7+
__version__ = '2.36.4'
88
__url__ = 'https://github.com/DefectDojo/django-DefectDojo'
99
__docs__ = 'https://documentation.defectdojo.com'

dojo/api_v2/serializers.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,7 +2064,7 @@ class ImportScanSerializer(serializers.Serializer):
20642064
queryset=Endpoint.objects.all(),
20652065
required=False,
20662066
default=None,
2067-
help_text="The IP address, host name or full URL. It must be valid",
2067+
help_text="Enter the ID of an Endpoint that is associated with the target Product. New Findings will be added to that Endpoint."
20682068
)
20692069
file = serializers.FileField(allow_empty_file=True, required=False)
20702070
product_type_name = serializers.CharField(required=False)
@@ -2331,7 +2331,10 @@ class ReImportScanSerializer(TaggitSerializer, serializers.Serializer):
23312331
choices=get_choices_sorted(), required=True
23322332
)
23332333
endpoint_to_add = serializers.PrimaryKeyRelatedField(
2334-
queryset=Endpoint.objects.all(), default=None, required=False
2334+
queryset=Endpoint.objects.all(),
2335+
required=False,
2336+
default=None,
2337+
help_text="Enter the ID of an Endpoint that is associated with the target Product. New Findings will be added to that Endpoint."
23352338
)
23362339
file = serializers.FileField(allow_empty_file=True, required=False)
23372340
product_type_name = serializers.CharField(required=False)

dojo/finding/views.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,17 +1272,18 @@ def close_finding(request, fid):
12721272
finding_in_group = finding.has_finding_group
12731273
# Check if there is a jira issue that needs to be updated
12741274
jira_issue_exists = finding.has_jira_issue or (finding.finding_group and finding.finding_group.has_jira_issue)
1275+
# fetch the project
1276+
jira_instance = jira_helper.get_jira_instance(finding)
1277+
jira_project = jira_helper.get_jira_project(finding)
12751278
# Only push if the finding is not in a group
12761279
if jira_issue_exists:
12771280
# Determine if any automatic sync should occur
1278-
push_to_jira = jira_helper.is_push_all_issues(finding) \
1279-
or jira_helper.get_jira_instance(finding).finding_jira_sync
1280-
# Add the closing note
1281-
if push_to_jira and not finding_in_group:
1282-
jira_helper.add_comment(finding, new_note, force_push=True)
1281+
push_to_jira = jira_helper.is_push_all_issues(finding) or jira_instance.finding_jira_sync
1282+
# Add the closing note
1283+
if (jira_project.push_notes or push_to_jira) and not finding_in_group:
1284+
jira_helper.add_comment(finding, new_note, force_push=True)
12831285
# Save the finding
12841286
finding.save(push_to_jira=(push_to_jira and not finding_in_group))
1285-
12861287
# we only push the group after saving the finding to make sure
12871288
# the updated data of the finding is pushed as part of the group
12881289
if push_to_jira and finding_in_group:

dojo/importers/options.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,11 @@ def compress_options(self):
119119
# Accommodate lists of fields
120120
elif isinstance(value, list) and len(value) > 0 and isinstance(value[0], Model):
121121
id_list = [item.id for item in value]
122+
item_type = type(value[0])
122123
class_name = None
123124
# Get the actual class if available
124125
if len(id_list) > 0:
125-
class_name = type(id_list[0])
126+
class_name = item_type
126127
# Ensure we are not setting a class name as None
127128
if class_name is type(None):
128129
compressed_fields[field] = value
@@ -149,7 +150,7 @@ def decompress_options(self):
149150
if class_name is type(None):
150151
model_list = model_value
151152
else:
152-
model_list = [class_name.objects.get(id=model_id) for model_id in model_value]
153+
model_list = list(class_name.objects.filter(id__in=model_value))
153154
decompressed_fields[field] = model_list
154155
elif isinstance(model_value, int):
155156
# Check for SimpleLazyObject that will be user objects

dojo/tools/aqua/parser.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@ def get_items(self, tree, test):
2424

2525
for node in vulnerabilityTree:
2626
resource = node.get("resource")
27-
vulnerabilities = node.get("vulnerabilities")
28-
27+
vulnerabilities = node.get("vulnerabilities", [])
28+
if vulnerabilities is None:
29+
vulnerabilities = []
2930
for vuln in vulnerabilities:
3031
item = get_item(resource, vuln, test)
31-
unique_key = resource.get("cpe") + vuln.get("name", "None")
32+
unique_key = resource.get("cpe") + vuln.get("name", "None") + resource.get("path", "None")
3233
items[unique_key] = item
3334
elif "cves" in tree:
3435
for cve in tree["cves"]:

helm/defectdojo/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
apiVersion: v2
2-
appVersion: "2.36.3"
2+
appVersion: "2.36.4"
33
description: A Helm chart for Kubernetes to install DefectDojo
44
name: defectdojo
5-
version: 1.6.140
5+
version: 1.6.141
66
icon: https://www.defectdojo.org/img/favicon.ico
77
maintainers:
88
- name: madchap
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
{
2+
"image": "your_image:latest",
3+
"scan_started": {
4+
"seconds": 1567784942,
5+
"nanos": 28041437
6+
},
7+
"scan_duration": 25,
8+
"image_size": 565733981,
9+
"digest": "54bc57e4e876533bc61ba7bf229f0f9f96d137b787614c3d0d5c70c3578fe867",
10+
"os": "alpine",
11+
"version": "3.9.4",
12+
"resources": [
13+
{
14+
"resource": {
15+
"format": "apk",
16+
"name": "musl",
17+
"version": "1.1.20-r4",
18+
"arch": "x86_64",
19+
"cpe": "pkg:/alpine:3.9.4:musl:1.1.20-r4",
20+
"license": "MIT"
21+
},
22+
"scanned": true,
23+
"vulnerabilities": null
24+
}
25+
],
26+
"image_assurance_results": {
27+
"disallowed": true,
28+
"audit_required": true,
29+
"policy_failures": [
30+
{
31+
"policy_id": 1,
32+
"policy_name": "Default",
33+
"blocking": true,
34+
"controls": [
35+
"max_severity"
36+
]
37+
},
38+
{
39+
"policy_id": 6,
40+
"policy_name": "Assurance_policy",
41+
"blocking": true,
42+
"controls": [
43+
"max_score"
44+
]
45+
}
46+
],
47+
"checks_performed": [
48+
{
49+
"failed": true,
50+
"policy_id": 1,
51+
"policy_name": "Default",
52+
"control": "max_severity",
53+
"maximum_severity_allowed": "high",
54+
"maximum_severity_found": "high",
55+
"maximum_fixable_severity_found": "high",
56+
"no_fix_excluded": true
57+
},
58+
{
59+
"policy_id": 1,
60+
"policy_name": "Default",
61+
"control": "malware"
62+
},
63+
{
64+
"policy_id": 1,
65+
"policy_name": "Default",
66+
"control": "sensitive_data"
67+
},
68+
{
69+
"policy_id": 1,
70+
"policy_name": "Default",
71+
"control": "root_user"
72+
},
73+
{
74+
"failed": true,
75+
"policy_id": 6,
76+
"policy_name": "Assurance_policy",
77+
"control": "max_score",
78+
"maximum_score_allowed": 7,
79+
"maximum_score_found": 7.5,
80+
"maximum_fixable_score_found": 7.5,
81+
"no_fix_excluded": true
82+
},
83+
{
84+
"policy_id": 6,
85+
"policy_name": "Assurance_policy",
86+
"control": "malware"
87+
},
88+
{
89+
"policy_id": 6,
90+
"policy_name": "Assurance_policy",
91+
"control": "sensitive_data"
92+
},
93+
{
94+
"policy_id": 6,
95+
"policy_name": "Assurance_policy",
96+
"control": "root_user"
97+
}
98+
],
99+
"block_required": true
100+
},
101+
"vulnerability_summary": {
102+
"total": 24,
103+
"high": 5,
104+
"medium": 18,
105+
"low": 1,
106+
"negligible": 0,
107+
"sensitive": 0,
108+
"malware": 0,
109+
"score_average": 5.454168,
110+
"max_score": 7.5,
111+
"max_fixable_score": 7.5,
112+
"max_fixable_severity": "high"
113+
},
114+
"scan_options": {
115+
"scan_sensitive_data": true,
116+
"scan_malware": true,
117+
"scan_timeout": 3600000000000,
118+
"manual_pull_fallback": true,
119+
"save_adhoc_scans": true
120+
},
121+
"initiating_user": "chk",
122+
"data_date": 1567724137,
123+
"pull_name": "your_image:latest",
124+
"changed_result": false,
125+
"required_image_platform": "amd64:::",
126+
"scanned_image_platform": "amd64::linux:"
127+
}

unittests/tools/test_aqua_parser.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,9 @@ def test_aqua_parser_for_aqua_severity(self):
9292
self.assertEqual(2, d['Medium'])
9393
self.assertEqual(2, d['Low'])
9494
self.assertEqual(7, d['Info'])
95+
96+
def test_aqua_parser_issue_10585(self):
97+
with open("unittests/scans/aqua/issue_10585.json") as testfile:
98+
parser = AquaParser()
99+
findings = parser.get_findings(testfile, Test())
100+
self.assertEqual(0, len(findings))

0 commit comments

Comments
 (0)