From e27e21e3fe05543c34c159cae70065fb44b5c4d0 Mon Sep 17 00:00:00 2001 From: DefectDojo release bot Date: Mon, 28 Oct 2024 18:53:19 +0000 Subject: [PATCH 01/12] Update versions in application files --- components/package.json | 2 +- helm/defectdojo/Chart.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/package.json b/components/package.json index 805b16ff7cf..06cdce1889b 100644 --- a/components/package.json +++ b/components/package.json @@ -1,6 +1,6 @@ { "name": "defectdojo", - "version": "2.39.4", + "version": "2.40.0-dev", "license" : "BSD-3-Clause", "private": true, "dependencies": { diff --git a/helm/defectdojo/Chart.yaml b/helm/defectdojo/Chart.yaml index 5337b2b7059..ffac3d938b3 100644 --- a/helm/defectdojo/Chart.yaml +++ b/helm/defectdojo/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v2 -appVersion: "2.39.4" +appVersion: "2.40.0-dev" description: A Helm chart for Kubernetes to install DefectDojo name: defectdojo -version: 1.6.157 +version: 1.6.158-dev icon: https://www.defectdojo.org/img/favicon.ico maintainers: - name: madchap From e49d93304c451d8349288f85b3b1277744c26d70 Mon Sep 17 00:00:00 2001 From: Julien Godin <40758407+JGodin-C2C@users.noreply.github.com> Date: Mon, 28 Oct 2024 20:50:11 +0100 Subject: [PATCH 02/12] fix: broker configuration fix for deployment (#11109) Signed-off-by: Julien Godin --- helm/defectdojo/templates/configmap.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm/defectdojo/templates/configmap.yaml b/helm/defectdojo/templates/configmap.yaml index b5248a0a9ba..5ae741f0abc 100644 --- a/helm/defectdojo/templates/configmap.yaml +++ b/helm/defectdojo/templates/configmap.yaml @@ -18,7 +18,7 @@ data: DD_CELERY_BROKER_SCHEME: {{ if eq .Values.celery.broker "redis" }}{{ template "redis.scheme" . }}{{ end }} DD_CELERY_BROKER_USER: '' DD_CELERY_BROKER_HOST: {{ if eq .Values.celery.broker "redis" }}{{ template "redis.hostname" . }}{{ end }} - DD_CELERY_BROKER_PORT: '{{ if eq .Values.celery.broker "redis" }}{{ .Values.redis.master.service.ports.redis | default "6379" }}{{ end }}' + DD_CELERY_BROKER_PORT: '{{ if eq .Values.celery.broker "redis" }}{{- if ( hasKey .Values.redis "master" ) -}}{{ .Values.redis.master.service.ports.redis }}{{ else }}6379{{ end }}{{- end -}}' DD_CELERY_BROKER_PARAMS: '{{ if eq .Values.celery.broker "redis" }}{{- if .Values.redis.transportEncryption.enabled -}}{{ .Values.redis.transportEncryption.params | default "ssl_cert_reqs=optional" }}{{ end }}{{ end }}' DD_CELERY_BROKER_PATH: '{{ .Values.celery.path | default "//" }}' DD_CELERY_LOG_LEVEL: {{ .Values.celery.logLevel }} From abb773556958104ad48f499d236e0be128dd8b10 Mon Sep 17 00:00:00 2001 From: Paul Osinski <42211303+paulOsinski@users.noreply.github.com> Date: Tue, 29 Oct 2024 15:29:33 -0400 Subject: [PATCH 03/12] Change logo for docs, add knowledge base link (#11158) * add knowledge base link * update logo for docs * add knowledge base link to master --------- Co-authored-by: Paul Osinski --- docs/assets/icons/logo.svg | 259 +++---------------------------------- docs/config.dev.toml | 6 + docs/config.master.toml | 6 + 3 files changed, 27 insertions(+), 244 deletions(-) diff --git a/docs/assets/icons/logo.svg b/docs/assets/icons/logo.svg index 71a24baac76..75983a52716 100644 --- a/docs/assets/icons/logo.svg +++ b/docs/assets/icons/logo.svg @@ -1,244 +1,15 @@ - - - - - - - - image/svg+xml - - - - - - - - - + + + + + + + \ No newline at end of file diff --git a/docs/config.dev.toml b/docs/config.dev.toml index 65fff4564ba..de3d1b24c36 100644 --- a/docs/config.dev.toml +++ b/docs/config.dev.toml @@ -77,6 +77,12 @@ weight = 1 pre = "" url = "https://github.com/DefectDojo/django-DefectDojo" +[[menu.main]] + name = "Knowledge Base" + weight = 50 + pre = "" + url = "https://support.defectdojo.com" + [markup] [markup.goldmark] [markup.goldmark.renderer] diff --git a/docs/config.master.toml b/docs/config.master.toml index 29c4e0a6adc..22f2f7748ab 100644 --- a/docs/config.master.toml +++ b/docs/config.master.toml @@ -77,6 +77,12 @@ weight = 1 pre = "" url = "https://github.com/DefectDojo/django-DefectDojo" +[[menu.main]] + name = "Knowledge Base" + weight = 50 + pre = "" + url = "https://support.defectdojo.com" + [markup] [markup.goldmark] [markup.goldmark.renderer] From 5a80eee057a924b1995628b125a87c4f922529ba Mon Sep 17 00:00:00 2001 From: manuelsommer <47991713+manuel-sommer@users.noreply.github.com> Date: Fri, 1 Nov 2024 19:15:05 +0100 Subject: [PATCH 04/12] Add ELBA vulnerability URL (#11138) --- dojo/settings/.settings.dist.py.sha256sum | 2 +- dojo/settings/settings.dist.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dojo/settings/.settings.dist.py.sha256sum b/dojo/settings/.settings.dist.py.sha256sum index def3909d2c9..79cb4cfb2ea 100644 --- a/dojo/settings/.settings.dist.py.sha256sum +++ b/dojo/settings/.settings.dist.py.sha256sum @@ -1 +1 @@ -002b28325f11793c5aa9f09326c2d5cc66de518cce51b2cb4cb681a920b89909 +d738d221fdbc0b2e04d9ff13d79c6cba52c49adfb81243a278252592a412d246 diff --git a/dojo/settings/settings.dist.py b/dojo/settings/settings.dist.py index 846639f07a3..9a8f28b2ddc 100644 --- a/dojo/settings/settings.dist.py +++ b/dojo/settings/settings.dist.py @@ -1736,6 +1736,7 @@ def saml2_attrib_map_format(dict): "USN": "https://ubuntu.com/security/notices/", # e.g. https://ubuntu.com/security/notices/USN-6642-1 "DLA": "https://security-tracker.debian.org/tracker/", # e.g. https://security-tracker.debian.org/tracker/DLA-3917-1 "ELSA": "https://linux.oracle.com/errata/&&.html", # e.g. https://linux.oracle.com/errata/ELSA-2024-12714.html + "ELBA": "https://linux.oracle.com/errata/&&.html", # e.g. https://linux.oracle.com/errata/ELBA-2024-7457.html "RXSA": "https://errata.rockylinux.org/", # e.g. https://errata.rockylinux.org/RXSA-2024:4928 } # List of acceptable file types that can be uploaded to a given object via arbitrary file upload From 6d811e0dc7e92428863c76a352e68eb6c631df27 Mon Sep 17 00:00:00 2001 From: manuelsommer <47991713+manuel-sommer@users.noreply.github.com> Date: Fri, 1 Nov 2024 22:43:40 +0100 Subject: [PATCH 05/12] File Uploads: Allow FPR format (#11157) * fix for issue #11153 * update sha sum --- dojo/settings/.settings.dist.py.sha256sum | 2 +- dojo/settings/settings.dist.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dojo/settings/.settings.dist.py.sha256sum b/dojo/settings/.settings.dist.py.sha256sum index 79cb4cfb2ea..010373c9855 100644 --- a/dojo/settings/.settings.dist.py.sha256sum +++ b/dojo/settings/.settings.dist.py.sha256sum @@ -1 +1 @@ -d738d221fdbc0b2e04d9ff13d79c6cba52c49adfb81243a278252592a412d246 +fcc15cb97df6ff9ef6752a1fe498502126174285e37d67640a6cc7a83314d951 diff --git a/dojo/settings/settings.dist.py b/dojo/settings/settings.dist.py index 9a8f28b2ddc..cfeacb9a411 100644 --- a/dojo/settings/settings.dist.py +++ b/dojo/settings/settings.dist.py @@ -276,7 +276,7 @@ DD_DELETE_PREVIEW=(bool, True), # List of acceptable file types that can be uploaded to a given object via arbitrary file upload DD_FILE_UPLOAD_TYPES=(list, [".txt", ".pdf", ".json", ".xml", ".csv", ".yml", ".png", ".jpeg", - ".sarif", ".xlsx", ".doc", ".html", ".js", ".nessus", ".zip"]), + ".sarif", ".xlsx", ".doc", ".html", ".js", ".nessus", ".zip", ".fpr"]), # Max file size for scan added via API in MB DD_SCAN_FILE_MAX_SIZE=(int, 100), # When disabled, existing user tokens will not be removed but it will not be From 2bbed9fb8996205ef9d4453e3c0228971a28f4a2 Mon Sep 17 00:00:00 2001 From: manuelsommer <47991713+manuel-sommer@users.noreply.github.com> Date: Fri, 1 Nov 2024 22:43:57 +0100 Subject: [PATCH 06/12] :tada: add tenable plugin to reference (#11151) --- dojo/tools/tenable/csv_format.py | 3 +++ unittests/tools/test_tenable_parser.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/dojo/tools/tenable/csv_format.py b/dojo/tools/tenable/csv_format.py index 2c2e0134462..3b38bd5a7af 100644 --- a/dojo/tools/tenable/csv_format.py +++ b/dojo/tools/tenable/csv_format.py @@ -103,6 +103,9 @@ def get_findings(self, filename: str, test: Test): mitigation = str(row.get("Solution", row.get("definition.solution", row.get("Steps to Remediate", "N/A")))) impact = row.get("Description", row.get("definition.description", "N/A")) references = row.get("See Also", row.get("definition.see_also", "N/A")) + references += "\nTenable Plugin ID: " + row.get("Plugin", "N/A") + references += "\nPlugin Publication Date: " + row.get("Plugin Publication Date", "N/A") + references += "\nPlugin Modification Date: " + row.get("Plugin Modification Date", "N/A") # Determine if the current row has already been processed dupe_key = ( severity diff --git a/unittests/tools/test_tenable_parser.py b/unittests/tools/test_tenable_parser.py index 7be782c49e3..681a315dd6f 100644 --- a/unittests/tools/test_tenable_parser.py +++ b/unittests/tools/test_tenable_parser.py @@ -309,3 +309,17 @@ def test_parse_issue_11102(self): endpoint.clean() self.assertEqual(2, len(findings)) self.assertEqual("Reconfigure the affected application if possible to avoid use of medium strength ciphers.", findings[0].mitigation) + + def test_parse_issue_11127(self): + with open("unittests/scans/tenable/issue_11102.csv", encoding="utf-8") as testfile: + parser = TenableParser() + findings = parser.get_findings(testfile, self.create_test()) + for finding in findings: + for endpoint in finding.unsaved_endpoints: + endpoint.clean() + reference = """https://www.openssl.org/blog/blog/2016/08/24/sweet32/ +https://sweet32.info +Tenable Plugin ID: 42873 +Plugin Publication Date: Nov 23, 2009 12:00:00 UTC +Plugin Modification Date: Feb 3, 2021 12:00:00 UTC""" + self.assertEqual(reference, findings[0].references) From 4b5c992db130e5bb906ffac104cd20a60be1bdab Mon Sep 17 00:00:00 2001 From: manuelsommer <47991713+manuel-sommer@users.noreply.github.com> Date: Fri, 1 Nov 2024 22:44:43 +0100 Subject: [PATCH 07/12] :tada: fix TrivyOperator new report structure (#11156) * :tada: fix TrivyOperator new report structure * added additional info to description --- dojo/tools/trivy_operator/checks_handler.py | 14 +- dojo/tools/trivy_operator/parser.py | 23 +- dojo/tools/trivy_operator/secrets_handler.py | 15 +- .../trivy_operator/vulnerability_handler.py | 17 +- .../trivy_operator/findings_in_list.json | 399 ++++++++++++++++++ unittests/tools/test_trivy_operator_parser.py | 8 +- 6 files changed, 456 insertions(+), 20 deletions(-) create mode 100644 unittests/scans/trivy_operator/findings_in_list.json diff --git a/dojo/tools/trivy_operator/checks_handler.py b/dojo/tools/trivy_operator/checks_handler.py index e6a1ccd8bb6..c42eef0fa8a 100644 --- a/dojo/tools/trivy_operator/checks_handler.py +++ b/dojo/tools/trivy_operator/checks_handler.py @@ -10,8 +10,15 @@ class TrivyChecksHandler: - def handle_checks(self, service, checks, test): + def handle_checks(self, labels, checks, test): findings = [] + resource_namespace = labels.get("trivy-operator.resource.namespace", "") + resource_kind = labels.get("trivy-operator.resource.kind", "") + resource_name = labels.get("trivy-operator.resource.name", "") + container_name = labels.get("trivy-operator.container.name", "") + service = f"{resource_namespace}/{resource_kind}/{resource_name}" + if container_name != "": + service = f"{service}/{container_name}" for check in checks: check_title = check.get("title") check_severity = TRIVY_SEVERITIES[check.get("severity")] @@ -23,6 +30,10 @@ def handle_checks(self, service, checks, test): + check_id.lower() ) check_description = check.get("description", "") + check_description += "\n**container.name:** " + container_name + check_description += "\n**resource.kind:** " + resource_kind + check_description += "\n**resource.name:** " + resource_name + check_description += "\n**resource.namespace:** " + resource_namespace title = f"{check_id} - {check_title}" finding = Finding( test=test, @@ -33,6 +44,7 @@ def handle_checks(self, service, checks, test): static_finding=True, dynamic_finding=False, service=service, + tags=[resource_namespace], ) if check_id: finding.unsaved_vulnerability_ids = [check_id] diff --git a/dojo/tools/trivy_operator/parser.py b/dojo/tools/trivy_operator/parser.py index 138cee17624..8be42e8e31e 100644 --- a/dojo/tools/trivy_operator/parser.py +++ b/dojo/tools/trivy_operator/parser.py @@ -25,7 +25,15 @@ def get_findings(self, scan_file, test): data = json.loads(str(scan_data, "utf-8")) except Exception: data = json.loads(scan_data) + findings = [] + if type(data) is list: + for listitems in data: + findings += self.output_findings(listitems, test) + else: + findings += self.output_findings(data, test) + return findings + def output_findings(self, data, test): if data is None: return [] metadata = data.get("metadata", None) @@ -40,24 +48,15 @@ def get_findings(self, scan_file, test): benchmarkreport = benchmark.get("detailReport", None) findings = [] if report is not None: - resource_namespace = labels.get( - "trivy-operator.resource.namespace", "", - ) - resource_kind = labels.get("trivy-operator.resource.kind", "") - resource_name = labels.get("trivy-operator.resource.name", "") - container_name = labels.get("trivy-operator.container.name", "") - service = f"{resource_namespace}/{resource_kind}/{resource_name}" - if container_name != "": - service = f"{service}/{container_name}" vulnerabilities = report.get("vulnerabilities", None) if vulnerabilities is not None: - findings += TrivyVulnerabilityHandler().handle_vulns(service, vulnerabilities, test) + findings += TrivyVulnerabilityHandler().handle_vulns(labels, vulnerabilities, test) checks = report.get("checks", None) if checks is not None: - findings += TrivyChecksHandler().handle_checks(service, checks, test) + findings += TrivyChecksHandler().handle_checks(labels, checks, test) secrets = report.get("secrets", None) if secrets is not None: - findings += TrivySecretsHandler().handle_secrets(service, secrets, test) + findings += TrivySecretsHandler().handle_secrets(labels, secrets, test) elif benchmarkreport is not None: findings += TrivyComplianceHandler().handle_compliance(benchmarkreport, test) return findings diff --git a/dojo/tools/trivy_operator/secrets_handler.py b/dojo/tools/trivy_operator/secrets_handler.py index c5e767a1bc5..a00c894a034 100644 --- a/dojo/tools/trivy_operator/secrets_handler.py +++ b/dojo/tools/trivy_operator/secrets_handler.py @@ -15,8 +15,15 @@ class TrivySecretsHandler: - def handle_secrets(self, service, secrets, test): + def handle_secrets(self, labels, secrets, test): findings = [] + resource_namespace = labels.get("trivy-operator.resource.namespace", "") + resource_kind = labels.get("trivy-operator.resource.kind", "") + resource_name = labels.get("trivy-operator.resource.name", "") + container_name = labels.get("trivy-operator.container.name", "") + service = f"{resource_namespace}/{resource_kind}/{resource_name}" + if container_name != "": + service = f"{service}/{container_name}" for secret in secrets: secret_title = secret.get("title") secret_category = secret.get("category") @@ -31,7 +38,10 @@ def handle_secrets(self, service, secrets, test): category=secret_category, match=secret_match, ) - + secret_description += "\n**container.name:** " + container_name + secret_description += "\n**resource.kind:** " + resource_kind + secret_description += "\n**resource.name:** " + resource_name + secret_description += "\n**resource.namespace:** " + resource_namespace finding = Finding( test=test, title=title, @@ -42,6 +52,7 @@ def handle_secrets(self, service, secrets, test): static_finding=True, dynamic_finding=False, service=service, + tags=[resource_namespace], ) if secret_rule_id: finding.unsaved_vulnerability_ids = [secret_rule_id] diff --git a/dojo/tools/trivy_operator/vulnerability_handler.py b/dojo/tools/trivy_operator/vulnerability_handler.py index 13be3e55a41..a5a26e1288a 100644 --- a/dojo/tools/trivy_operator/vulnerability_handler.py +++ b/dojo/tools/trivy_operator/vulnerability_handler.py @@ -14,8 +14,15 @@ class TrivyVulnerabilityHandler: - def handle_vulns(self, service, vulnerabilities, test): + def handle_vulns(self, labels, vulnerabilities, test): findings = [] + resource_namespace = labels.get("trivy-operator.resource.namespace", "") + resource_kind = labels.get("trivy-operator.resource.kind", "") + resource_name = labels.get("trivy-operator.resource.name", "") + container_name = labels.get("trivy-operator.container.name", "") + service = f"{resource_namespace}/{resource_kind}/{resource_name}" + if container_name != "": + service = f"{service}/{container_name}" for vulnerability in vulnerabilities: vuln_id = vulnerability.get("vulnerabilityID", "0") severity = TRIVY_SEVERITIES[vulnerability.get("severity")] @@ -24,8 +31,7 @@ def handle_vulns(self, service, vulnerabilities, test): package_name = vulnerability.get("resource") package_version = vulnerability.get("installedVersion") cvssv3_score = vulnerability.get("score") - - finding_tags = [] + finding_tags = [resource_namespace] target_target = None target_class = None package_path = None @@ -57,7 +63,10 @@ def handle_vulns(self, service, vulnerabilities, test): description = DESCRIPTION_TEMPLATE.format( title=vulnerability.get("title"), fixed_version=mitigation, ) - + description += "\n**container.name:** " + container_name + description += "\n**resource.kind:** " + resource_kind + description += "\n**resource.name:** " + resource_name + description += "\n**resource.namespace:** " + resource_namespace title = f"{vuln_id} {package_name} {package_version}" finding = Finding( test=test, diff --git a/unittests/scans/trivy_operator/findings_in_list.json b/unittests/scans/trivy_operator/findings_in_list.json new file mode 100644 index 00000000000..7a79600eb8f --- /dev/null +++ b/unittests/scans/trivy_operator/findings_in_list.json @@ -0,0 +1,399 @@ +[ + { + "apiVersion": "aquasecurity.github.io/v1alpha1", + "kind": "ConfigAuditReport", + "metadata": { + "annotations": { + "trivy-operator.aquasecurity.github.io/report-ttl": "24h0m0s" + }, + "creationTimestamp": "2023-03-23T16:22:54Z", + "generation": 1, + "labels": { + "plugin-config-hash": "659b7b9c46", + "resource-spec-hash": "fc85b485f", + "trivy-operator.resource.kind": "ReplicaSet", + "trivy-operator.resource.name": "nginx-deployment-965685897", + "trivy-operator.resource.namespace": "default" + }, + "name": "replicaset-nginx-deployment-965685897", + "namespace": "default", + "ownerReferences": [ + { + "apiVersion": "apps/v1", + "blockOwnerDeletion": false, + "controller": true, + "kind": "ReplicaSet", + "name": "nginx-deployment-965685897", + "uid": "d19c7f74-b4c3-429d-9a45-1b2f5efc3c88" + } + ], + "resourceVersion": "1268", + "uid": "a92e0951-e988-419d-8602-6852f920ce06" + }, + "report": { + "checks": [ + { + "category": "Kubernetes Security Check", + "checkID": "KSV014", + "description": "An immutable root file system prevents applications from writing to their local disk. This can limit intrusions, as attackers will not be able to tamper with the file system or write foreign executables to disk.", + "messages": [ + "Container 'nginx' of ReplicaSet 'nginx-deployment-965685897' should set 'securityContext.readOnlyRootFilesystem' to true" + ], + "severity": "LOW", + "success": false, + "title": "Root file system is not read-only" + }, + { + "category": "Kubernetes Security Check", + "checkID": "KSV016", + "description": "When containers have memory requests specified, the scheduler can make better decisions about which nodes to place pods on, and how to deal with resource contention.", + "messages": [ + "Container 'nginx' of ReplicaSet 'nginx-deployment-965685897' should set 'resources.requests.memory'" + ], + "severity": "LOW", + "success": false, + "title": "Memory requests not specified" + }, + { + "category": "Kubernetes Security Check", + "checkID": "KSV030", + "description": "The RuntimeDefault/Localhost seccomp profile must be required, or allow specific additional profiles.", + "messages": [ + "Either Pod or Container should set 'securityContext.seccompProfile.type' to 'RuntimeDefault'" + ], + "severity": "LOW", + "success": false, + "title": "Default Seccomp profile not set" + }, + { + "category": "Kubernetes Security Check", + "checkID": "KSV015", + "description": "When containers have resource requests specified, the scheduler can make better decisions about which nodes to place pods on, and how to deal with resource contention.", + "messages": [ + "Container 'nginx' of ReplicaSet 'nginx-deployment-965685897' should set 'resources.requests.cpu'" + ], + "severity": "LOW", + "success": false, + "title": "CPU requests not specified" + }, + { + "category": "Kubernetes Security Check", + "checkID": "KSV011", + "description": "Enforcing CPU limits prevents DoS via resource exhaustion.", + "messages": [ + "Container 'nginx' of ReplicaSet 'nginx-deployment-965685897' should set 'resources.limits.cpu'" + ], + "severity": "LOW", + "success": false, + "title": "CPU not limited" + }, + { + "category": "Kubernetes Security Check", + "checkID": "KSV012", + "description": "'runAsNonRoot' forces the running image to run as a non-root user to ensure least privileges.", + "messages": [ + "Container 'nginx' of ReplicaSet 'nginx-deployment-965685897' should set 'securityContext.runAsNonRoot' to true" + ], + "severity": "MEDIUM", + "success": false, + "title": "Runs as root user" + }, + { + "category": "Kubernetes Security Check", + "checkID": "KSV018", + "description": "Enforcing memory limits prevents DoS via resource exhaustion.", + "messages": [ + "Container 'nginx' of ReplicaSet 'nginx-deployment-965685897' should set 'resources.limits.memory'" + ], + "severity": "LOW", + "success": false, + "title": "Memory not limited" + }, + { + "category": "Kubernetes Security Check", + "checkID": "KSV110", + "description": "ensure that default namespace should not be used", + "messages": [ + "ReplicaSet 'nginx-deployment-965685897' should not be set with 'default' namespace" + ], + "severity": "LOW", + "success": false, + "title": "The default namespace should not be used" + }, + { + "category": "Kubernetes Security Check", + "checkID": "KSV003", + "description": "The container should drop all default capabilities and add only those that are needed for its execution.", + "messages": [ + "Container 'nginx' of ReplicaSet 'nginx-deployment-965685897' should add 'ALL' to 'securityContext.capabilities.drop'" + ], + "severity": "LOW", + "success": false, + "title": "Default capabilities not dropped" + }, + { + "category": "Kubernetes Security Check", + "checkID": "KSV021", + "description": "Force the container to run with group ID \u003e 10000 to avoid conflicts with the host’s user table.", + "messages": [ + "Container 'nginx' of ReplicaSet 'nginx-deployment-965685897' should set 'securityContext.runAsGroup' \u003e 10000" + ], + "severity": "LOW", + "success": false, + "title": "Runs with low group ID" + }, + { + "category": "Kubernetes Security Check", + "checkID": "KSV001", + "description": "A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.", + "messages": [ + "Container 'nginx' of ReplicaSet 'nginx-deployment-965685897' should set 'securityContext.allowPrivilegeEscalation' to false" + ], + "severity": "MEDIUM", + "success": false, + "title": "Process can elevate its own privileges" + }, + { + "category": "Kubernetes Security Check", + "checkID": "KSV106", + "description": "Containers must drop ALL capabilities, and are only permitted to add back the NET_BIND_SERVICE capability.", + "messages": [ + "container should drop all" + ], + "severity": "LOW", + "success": false, + "title": "Container capabilities must only include NET_BIND_SERVICE" + }, + { + "category": "Kubernetes Security Check", + "checkID": "KSV020", + "description": "Force the container to run with user ID \u003e 10000 to avoid conflicts with the host’s user table.", + "messages": [ + "Container 'nginx' of ReplicaSet 'nginx-deployment-965685897' should set 'securityContext.runAsUser' \u003e 10000" + ], + "severity": "LOW", + "success": false, + "title": "Runs with low user ID" + } + ], + "scanner": { + "name": "Trivy", + "vendor": "Aqua Security", + "version": "dev" + }, + "summary": { + "criticalCount": 0, + "highCount": 0, + "lowCount": 11, + "mediumCount": 2 + }, + "updateTimestamp": "2023-03-23T16:22:54Z" + } + }, + { + "kind": "VulnerabilityReport", + "apiVersion": "aquasecurity.github.io/v1alpha1", + "metadata": { + "name": "pod-ubuntu-ubuntu", + "namespace": "lbc", + "uid": "e2c1fa59-051b-479d-ab47-f7bf6e7f858d", + "resourceVersion": "26700784781", + "generation": 1, + "creationTimestamp": "2024-01-23T13:43:55Z", + "labels": { + "resource-spec-hash": "666674544b", + "trivy-operator.container.name": "ubuntu", + "trivy-operator.resource.kind": "Pod", + "trivy-operator.resource.name": "ubuntu", + "trivy-operator.resource.namespace": "lbc" + }, + "annotations": { + "trivy-operator.aquasecurity.github.io/report-ttl": "24h0m0s" + }, + "ownerReferences": [ + { + "apiVersion": "v1", + "kind": "Pod", + "name": "ubuntu", + "uid": "aa8d6ec8-5417-4190-93e9-6d4d78dc8da9", + "controller": true, + "blockOwnerDeletion": false + } + ], + "managedFields": [ + { + "manager": "trivy-operator", + "operation": "Update", + "apiVersion": "aquasecurity.github.io/v1alpha1", + "time": "2024-01-23T13:43:55Z", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:annotations": { + ".": {}, + "f:trivy-operator.aquasecurity.github.io/report-ttl": {} + }, + "f:labels": { + ".": {}, + "f:resource-spec-hash": {}, + "f:trivy-operator.container.name": {}, + "f:trivy-operator.resource.kind": {}, + "f:trivy-operator.resource.name": {}, + "f:trivy-operator.resource.namespace": {} + }, + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"aa8d6ec8-5417-4190-93e9-6d4d78dc8da9\"}": {} + } + }, + "f:report": { + ".": {}, + "f:artifact": { + ".": {}, + "f:digest": {}, + "f:repository": {}, + "f:tag": {} + }, + "f:os": { + ".": {}, + "f:family": {}, + "f:name": {} + }, + "f:registry": { + ".": {}, + "f:server": {} + }, + "f:scanner": { + ".": {}, + "f:name": {}, + "f:vendor": {}, + "f:version": {} + }, + "f:summary": { + ".": {}, + "f:criticalCount": {}, + "f:highCount": {}, + "f:lowCount": {}, + "f:mediumCount": {}, + "f:noneCount": {}, + "f:unknownCount": {} + }, + "f:updateTimestamp": {}, + "f:vulnerabilities": {} + } + } + } + ] + }, + "report": { + "updateTimestamp": "2024-01-23T13:43:55Z", + "scanner": { + "name": "Trivy", + "vendor": "Aqua Security", + "version": "0.48.3" + }, + "registry": { + "server": "index.docker.io" + }, + "artifact": { + "repository": "library/ubuntu", + "digest": "sha256:f78909c2b360d866b3220655c0b079838258b8891a12ac25fc670f0cbb54229f", + "tag": "20.04" + }, + "os": { + "family": "ubuntu", + "name": "20.04" + }, + "summary": { + "criticalCount": 0, + "highCount": 0, + "mediumCount": 5, + "lowCount": 0, + "unknownCount": 0, + "noneCount": 0 + }, + "vulnerabilities": [ + { + "vulnerabilityID": "CVE-2024-0553", + "resource": "libgnutls30", + "installedVersion": "3.6.13-2ubuntu1.9", + "fixedVersion": "3.6.13-2ubuntu1.10", + "publishedDate": "2024-01-16T12:15:45Z", + "lastModifiedDate": "2024-01-19T21:15:08Z", + "severity": "MEDIUM", + "title": "gnutls: incomplete fix for CVE-2023-5981", + "primaryLink": "https://avd.aquasec.com/nvd/cve-2024-0553", + "links": [], + "score": 5.9, + "target": "ubuntu:20.04 (ubuntu 20.04)", + "class": "os-pkgs", + "packageType": "ubuntu" + }, + { + "vulnerabilityID": "CVE-2024-22365", + "resource": "libpam-modules", + "installedVersion": "1.3.1-5ubuntu4.6", + "fixedVersion": "1.3.1-5ubuntu4.7", + "publishedDate": "", + "lastModifiedDate": "", + "severity": "MEDIUM", + "title": "pam: allowing unpriledged user to block another user namespace", + "primaryLink": "https://avd.aquasec.com/nvd/cve-2024-22365", + "links": [], + "score": 5.5, + "target": "ubuntu:20.04 (ubuntu 20.04)", + "class": "os-pkgs", + "packageType": "ubuntu" + }, + { + "vulnerabilityID": "CVE-2024-22365", + "resource": "libpam-modules-bin", + "installedVersion": "1.3.1-5ubuntu4.6", + "fixedVersion": "1.3.1-5ubuntu4.7", + "publishedDate": "", + "lastModifiedDate": "", + "severity": "MEDIUM", + "title": "pam: allowing unpriledged user to block another user namespace", + "primaryLink": "https://avd.aquasec.com/nvd/cve-2024-22365", + "links": [], + "score": 5.5, + "target": "ubuntu:20.04 (ubuntu 20.04)", + "class": "os-pkgs", + "packageType": "ubuntu" + }, + { + "vulnerabilityID": "CVE-2024-22365", + "resource": "libpam-runtime", + "installedVersion": "1.3.1-5ubuntu4.6", + "fixedVersion": "1.3.1-5ubuntu4.7", + "publishedDate": "", + "lastModifiedDate": "", + "severity": "MEDIUM", + "title": "pam: allowing unpriledged user to block another user namespace", + "primaryLink": "https://avd.aquasec.com/nvd/cve-2024-22365", + "links": [], + "score": 5.5, + "target": "ubuntu:20.04 (ubuntu 20.04)", + "class": "os-pkgs", + "packageType": "ubuntu" + }, + { + "vulnerabilityID": "CVE-2024-22365", + "resource": "libpam0g", + "installedVersion": "1.3.1-5ubuntu4.6", + "fixedVersion": "1.3.1-5ubuntu4.7", + "publishedDate": "", + "lastModifiedDate": "", + "severity": "MEDIUM", + "title": "pam: allowing unpriledged user to block another user namespace", + "primaryLink": "https://avd.aquasec.com/nvd/cve-2024-22365", + "links": [], + "score": 5.5, + "target": "ubuntu:20.04 (ubuntu 20.04)", + "class": "os-pkgs", + "packageType": "ubuntu" + } + ] + } + } +] \ No newline at end of file diff --git a/unittests/tools/test_trivy_operator_parser.py b/unittests/tools/test_trivy_operator_parser.py index 8ac6b5f3189..5e4a71558da 100644 --- a/unittests/tools/test_trivy_operator_parser.py +++ b/unittests/tools/test_trivy_operator_parser.py @@ -135,7 +135,7 @@ def test_vulnerabilityreport_extended(self): self.assertEqual("3.6.13-2ubuntu1.10", finding.mitigation) self.assertEqual(5.9, finding.cvssv3_score) self.assertEqual("ubuntu:20.04 (ubuntu 20.04)", finding.file_path) - self.assertEqual("os-pkgs, ubuntu", str(finding.tags)) + self.assertEqual("lbc, os-pkgs, ubuntu", str(finding.tags)) def test_cis_benchmark(self): with open(sample_path("cis_benchmark.json"), encoding="utf-8") as test_file: @@ -157,3 +157,9 @@ def test_cis_benchmark(self): self.assertEqual("Medium", finding.severity) self.assertEqual(1, len(finding.unsaved_vulnerability_ids)) self.assertEqual("AVD-KSV-0012", finding.unsaved_vulnerability_ids[0]) + + def test_findings_in_list(self): + with open(sample_path("findings_in_list.json"), encoding="utf-8") as test_file: + parser = TrivyOperatorParser() + findings = parser.get_findings(test_file, Test()) + self.assertEqual(len(findings), 18) From 68e0a8bae0b173c98ff6fd924ba5ea36071c1067 Mon Sep 17 00:00:00 2001 From: Harold Blankenship <36673698+hblankenship@users.noreply.github.com> Date: Fri, 1 Nov 2024 16:45:10 -0500 Subject: [PATCH 08/12] use engagement_end_date (#11174) --- dojo/api_v2/serializers.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dojo/api_v2/serializers.py b/dojo/api_v2/serializers.py index 56a18265064..bc9cbc03b86 100644 --- a/dojo/api_v2/serializers.py +++ b/dojo/api_v2/serializers.py @@ -2258,6 +2258,13 @@ def setup_common_context(self, data: dict) -> dict: if context.get("scan_date") else None ) + + # engagement end date was not being used at all and so target_end would also turn into None + # in this case, do not want to change target_end unless engagement_end exists + eng_end_date = context.get("engagement_end_date", None) + if eng_end_date: + context["target_end"] = context.get("engagement_end_date") + return context From 8a08e60fabb4c93c546f668fae73a921f88d4daf Mon Sep 17 00:00:00 2001 From: manuelsommer <47991713+manuel-sommer@users.noreply.github.com> Date: Sat, 2 Nov 2024 02:59:22 +0100 Subject: [PATCH 09/12] fix unittest documentation #11128 (#11143) * fix unittest documentation #11128 * udpate * Update docs/content/en/contributing/how-to-write-a-parser.md Co-authored-by: Charles Neill <1749665+cneill@users.noreply.github.com> * Update docs/content/en/contributing/how-to-write-a-parser.md Co-authored-by: Charles Neill <1749665+cneill@users.noreply.github.com> --------- Co-authored-by: Charles Neill <1749665+cneill@users.noreply.github.com> --- .../en/contributing/how-to-write-a-parser.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/content/en/contributing/how-to-write-a-parser.md b/docs/content/en/contributing/how-to-write-a-parser.md index c87846cb620..5652f0dbc59 100644 --- a/docs/content/en/contributing/how-to-write-a-parser.md +++ b/docs/content/en/contributing/how-to-write-a-parser.md @@ -16,9 +16,9 @@ All commands assume that you're located at the root of the django-DefectDojo clo - It's advised that you create a dedicated branch for your development, such as `git checkout -b parser-name`. It is easiest to use the docker compose deployment as it has hot-reload capbility for uWSGI. -Set up your environment to use the debug environment: +Set up your environment to use the dev environment: -`$ docker/setEnv.sh debug` +`$ docker/setEnv.sh dev` Please have a look at [DOCKER.md](https://github.com/DefectDojo/django-DefectDojo/blob/master/readme-docs/DOCKER.md) for more details. @@ -294,12 +294,24 @@ This local command will launch the unit test for your new parser $ docker compose exec uwsgi bash -c 'python manage.py test unittests.tools.. -v2' {{< /highlight >}} +or like this: + +{{< highlight bash >}} +$ ./dc-unittest.sh --test-case unittests.tools.. +{{< /highlight >}} + Example for the blackduck hub parser: {{< highlight bash >}} $ docker compose exec uwsgi bash -c 'python manage.py test unittests.tools.test_blackduck_csv_parser.TestBlackduckHubParser -v2' {{< /highlight >}} +or like this: + +{{< highlight bash >}} +$ ./dc-unittest.sh --test-case unittests.tools.test_blackduck_csv_parser.TestBlackduckHubParser +{{< /highlight >}} + {{% alert title="Information" color="info" %}} If you want to run all unit tests, simply run `$ docker compose exec uwsgi bash -c 'python manage.py test unittests -v2'` {{% /alert %}} From 1b68cbe75ff5aaed23af2f5ca833e2e57b61efa5 Mon Sep 17 00:00:00 2001 From: Paul Osinski <42211303+paulOsinski@users.noreply.github.com> Date: Mon, 4 Nov 2024 11:19:16 -0500 Subject: [PATCH 10/12] correct broken documentation links (#11178) * correct broken documentation links * Update docs/content/en/getting_started/architecture.md Co-authored-by: Charles Neill <1749665+cneill@users.noreply.github.com> * Update installation.md with new AWS launch guide --------- Co-authored-by: Paul Osinski Co-authored-by: Jay Paz Co-authored-by: Charles Neill <1749665+cneill@users.noreply.github.com> Co-authored-by: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> --- docs/content/en/getting_started/installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/en/getting_started/installation.md b/docs/content/en/getting_started/installation.md index a127f36e492..8f6affa702e 100644 --- a/docs/content/en/getting_started/installation.md +++ b/docs/content/en/getting_started/installation.md @@ -14,11 +14,11 @@ See instructions in [DOCKER.md]( Date: Mon, 4 Nov 2024 10:37:03 -0600 Subject: [PATCH 11/12] Update .settings.dist.py.sha256sum --- dojo/settings/.settings.dist.py.sha256sum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dojo/settings/.settings.dist.py.sha256sum b/dojo/settings/.settings.dist.py.sha256sum index 11afd6a9628..2347c09dca8 100644 --- a/dojo/settings/.settings.dist.py.sha256sum +++ b/dojo/settings/.settings.dist.py.sha256sum @@ -1 +1 @@ -fcc15cb97df6ff9ef6752a1fe498502126174285e37d67640a6cc7a83314d951 \ No newline at end of file +39cdd5dfe53499bfe201d3e5a0f55b20514272235e86db7d5238f2663b79f946 From 927305031f94c06e9275244dcb79c09c06ffcb0d Mon Sep 17 00:00:00 2001 From: Ross Esposito Date: Mon, 4 Nov 2024 10:52:17 -0600 Subject: [PATCH 12/12] Fixing sha again --- dojo/settings/.settings.dist.py.sha256sum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dojo/settings/.settings.dist.py.sha256sum b/dojo/settings/.settings.dist.py.sha256sum index 2347c09dca8..259f13a4c69 100644 --- a/dojo/settings/.settings.dist.py.sha256sum +++ b/dojo/settings/.settings.dist.py.sha256sum @@ -1 +1 @@ -39cdd5dfe53499bfe201d3e5a0f55b20514272235e86db7d5238f2663b79f946 +6b9365d002880ae64ab54da905ede076db5a8661960f8f1e2793b7f4d25ff7e8