From 2a0e29ee65f5104eccfd6d6c9f731f5c2a8062c7 Mon Sep 17 00:00:00 2001 From: Paul Osinski <42211303+paulOsinski@users.noreply.github.com> Date: Wed, 17 Jul 2024 22:58:41 -0400 Subject: [PATCH 1/9] /import helptext correction: endpoint_to_add (#10582) * correct help_text on /import endpoint_to_add flag * add helptext to /reimport endpoint_to_add option --- dojo/api_v2/serializers.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dojo/api_v2/serializers.py b/dojo/api_v2/serializers.py index 56aefa285d0..ffc66256450 100644 --- a/dojo/api_v2/serializers.py +++ b/dojo/api_v2/serializers.py @@ -2064,7 +2064,7 @@ class ImportScanSerializer(serializers.Serializer): queryset=Endpoint.objects.all(), required=False, default=None, - help_text="The IP address, host name or full URL. It must be valid", + help_text="Enter the ID of an Endpoint that is associated with the target Product. New Findings will be added to that Endpoint." ) file = serializers.FileField(allow_empty_file=True, required=False) product_type_name = serializers.CharField(required=False) @@ -2331,7 +2331,10 @@ class ReImportScanSerializer(TaggitSerializer, serializers.Serializer): choices=get_choices_sorted(), required=True ) endpoint_to_add = serializers.PrimaryKeyRelatedField( - queryset=Endpoint.objects.all(), default=None, required=False + queryset=Endpoint.objects.all(), + required=False, + default=None, + help_text="Enter the ID of an Endpoint that is associated with the target Product. New Findings will be added to that Endpoint." ) file = serializers.FileField(allow_empty_file=True, required=False) product_type_name = serializers.CharField(required=False) From c46b08d9ff65cf2fcb625a809e033b41b2330351 Mon Sep 17 00:00:00 2001 From: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:57:49 -0500 Subject: [PATCH 2/9] Close Findings: Push notes if `push notes` is enabled (#10581) --- dojo/finding/views.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/dojo/finding/views.py b/dojo/finding/views.py index 04d980e59c9..4f4c0d4b049 100644 --- a/dojo/finding/views.py +++ b/dojo/finding/views.py @@ -1272,17 +1272,18 @@ def close_finding(request, fid): finding_in_group = finding.has_finding_group # Check if there is a jira issue that needs to be updated jira_issue_exists = finding.has_jira_issue or (finding.finding_group and finding.finding_group.has_jira_issue) + # fetch the project + jira_instance = jira_helper.get_jira_instance(finding) + jira_project = jira_helper.get_jira_project(finding) # Only push if the finding is not in a group if jira_issue_exists: # Determine if any automatic sync should occur - push_to_jira = jira_helper.is_push_all_issues(finding) \ - or jira_helper.get_jira_instance(finding).finding_jira_sync - # Add the closing note - if push_to_jira and not finding_in_group: - jira_helper.add_comment(finding, new_note, force_push=True) + push_to_jira = jira_helper.is_push_all_issues(finding) or jira_instance.finding_jira_sync + # Add the closing note + if (jira_project.push_notes or push_to_jira) and not finding_in_group: + jira_helper.add_comment(finding, new_note, force_push=True) # Save the finding finding.save(push_to_jira=(push_to_jira and not finding_in_group)) - # we only push the group after saving the finding to make sure # the updated data of the finding is pushed as part of the group if push_to_jira and finding_in_group: From 5abd7e27c9e13d2c440beb0af87688376302d2b2 Mon Sep 17 00:00:00 2001 From: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:58:02 -0500 Subject: [PATCH 3/9] Option Compression: add some polish (#10583) --- dojo/importers/options.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dojo/importers/options.py b/dojo/importers/options.py index 52b291ecaf1..2cc28623394 100644 --- a/dojo/importers/options.py +++ b/dojo/importers/options.py @@ -119,10 +119,11 @@ def compress_options(self): # Accommodate lists of fields elif isinstance(value, list) and len(value) > 0 and isinstance(value[0], Model): id_list = [item.id for item in value] + item_type = type(value[0]) class_name = None # Get the actual class if available if len(id_list) > 0: - class_name = type(id_list[0]) + class_name = item_type # Ensure we are not setting a class name as None if class_name is type(None): compressed_fields[field] = value @@ -149,7 +150,7 @@ def decompress_options(self): if class_name is type(None): model_list = model_value else: - model_list = [class_name.objects.get(id=model_id) for model_id in model_value] + model_list = list(class_name.objects.filter(id__in=model_value)) decompressed_fields[field] = model_list elif isinstance(model_value, int): # Check for SimpleLazyObject that will be user objects From 6c6c301d7df9f3701d1462eaa6e077876afb6c90 Mon Sep 17 00:00:00 2001 From: manuelsommer <47991713+manuel-sommer@users.noreply.github.com> Date: Mon, 22 Jul 2024 16:56:52 +0200 Subject: [PATCH 4/9] :bug: fix aqua nonetype error #10585 (#10594) --- dojo/tools/aqua/parser.py | 5 +- unittests/scans/aqua/issue_10585.json | 127 ++++++++++++++++++++++++++ unittests/tools/test_aqua_parser.py | 6 ++ 3 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 unittests/scans/aqua/issue_10585.json diff --git a/dojo/tools/aqua/parser.py b/dojo/tools/aqua/parser.py index d6ea61edc9a..1970b74f139 100644 --- a/dojo/tools/aqua/parser.py +++ b/dojo/tools/aqua/parser.py @@ -24,8 +24,9 @@ def get_items(self, tree, test): for node in vulnerabilityTree: resource = node.get("resource") - vulnerabilities = node.get("vulnerabilities") - + vulnerabilities = node.get("vulnerabilities", []) + if vulnerabilities is None: + vulnerabilities = [] for vuln in vulnerabilities: item = get_item(resource, vuln, test) unique_key = resource.get("cpe") + vuln.get("name", "None") diff --git a/unittests/scans/aqua/issue_10585.json b/unittests/scans/aqua/issue_10585.json new file mode 100644 index 00000000000..d4d05b6ab61 --- /dev/null +++ b/unittests/scans/aqua/issue_10585.json @@ -0,0 +1,127 @@ +{ + "image": "your_image:latest", + "scan_started": { + "seconds": 1567784942, + "nanos": 28041437 + }, + "scan_duration": 25, + "image_size": 565733981, + "digest": "54bc57e4e876533bc61ba7bf229f0f9f96d137b787614c3d0d5c70c3578fe867", + "os": "alpine", + "version": "3.9.4", + "resources": [ + { + "resource": { + "format": "apk", + "name": "musl", + "version": "1.1.20-r4", + "arch": "x86_64", + "cpe": "pkg:/alpine:3.9.4:musl:1.1.20-r4", + "license": "MIT" + }, + "scanned": true, + "vulnerabilities": null + } + ], + "image_assurance_results": { + "disallowed": true, + "audit_required": true, + "policy_failures": [ + { + "policy_id": 1, + "policy_name": "Default", + "blocking": true, + "controls": [ + "max_severity" + ] + }, + { + "policy_id": 6, + "policy_name": "Assurance_policy", + "blocking": true, + "controls": [ + "max_score" + ] + } + ], + "checks_performed": [ + { + "failed": true, + "policy_id": 1, + "policy_name": "Default", + "control": "max_severity", + "maximum_severity_allowed": "high", + "maximum_severity_found": "high", + "maximum_fixable_severity_found": "high", + "no_fix_excluded": true + }, + { + "policy_id": 1, + "policy_name": "Default", + "control": "malware" + }, + { + "policy_id": 1, + "policy_name": "Default", + "control": "sensitive_data" + }, + { + "policy_id": 1, + "policy_name": "Default", + "control": "root_user" + }, + { + "failed": true, + "policy_id": 6, + "policy_name": "Assurance_policy", + "control": "max_score", + "maximum_score_allowed": 7, + "maximum_score_found": 7.5, + "maximum_fixable_score_found": 7.5, + "no_fix_excluded": true + }, + { + "policy_id": 6, + "policy_name": "Assurance_policy", + "control": "malware" + }, + { + "policy_id": 6, + "policy_name": "Assurance_policy", + "control": "sensitive_data" + }, + { + "policy_id": 6, + "policy_name": "Assurance_policy", + "control": "root_user" + } + ], + "block_required": true + }, + "vulnerability_summary": { + "total": 24, + "high": 5, + "medium": 18, + "low": 1, + "negligible": 0, + "sensitive": 0, + "malware": 0, + "score_average": 5.454168, + "max_score": 7.5, + "max_fixable_score": 7.5, + "max_fixable_severity": "high" + }, + "scan_options": { + "scan_sensitive_data": true, + "scan_malware": true, + "scan_timeout": 3600000000000, + "manual_pull_fallback": true, + "save_adhoc_scans": true + }, + "initiating_user": "chk", + "data_date": 1567724137, + "pull_name": "your_image:latest", + "changed_result": false, + "required_image_platform": "amd64:::", + "scanned_image_platform": "amd64::linux:" +} \ No newline at end of file diff --git a/unittests/tools/test_aqua_parser.py b/unittests/tools/test_aqua_parser.py index 89f16334fa5..96d07bd3dca 100644 --- a/unittests/tools/test_aqua_parser.py +++ b/unittests/tools/test_aqua_parser.py @@ -92,3 +92,9 @@ def test_aqua_parser_for_aqua_severity(self): self.assertEqual(2, d['Medium']) self.assertEqual(2, d['Low']) self.assertEqual(7, d['Info']) + + def test_aqua_parser_issue_10585(self): + with open("unittests/scans/aqua/issue_10585.json") as testfile: + parser = AquaParser() + findings = parser.get_findings(testfile, Test()) + self.assertEqual(0, len(findings)) From f636221e645ca1da0caec48af778f4cb7b4be29b Mon Sep 17 00:00:00 2001 From: manuelsommer <47991713+manuel-sommer@users.noreply.github.com> Date: Mon, 22 Jul 2024 16:57:41 +0200 Subject: [PATCH 5/9] :bug: fix aqua issue #10586 (#10595) --- dojo/tools/aqua/parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dojo/tools/aqua/parser.py b/dojo/tools/aqua/parser.py index 1970b74f139..d6056f892f2 100644 --- a/dojo/tools/aqua/parser.py +++ b/dojo/tools/aqua/parser.py @@ -29,7 +29,7 @@ def get_items(self, tree, test): vulnerabilities = [] for vuln in vulnerabilities: item = get_item(resource, vuln, test) - unique_key = resource.get("cpe") + vuln.get("name", "None") + unique_key = resource.get("cpe") + vuln.get("name", "None") + resource.get("path", "None") items[unique_key] = item elif "cves" in tree: for cve in tree["cves"]: From 47fe6f6f765f6a6bcab22815dd60136a6e4d36e9 Mon Sep 17 00:00:00 2001 From: DefectDojo release bot Date: Mon, 22 Jul 2024 15:07:27 +0000 Subject: [PATCH 6/9] Update versions in application files --- components/package.json | 2 +- dojo/__init__.py | 2 +- helm/defectdojo/Chart.yaml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/package.json b/components/package.json index ab3201e6a41..0980554df32 100644 --- a/components/package.json +++ b/components/package.json @@ -1,6 +1,6 @@ { "name": "defectdojo", - "version": "2.37.0-dev", + "version": "2.36.4", "license" : "BSD-3-Clause", "private": true, "dependencies": { diff --git a/dojo/__init__.py b/dojo/__init__.py index 707177ee3ee..0b33f28f649 100644 --- a/dojo/__init__.py +++ b/dojo/__init__.py @@ -4,6 +4,6 @@ # Django starts so that shared_task will use this app. from .celery import app as celery_app # noqa: F401 -__version__ = '2.37.0-dev' +__version__ = '2.36.4' __url__ = 'https://github.com/DefectDojo/django-DefectDojo' __docs__ = 'https://documentation.defectdojo.com' diff --git a/helm/defectdojo/Chart.yaml b/helm/defectdojo/Chart.yaml index cabc1b46323..ce087c199de 100644 --- a/helm/defectdojo/Chart.yaml +++ b/helm/defectdojo/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v2 -appVersion: "2.37.0-dev" +appVersion: "2.36.4" description: A Helm chart for Kubernetes to install DefectDojo name: defectdojo -version: 1.6.141-dev +version: 1.6.141 icon: https://www.defectdojo.org/img/favicon.ico maintainers: - name: madchap From f3e904bf1e930587a635fb07a5319803201cd98a Mon Sep 17 00:00:00 2001 From: DefectDojo release bot Date: Mon, 22 Jul 2024 15:45:24 +0000 Subject: [PATCH 7/9] Update versions in application files --- components/package.json | 2 +- dojo/__init__.py | 2 +- helm/defectdojo/Chart.yaml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/package.json b/components/package.json index 0980554df32..ab3201e6a41 100644 --- a/components/package.json +++ b/components/package.json @@ -1,6 +1,6 @@ { "name": "defectdojo", - "version": "2.36.4", + "version": "2.37.0-dev", "license" : "BSD-3-Clause", "private": true, "dependencies": { diff --git a/dojo/__init__.py b/dojo/__init__.py index 0b33f28f649..707177ee3ee 100644 --- a/dojo/__init__.py +++ b/dojo/__init__.py @@ -4,6 +4,6 @@ # Django starts so that shared_task will use this app. from .celery import app as celery_app # noqa: F401 -__version__ = '2.36.4' +__version__ = '2.37.0-dev' __url__ = 'https://github.com/DefectDojo/django-DefectDojo' __docs__ = 'https://documentation.defectdojo.com' diff --git a/helm/defectdojo/Chart.yaml b/helm/defectdojo/Chart.yaml index ce087c199de..00d482acf72 100644 --- a/helm/defectdojo/Chart.yaml +++ b/helm/defectdojo/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v2 -appVersion: "2.36.4" +appVersion: "2.37.0-dev" description: A Helm chart for Kubernetes to install DefectDojo name: defectdojo -version: 1.6.141 +version: 1.6.142-dev icon: https://www.defectdojo.org/img/favicon.ico maintainers: - name: madchap From 8787d8e87db6b5a90709e8560ab87b9f28d545d0 Mon Sep 17 00:00:00 2001 From: DefectDojo Date: Mon, 22 Jul 2024 15:50:36 +0000 Subject: [PATCH 8/9] Update helm lock file Signed-off-by: DefectDojo --- helm/defectdojo/Chart.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/helm/defectdojo/Chart.lock b/helm/defectdojo/Chart.lock index b56a8256051..23cc2f618ca 100644 --- a/helm/defectdojo/Chart.lock +++ b/helm/defectdojo/Chart.lock @@ -4,7 +4,7 @@ dependencies: version: 9.19.1 - name: postgresql repository: https://charts.bitnami.com/bitnami - version: 15.5.16 + version: 15.5.17 - name: postgresql-ha repository: https://charts.bitnami.com/bitnami version: 9.4.11 @@ -13,6 +13,6 @@ dependencies: version: 14.4.6 - name: redis repository: https://charts.bitnami.com/bitnami - version: 19.6.1 -digest: sha256:87e072ffd03b4de3bec0a96f880de20b2d0e89673295579420d233f3d6659686 -generated: "2024-07-15T18:17:40.021560047Z" + version: 19.6.2 +digest: sha256:797914213a13f15ef96ce0ba1ff8f8e3b3025f6f548a732cb845650f01ccdefa +generated: "2024-07-22T15:50:25.70755734Z" From 0e86398445f243173f6aa7bdc9cc1049787de405 Mon Sep 17 00:00:00 2001 From: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:51:16 -0500 Subject: [PATCH 9/9] Fix ruff --- dojo/api_v2/serializers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dojo/api_v2/serializers.py b/dojo/api_v2/serializers.py index 8af6853bab0..986bd8186a9 100644 --- a/dojo/api_v2/serializers.py +++ b/dojo/api_v2/serializers.py @@ -2064,7 +2064,7 @@ class ImportScanSerializer(serializers.Serializer): queryset=Endpoint.objects.all(), required=False, default=None, - help_text="Enter the ID of an Endpoint that is associated with the target Product. New Findings will be added to that Endpoint." + help_text="Enter the ID of an Endpoint that is associated with the target Product. New Findings will be added to that Endpoint.", ) file = serializers.FileField(allow_empty_file=True, required=False) product_type_name = serializers.CharField(required=False) @@ -2334,7 +2334,7 @@ class ReImportScanSerializer(TaggitSerializer, serializers.Serializer): queryset=Endpoint.objects.all(), required=False, default=None, - help_text="Enter the ID of an Endpoint that is associated with the target Product. New Findings will be added to that Endpoint." + help_text="Enter the ID of an Endpoint that is associated with the target Product. New Findings will be added to that Endpoint.", ) file = serializers.FileField(allow_empty_file=True, required=False) product_type_name = serializers.CharField(required=False)