Skip to content

Commit 8a7ff18

Browse files
authored
Merge pull request #13721 from DefectDojo/master-into-dev/2.52.2-2.53.0-dev
Release: Merge back 2.52.2 into dev from: master-into-dev/2.52.2-2.53.0-dev
2 parents 461a885 + 6f0897a commit 8a7ff18

51 files changed

Lines changed: 897 additions & 161 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/renovate.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@
2727
"matchDatasources": "github-releases",
2828
"matchPackageNames": "renovatebot/renovate",
2929
"schedule": ["* * * * 0"]
30+
},{
31+
"description": "Minikube does not like freshly released k8s. We need to wait some time so it will be adopted",
32+
"matchDatasources": [
33+
"custom.endoflife-oldest-maintained",
34+
"github-releases"
35+
],
36+
"matchPackageNames": [
37+
"kubernetes",
38+
"kubernetes/kubernetes"
39+
],
40+
"minimumReleaseAge": "2 days"
3041
}],
3142
"customDatasources": {
3243
"endoflife-oldest-maintained": {

.github/workflows/test-helm-chart.yml

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ jobs:
115115
if: startsWith(github.head_ref, 'renovate/') || startsWith(github.head_ref, 'dependabot/')
116116
run: |
117117
yq -i '.annotations."artifacthub.io/changes" += "- kind: changed\n description: ${{ github.event.pull_request.title }}\n"' helm/defectdojo/Chart.yaml
118+
git add helm/defectdojo/Chart.yaml
119+
git commit -m "ci: update Chart annotations from PR #${{ github.event.pull_request.number }}" || echo "No changes to commit"
118120
119121
- name: Run helm-docs (update)
120122
uses: losisin/helm-docs-github-action@a57fae5676e4c55a228ea654a1bcaec8dd3cf5b5 # v1.6.2
@@ -123,27 +125,25 @@ jobs:
123125
chart-search-root: "helm/defectdojo"
124126
git-push: true
125127

126-
# Documentation provided in the README file needs to contain the latest information from `values.yaml` and all other related assets.
127-
# If this step fails, install https://github.com/norwoodj/helm-docs and run locally `helm-docs --chart-search-root helm/defectdojo` before committing your changes.
128-
# The helm-docs documentation will be generated for you.
129128
- name: Run helm-docs (check)
130129
uses: losisin/helm-docs-github-action@a57fae5676e4c55a228ea654a1bcaec8dd3cf5b5 # v1.6.2
131-
if: ! startsWith(github.head_ref, 'renovate/') || startsWith(github.head_ref, 'dependabot/')
130+
if: ${{ !(startsWith(github.head_ref, 'renovate/') || startsWith(github.head_ref, 'dependabot/')) }}
132131
with:
133132
fail-on-diff: true
134133
chart-search-root: "helm/defectdojo"
135134

135+
- name: Failed Information
136+
if: failure()
137+
run: |-
138+
echo "Your HELM chart changed but you haven't adjusted documentation. Check https://github.com/defectdojo/django-DefectDojo/tree/master/helm/defectdojo#helm-docs-update for more information."
139+
136140
generate_schema:
137141
name: Update schema
138142
runs-on: ubuntu-latest
139143
steps:
140144
- name: Checkout
141145
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
142146

143-
# The HELM structure supports the existence of a `values.schema.json` file. This file is used to validate all values provided by the user before Helm starts rendering templates.
144-
# The chart needs to have a `values.schema.json` file that is compatible with the default `values.yaml` file.
145-
# If this step fails, install https://github.com/losisin/helm-values-schema-json and run locally `helm schema --use-helm-docs` in `helm/defectdojo` before committing your changes.
146-
# The helm schema will be generated for you.
147147
- name: Generate values schema json
148148
uses: losisin/helm-values-schema-json-action@660c441a4a507436a294fc55227e1df54aca5407 # v2.3.1
149149
with:
@@ -152,6 +152,11 @@ jobs:
152152
useHelmDocs: true
153153
values: values.yaml
154154

155+
- name: Failed Information
156+
if: failure()
157+
run: |-
158+
echo "Your HELM chart changed but you haven't adjusted schema. Check https://github.com/defectdojo/django-DefectDojo/tree/master/helm/defectdojo#helm-schema-update for more information."
159+
155160
lint_format:
156161
name: Lint chart (format)
157162
runs-on: ubuntu-latest

docs/content/en/connecting_your_tools/import_intro.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,16 @@ description: "Learn how to import data manually, through the API, or via a conne
44
weight: 1
55
---
66

7-
One of the things we understand at DefectDojo is that every company’s security needs are completely different. There is no ‘one\-size\-fits\-all’ approach. As your organization changes, having a flexible approach is key.
8-
9-
DefectDojo allows you to connect your security tools in a flexible way to match those changes.
7+
One of the things we understand at DefectDojo is that every company’s security needs are completely different. There is no one-size-fits-all approach. As your organization changes, having a flexible approach is key, and DefectDojo allows you to connect your security tools in a flexible way to match those changes.
108

119
## Scan Upload Methods
1210

13-
When DefectDojo receives a vulnerability report from a security tool, it will create Findings based on the vulnerabilities contained within that report. DefectDojo acts as the central repository for these Findings where they can be triaged, remediated or otherwise addressed by you and your team.
11+
When DefectDojo receives a vulnerability report from a security tool, it will create Findings based on the vulnerabilities contained within that report. DefectDojo acts as the central repository for these Findings where they can be triaged, remediated, or otherwise addressed by you and your team.
1412

1513
There are two main ways that DefectDojo can upload Finding reports.
1614

1715
* Via direct **import** through the UI: [Import Scan Form](../import_scan_files/import_scan_ui)
18-
* Via **API** endpoint (allowing for automated data ingest): See [API Docs](https://docs.defectdojo.com/en/api/api-v2-docs/)
16+
* Via **API** endpoint (allowing for automated data ingestion): See [API Docs](https://docs.defectdojo.com/en/api/api-v2-docs/)
1917

2018
#### DefectDojo Pro Methods
2119

@@ -29,8 +27,8 @@ There are two main ways that DefectDojo can upload Finding reports.
2927

3028
| | **UI Import** | **API** | **Connectors** <span style="background-color:rgba(242, 86, 29, 0.3)">(Pro)</span> | **Smart Upload** <span style="background-color:rgba(242, 86, 29, 0.3)">(Pro)</span>|
3129
| --- | --- | --- | --- | --- |
32-
| **Supported Scan Types** | All: see [Supported Tools](/supported_tools/) | All: see [Supported Tools](/supported_tools/) | Snyk, Semgrep, Burp Suite, AWS Security Hub, Probely, Checkmarx, Tenable | Nexpose, NMap, OpenVas, Qualys, Tenable |
33-
| **Automation?** | Available via API: `/reimport` `/import` endpoints | Triggered from [CLI Importer](../external_tools) or external code | Connectors is inherently automated | Available via API: `/smart_upload_import` endpoint |
30+
| **Supported Scan Types** | All: see [Supported Tools](/supported_tools/) | All: see [Supported Tools](/supported_tools/) | Anchore, AWS Security Hub, BurpSuite, Checkmarx ONE, Dependency-Track, Probely, Semgrep, SonarQube, Snyk, Tenable, Wiz | Nexpose, NMap, OpenVas, Qualys, Tenable |
31+
| **Automation?** | Available via API: `/reimport` `/import` endpoints | Triggered from [CLI Importer](../external_tools) or external code | Connectors is an inherently automated feature | Available via API: `/smart_upload_import` endpoint |
3432

3533
### Product Hierarchy and organization
3634

docs/content/en/working_with_findings/organizing_engagements_tests/product_hierarchy.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,16 +116,17 @@ Tests always have:
116116
* an associated test **Environment**
117117
* an associated **Engagement**
118118

119-
Tests can be created in different ways. Tests can be automatically created when scan data is imported directly into to an Engagement, resulting in a new Test containing the scan data. Tests can also be created in anticipation of planning future engagements, or for manually entered security findings requiring tracking and remediation.
119+
Tests can be created in different ways. Tests can be automatically created when scan data is imported directly into an Engagement, resulting in a new Test containing the scan data. Tests can also be created in anticipation of planning future engagements, or for manually entered security findings requiring tracking and remediation.
120120

121121
### **Test Types**
122122

123123
DefectDojo supports two categories of Test Types:
124124

125125
1. **Parser-based Test Types**: These correspond to specific security scanners that produce output in formats like XML, JSON, or CSV. When importing scan results, DefectDojo uses specialized parsers to convert the scanner output into Findings.
126126

127-
2. **Non-parser Test Types**: These are used for manually created findings not imported from a scan files.
128-
The following Test Types appear in the "Scan Type" dropdown when creating a new test, but will not appear when selecting "Import Scan":
127+
2. **Non-parser Test Types**: These are used for manually created Findings not imported from scan files. These Test Types use the [Generic Findings Import](/supported_tools/parsers/generic_findings_import/) method to render Findings and metadata.
128+
129+
The following Test Types appear in the "Scan Type" dropdown when creating a new test.
129130
* API Test
130131
* Static Check
131132
* Pen Test

docs/content/supported_tools/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ DefectDojo can parse data from 200+ security reports and counting.
2626

2727
| [Connectors](/en/connecting_your_tools/connectors/about_connectors/): supported tools | [Smart Upload](/en/connecting_your_tools/import_scan_files/smart_upload/): supported tools |
2828
| --- | --- |
29-
| AWS Security Hub, BurpSuite, Checkmarx ONE, Dependency-Track, Probely, Semgrep, SonarQube, Snyk, Tenable | Nexpose, NMap, OpenVas, Qualys, Tenable, Wiz |
29+
| Anchore, AWS Security Hub, BurpSuite, Checkmarx ONE, Dependency-Track, Probely, Semgrep, SonarQube, Snyk, Tenable | Nexpose, NMap, OpenVas, Qualys, Tenable, Wiz |
3030

3131
# All Supported Tools
3232

docs/content/supported_tools/parsers/generic_findings_import.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ Open-source and Pro users can use Generic Findings Import as a method to ingest
88

99
Using Generic Findings Import will create a new Test Type in your DefectDojo instance called "`{The Name Of Your Test}` (Generic Findings Import)". For example, this JSON content will result in a Test Type called "Example Report (Generic Findings Import)":
1010

11+
```
1112
{
1213
"name": "Example Report",
1314
"findings": []
1415
}
16+
```
1517

1618
DefectDojo Pro users can also consider using the [Universal Parser](../universal_parser), a tool which allows for highly customizable JSON, XML and CSV imports.
1719

18-
For more information on supported parameters for Generic Findings Import, see the [Parser Guide](../file/generic)
20+
For more information on supported parameters for Generic Findings Import, see the related [Parser Guide](../file/generic).

dojo/api_v2/views.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from django.db.models.query import QuerySet as DjangoQuerySet
1515
from django.http import FileResponse, HttpResponse
1616
from django.shortcuts import get_object_or_404
17+
from django.urls import reverse
1718
from django.utils import timezone
1819
from django_filters.rest_framework import DjangoFilterBackend
1920
from drf_spectacular.renderers import OpenApiJsonRenderer2
@@ -176,6 +177,7 @@
176177
generate_file_response,
177178
get_setting,
178179
get_system_setting,
180+
process_tag_notifications,
179181
)
180182

181183
logger = logging.getLogger(__name__)
@@ -528,6 +530,15 @@ def notes(self, request, pk=None):
528530
)
529531
note.save()
530532
engagement.notes.add(note)
533+
# Determine if we need to send any notifications for user mentioned
534+
process_tag_notifications(
535+
request=request,
536+
note=note,
537+
parent_url=request.build_absolute_uri(
538+
reverse("view_engagement", args=(engagement.id,)),
539+
),
540+
parent_title=f"Engagement: {engagement.name}",
541+
)
531542

532543
serialized_note = serializers.NoteSerializer(
533544
{"author": author, "entry": entry, "private": private},
@@ -1086,6 +1097,15 @@ def notes(self, request, pk=None):
10861097
)
10871098
note.save()
10881099
finding.notes.add(note)
1100+
# Determine if we need to send any notifications for user mentioned
1101+
process_tag_notifications(
1102+
request=request,
1103+
note=note,
1104+
parent_url=request.build_absolute_uri(
1105+
reverse("view_finding", args=(finding.id,)),
1106+
),
1107+
parent_title=f"Finding: {finding.title}",
1108+
)
10891109

10901110
if finding.has_jira_issue:
10911111
jira_helper.add_comment(finding, note)
@@ -2135,6 +2155,15 @@ def notes(self, request, pk=None):
21352155
)
21362156
note.save()
21372157
test.notes.add(note)
2158+
# Determine if we need to send any notifications for user mentioned
2159+
process_tag_notifications(
2160+
request=request,
2161+
note=note,
2162+
parent_url=request.build_absolute_uri(
2163+
reverse("view_test", args=(test.id,)),
2164+
),
2165+
parent_title=f"Test: {test.title}",
2166+
)
21382167

21392168
serialized_note = serializers.NoteSerializer(
21402169
{"author": author, "entry": entry, "private": private},

dojo/finding/helper.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
from contextlib import suppress
3+
from datetime import datetime
34
from time import strftime
45

56
from django.conf import settings
@@ -9,6 +10,7 @@
910
from django.dispatch.dispatcher import receiver
1011
from django.urls import reverse
1112
from django.utils import timezone
13+
from django.utils.timezone import is_naive, make_aware, now
1214
from fieldsignals import pre_save_changed
1315

1416
import dojo.jira_link.helper as jira_helper
@@ -797,6 +799,17 @@ def save_vulnerability_ids_template(finding_template, vulnerability_ids):
797799
finding_template.cve = None
798800

799801

802+
def normalize_datetime(value):
803+
"""Ensure value is timezone-aware datetime."""
804+
if value:
805+
if not isinstance(value, datetime):
806+
value = datetime.combine(value, datetime.min.time())
807+
# Make timezone-aware if naive
808+
if is_naive(value):
809+
value = make_aware(value)
810+
return value
811+
812+
800813
def close_finding(
801814
*,
802815
finding,
@@ -818,15 +831,16 @@ def close_finding(
818831
"""
819832
# Core status updates
820833
finding.is_mitigated = is_mitigated
821-
now = timezone.now()
822-
finding.mitigated = mitigated or now
834+
current_time = now()
835+
mitigated_date = normalize_datetime(mitigated) or current_time
836+
finding.mitigated = mitigated_date
823837
finding.mitigated_by = mitigated_by or user
824838
finding.active = False
825839
finding.false_p = bool(false_p)
826840
finding.out_of_scope = bool(out_of_scope)
827841
finding.duplicate = bool(duplicate)
828842
finding.under_review = False
829-
finding.last_reviewed = finding.mitigated
843+
finding.last_reviewed = mitigated_date
830844
finding.last_reviewed_by = user
831845

832846
# Create note if provided
@@ -836,16 +850,16 @@ def close_finding(
836850
entry=note_entry,
837851
author=user,
838852
note_type=note_type,
839-
date=finding.mitigated,
853+
date=mitigated_date,
840854
)
841855
finding.notes.add(new_note)
842856

843857
# Endpoint statuses
844858
for status in finding.status_finding.all():
845859
status.mitigated_by = finding.mitigated_by
846-
status.mitigated_time = finding.mitigated
860+
status.mitigated_time = mitigated_date
847861
status.mitigated = True
848-
status.last_modified = timezone.now()
862+
status.last_modified = current_time
849863
status.save()
850864

851865
# Risk acceptance

dojo/finding/views.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,12 +1145,14 @@ def close_finding(request, fid):
11451145
note_type_activation = Note_Type.objects.filter(is_active=True)
11461146
missing_note_types = get_missing_mandatory_notetypes(finding) if len(note_type_activation) else note_type_activation
11471147
form = CloseFindingForm(
1148+
instance=finding,
11481149
missing_note_types=missing_note_types,
11491150
can_edit_mitigated_data=finding_helper.can_edit_mitigated_data(request.user),
11501151
)
11511152
if request.method == "POST":
11521153
form = CloseFindingForm(
11531154
request.POST,
1155+
instance=finding,
11541156
missing_note_types=missing_note_types,
11551157
can_edit_mitigated_data=finding_helper.can_edit_mitigated_data(request.user),
11561158
)

dojo/settings/settings.dist.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,6 +1949,7 @@ def saml2_attrib_map_format(din):
19491949
"TS-": """https://tailscale.com/security-bulletins#""", # e.g. https://tailscale.com/security-bulletins or https://tailscale.com/security-bulletins#ts-2022-001-1243
19501950
"TYPO3-": "https://typo3.org/security/advisory/", # e.g. https://typo3.org/security/advisory/typo3-core-sa-2025-010
19511951
"USN-": "https://ubuntu.com/security/notices/", # e.g. https://ubuntu.com/security/notices/USN-6642-1
1952+
"VA-": "https://cvepremium.circl.lu/vuln/", # e.g. https://cvepremium.circl.lu/vuln/va-25-282-01
19521953
"VAR-": "https://cvepremium.circl.lu/vuln/", # e.g. https://cvepremium.circl.lu/vuln/var-201801-0152
19531954
"VNS": "https://vulners.com/",
19541955
"WID-SEC-W-": "https://cvepremium.circl.lu/vuln/", # e.g. https://cvepremium.circl.lu/vuln/wid-sec-w-2025-1468

0 commit comments

Comments
 (0)