Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9fc3d88
Update versions in application files
Dec 8, 2025
75d18e5
Merge pull request #13845 from DefectDojo/master-into-bugfix/2.53.1-2…
rossops Dec 8, 2025
3b1b5da
[docs] asset/organization in Pro (#13848)
paulOsinski Dec 8, 2025
1fb8dcf
[docs] Pro changelog updates (#13855)
paulOsinski Dec 11, 2025
ee9ee74
update sso docs for group read all permission (#13850)
paulOsinski Dec 11, 2025
764f071
fix(GHA): Failed in all dependences had not been in latest version (#…
kiblik Dec 15, 2025
1d4d0db
fix(HELM): Use renovate-compatible format (#13866)
kiblik Dec 15, 2025
6aa64b9
:lipstick: Beautify Rubocop json (#13894)
manuel-sommer Dec 15, 2025
b4771c0
:tada: Add ICSA vulnid (#13895)
manuel-sommer Dec 15, 2025
efe0f5d
async delete: retry on deadlock (#13863)
valentijnscholten Dec 15, 2025
c8cf437
feat(releases): Add section for GHA (#13867)
kiblik Dec 15, 2025
01b2a16
fix(HELM): Improve autogeneration of annotation (#13879)
kiblik Dec 15, 2025
fb35166
fix logger NoneType (#13880)
valentijnscholten Dec 15, 2025
fa8b8a6
Update RELEASING.md with release type clarifications (#13881)
valentijnscholten Dec 15, 2025
05138f3
jira: add none checks in a few places (#13886)
valentijnscholten Dec 15, 2025
0f4aad7
foundy_by: optimize for dedupe (#13888)
valentijnscholten Dec 15, 2025
f4f0b36
importers: log time spent on parsing (#13892)
valentijnscholten Dec 15, 2025
ca91c99
reimport: add management command to reimport sample scans (#13893)
valentijnscholten Dec 15, 2025
a15332e
reimport: add test for internal duplicates during matching (#13890)
valentijnscholten Dec 15, 2025
da66f9e
Update versions in application files
Dec 15, 2025
7e4585d
Updating helm deps
rossops Dec 15, 2025
f21b1ff
Merge pull request #13903 from DefectDojo/release/2.53.2
rossops Dec 15, 2025
33a25c8
Update versions in application files
Dec 15, 2025
7b73a29
Merge branch 'dev' into master-into-dev/2.53.2-2.54.0-dev
Maffooch Dec 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,8 @@ lint:
- changed-files:
- any-glob-to-any-file:
- ruff.toml

gha:
- changed-files:
- any-glob-to-any-file:
- .github/workflows
2 changes: 2 additions & 0 deletions .github/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ categories:
label: 'localization'
- title: '🔧 Improved code quality with linters'
label: 'lint'
- title: '⚙️ Improvemets of GitHub Actions'
label: 'gha'
- title: '🧰 Maintenance'
collapse-after: 3
labels:
Expand Down
17 changes: 11 additions & 6 deletions .github/workflows/test-helm-chart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@ jobs:
with:
python-version: 3.14 # Renovate helper is not needed here

- name: Configure Helm repos
run: |-
helm dependency list ./helm/defectdojo
helm dependency update ./helm/defectdojo
# Running update is not needed for listing - it just triggers errors as soon as one of the subcharts is not in the latest version (`helm dep. update` change content of the chart)
# As soon as we would like to run more extensive tests, this can be reenabled, but this will need to be placed after "ct list-changed" command
# - name: Configure Helm repos
# run: |-
# helm dependency list ./helm/defectdojo
# helm dependency update ./helm/defectdojo

- name: Set up chart-testing
uses: helm/chart-testing-action@6ec842c01de15ebb84c8627d2744a0c2f2755c9f # v2.8.0
with:
version: 3.14.0 # renovate: datasource=github-releases depName=helm/chart-testing
yamale_version: 6.1.0 # renovate: datasource=pypi depName=yamale versioning=semver
yamllint_version: 1.37.1 # renovate: datasource=pypi depName=yamllint versioning=semver

Expand All @@ -52,6 +55,8 @@ jobs:
changed=$(ct list-changed --config ct.yaml --target-branch ${{ env.ct-branch}})
if [[ -n "$changed" ]]; then
echo "changed=true" >> $GITHUB_OUTPUT
echo "Content changed:"
echo "$changed" | sed 's/^/ /'
fi

# run version check only if not dev as in dev we have a `x.y.z-dev` version
Expand Down Expand Up @@ -114,12 +119,12 @@ jobs:
- name: Update values in HELM chart
if: startsWith(github.head_ref, 'renovate/') || startsWith(github.head_ref, 'dependabot/')
run: |
title=${{ github.event.pull_request.title }}
title='${{ github.event.pull_request.title }}'
chars='{}:[],&*#?|-<>=!%@'
for c in $(echo "$chars" | grep -o .); do
title="${title//"$c"/_}"
done
yq -i '.annotations."artifacthub.io/changes" += "- kind: changed\n description: $title\n"' helm/defectdojo/Chart.yaml
yq -i '.annotations."artifacthub.io/changes" += "- kind: changed\n description: '$title'\n"' helm/defectdojo/Chart.yaml
git add helm/defectdojo/Chart.yaml
git commit -m "ci: update Chart annotations from PR #${{ github.event.pull_request.number }}" || echo "No changes to commit"

Expand Down
Binary file added docs/assets/images/asset_hierarchy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/images/asset_hierarchy_node.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/images/assets_loadmore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions docs/content/en/about_defectdojo/pro_features.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ See our [Pro UI Guide](../ui_pro_vs_os) for more information.

![image](images/enabling_deduplication_within_an_engagement_2.png)

### Assets/Organizations

DefectDojo Pro allows for improved organizational visualization for large lists of repositories or other business structures. See [Assets/Organizations documentation](/en/working_with_findings/organizing_engagements_tests/pro_assets_organizations/) for details.

![image](images/asset_hierarchy_diagram.png)

### Finding Priority

DefectDojo Pro can pre-triage your Findings by Priority and Risk, allowing your team to identify and fix your most critical issues first.
Expand Down
49 changes: 49 additions & 0 deletions docs/content/en/changelog/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,57 @@ Here are the release notes for **DefectDojo Pro (Cloud Version)**. These release

For Open Source release notes, please see the [Releases page on GitHub](https://github.com/DefectDojo/django-DefectDojo/releases), or alternatively consult the Open Source [upgrade notes](/en/open_source/upgrading/upgrading_guide/).

## Dec 2025: v2.53

### Dec 8, 2025: v2.53.1

* **(Assets/Organizations)** Introduced overhaul to Products/Product Types, added the ability to create and diagram relationships between Assets. See [Assets/Organizations documentation](/en/working_with_findings/organizing_engagements_tests/pro_assets_organizations/) for details, and information on opting in to the Beta.
* **(Findings)** Added new KEV fields for ransomware, exploits, and date handling.

### Dec 1, 2025: v2.53.0

* **(Pro UI)** Added Asset Hierarchy.
* **(Priority)** Priority and Risk can now be overridden manually, or through Rules Engine.

## Nov 2025: v2.52

### Nov 24, 2025: v2.52.3

* **(Pro UI)** Improved error messaging for failed Imports.
* **(Pro UI)** Added Engagement Tags column to Finding lists


### Nov 17, 2025: v2.52.2

* No significant feature changes.

### Nov 10, 2025: v2.52.1

* **(Pro UI)** Finding view now shows all associated Endpoints, not just Active Endpoints


### Nov 3, 2025: v2.52.0

* **(Pro UI)** In-app Contact Support form now requires a valid email address in your user profile.
* **(Pro UI)** You can now Add Files to Findings through the Pro UI directly from Finding Lists.
* **(Pro UI)** Unicode letters are now allowed in Tags.

## Oct 2025: v2.51

### Oct 27, 2025: v2.51.3

* **(Tools)** Added Nuclei scan support for Smart Upload.
* **(Priority)** Added Prioritization Engine to allow for configurable Priority and Risk calculations for individual Findings under a given Product.
* **(Metrics)** Updated Metrics table to include Products with zero Findings (as a result of filter parameters, or otherwise).
* **(Pro UI)** Added Surveys to Pro UI.



### Oct 20, 2025: v2.51.2

* **(Connectors)** Added Anchore Enterprise Connector.


### Oct 14, 2025: v2.51.1

* **(Pro UI)** Added Finding Quick Report feature. Quick report allows users to quickly render an HTML report with the currently displayed Findings on a Finding table.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ The Azure AD token need to be configured to include Group IDs. Without this step
To update the format of the token, add a [Group Claim](https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/how-to-connect-fed-group-claims) that applies to whatever Group type you are using.
If unsure of what type that is, select `All Groups`. Do not activate `Emit groups as role claims` within the Azure AD "Token configuration" page.

Application API permissions need to be updated with the `Group.Read.All` permission so that groups can be read on behalf of the user that has successfully signed in.
Application API permissions need to be updated with the `GroupMember.Read.All` or `Group.Read.All` permission so that groups can be read on behalf of the user that has successfully signed in. `GroupMember.Read.All` is recommended as this grants the application fewer permissions.

##### Group Cleaning

Expand Down Expand Up @@ -169,7 +169,7 @@ The Azure AD token returned by Azure will also need to be configured to include

If unsure of what type that is, select `All Groups`. Do not activate `Emit groups as role claims` within the Azure AD "Token configuration" page.

Application API permissions need to be updated with the `Group.Read.All` permission so that groups can be read on behalf of the user that has successfully signed in.
Application API permissions need to be updated with the `GroupMember.Read.All` or `Group.Read.All` permission so that groups can be read on behalf of the user that has successfully signed in. `GroupMember.Read.All` is recommended as this grants the application fewer permissions.

To limit the amount of groups imported from Azure AD, a regular expression can be used as the following:

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
title: "⚠️ Assets and Organizations (Pro)"
description: "DefectDojo Pro - Product Hierarchy Overhaul"
---

DefectDojo Pro is extending the Product/Product Type object classes to provide greater flexibility with the data model.

Currently, this feature is in Beta. Pro users who are interested in opting in can do so by emailing [support@defectdojo.com](mailto:support@defectdojo.com).

## Significant Changes

* **Product Types** have been renamed to "Organizations", and **Products** have been renamed to "Assets". Currently, this name change is opt-in for existing DefectDojo Pro subscriptions.
* **Assets** can now have parent/child relationships with one another to further sub-categorize Organizational components.

### Organizations

As with Product Types, **Organizations** should be understood as a top-level category. You can use these to separate your business' core software applications, departments or business functions.

For example, you could create an Organization for many repository groupings: "Core Application", "Infrastructure", "DevOps", "Analytics", "SDK" could all contain multiple code repos.

Keep in mind that for reporting purposes, it’s easier to combine multiple Organizations into a single document than it is to subdivide a single Organization into separate documents. Therefore, we recommend setting up Organizations at as granular a level as makes sense for your team's reports. For example, there is no need to represent a large business division as an Organization if you're primarily going to be reporting on individual departments within that division.

### Assets

Assets are meant to represent subdivisions of your Organizations. However, unlike Products, Assets can be nested, and have parent-child relationships with one another.

## Asset Nesting Examples

### Asset-Level Branch Representation

Development and feature branches can be represented in a variety of ways; separate Engagements or Tests are existing ways that you can represent the difference between your Production, Dev, and other feature branches.

You can also represent these using nested Assets. Consider the following Asset tree:

```
Core Application [Organization]
└── webapp-frontend
├── webapp-frontend/prod
└── webapp-frontend/dev
├── webapp-frontend/dev/feature-a
└── webapp-frontend/dev/feature-b
```

In this environment, each branch (`prod`, `dev`, `feature a`, `feature b`) could have its own Engagements and Tests that are isolated from the other Assets, so that they don't deduplicate against each other. This setup can also ease in navigation, as Asset names can directly correspond to the path on Git.

### Mono-Repo: Separate Components

If you use a single repository for all of your code, but have different teams contributing to directories within that repository, you can set up your Asset nesting to represent that structure.

```
Core Application [Organization]
├── webapp-frontend [Parent Asset]
│ ├── mobile-ios
│ ├── mobile-android
│ └── mobile-sdk
├── webapp-backend [Parent Asset]
│ ├── database
│ └── api
└── infra [Parent Asset]
├── docker
├── kubernetes
└── nginx
```

In this diagram, every element under "Core Application" could be recorded as a separate Asset, with unique business criticality (see: [Priority & Risk](/en/working_with_findings/priority_adjustments/)), RBAC, and corresponding Engagements and Tests. You could continue to test, and store results, on the parent Asset (for example, `webapp-backend`), but you could also run isolated testing on a particular child Asset (for example, `database`).

### Pen Tests: Isolated RBAC

If you want to store pen test results within a single asset, but you don't want testers to be able to look at asset data, you could create child assets for each testing group to upload their results.

```
Core Application [Organization]
└── webapp-frontend [Parent Asset]
├── Pen Test Group A
└── Pen Test Group B
```

Crucially, giving a user RBAC access to a single Child Asset (e.g. `Pen Test Group A`) here does not allow them to see any Findings from other Child Assets (e.g. `Pen Test Group B`), nor does it allow them to see Findings in the Parent Asset (`webapp-frontend`).

The Parent Asset could contain Engagements representing CI/CD results, internal Testing, historical data, or other Finding data which you do not want 3rd parties to be able to discover. Creating a Child Asset for specific Test results allows your internal team to report on those results in combination with the state of the parent Asset.

## Visualizing Assets - Hierarchy

You can visualize the structure of Assets in DefectDojo, and change relationships using the Asset Hierarchy option in the menu.

![image](images/asset_hierarchy.png)

Opening Asset Hierarchy will display a table of all of your Assets which can be filtered. Selecting one or more Assets from this table will render a hierarchy diagram.

![image](images/asset_hierarchy_diagram.png)

### Diagram navigation

The icons at the top left of the hierarchy diagram allow you to zoom in and out. Clicking and dragging in this diagram allows you to scroll through the diagram.

Each Asset is rendered as a single node in this diagram, which can be moved around for display purposes.

Assets are connected together using labelled paths, which represent the kind of relationship each note has to one another. Currently, `parent` is the only label supported.

### Exploring Asset nodes

Each Asset node can be interacted with by clicking on the blue buttons. These buttons appear only when an Asset node is selected (by clicking on the node).

![image](images/asset_hierarchy_node.png)

* 👁️ (eyeball icon) will take you directly to the corresponding Asset View (formerly known as the Product View).
* ✏️ (pencil icon) will open a modal with the Edit Asset form (formerly known as the Edit Product form)
* ➕ (plus icon) will allow you to add a new Child Asset to this Asset. The Asset does not need to be currently visible in the diagram, but must be part of the same Organization.
* ✥ (four-arrows icon) allows you to change the Parent Asset of the currently selected Asset.
* 🗑️ (trash can icon) allows you to remove an Asset's parent relationship. This icon only appears if an Asset already has a Parent.

If your diagram displays an Asset with un-selected Parent Assets, you can click the Load More button to populate the diagram with the Parent Asset (as well as that Parent Asset's children).

![image](images/assets_loadmore.png)

## Notes

* Note that deduplication scopes have not changed; Assets only deduplicate Findings within themselves, and do not consider Findings in other Assets, regardless of Parent/Child relationships.
* RBAC scopes have not changed within this system; each Asset is still considered an individual object for the purposes of assigning permissions. No new RBAC inheritance has been created.
* Giving a user access to an entire Organization will still give that user access to all Assets contained within that Organization (as with Product Types).
* Giving a user access to a single Asset does not give that user access to any related Parent or Child Assets, nor access to the Organization.
* There is no limit to the number of Parent/Child relationships that can be created. Theoretically, you could represent a repository's entire directory structure with separate Assets if you wished.
* Cyclical relationships are not allowed: Parent Assets cannot be Children of their Child Assets.
11 changes: 9 additions & 2 deletions dojo/finding/deduplication.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,14 @@ def set_duplicate(new_finding, existing_finding):
for find in new_finding.original_finding.all():
new_finding.original_finding.remove(find)
set_duplicate(find, existing_finding)
existing_finding.found_by.add(new_finding.test.test_type)
# Only add test type to found_by if it is not already present.
# This is efficient because `found_by` is prefetched for candidates via `build_dedupe_scope_queryset()`.
test_type = getattr(getattr(new_finding, "test", None), "test_type", None)
if test_type is not None and test_type not in existing_finding.found_by.all():
existing_finding.found_by.add(test_type)

# existing_finding.found_by.add(new_finding.test.test_type)

logger.debug("saving new finding: %d", new_finding.id)
super(Finding, new_finding).save()
logger.debug("saving existing finding: %d", existing_finding.id)
Expand Down Expand Up @@ -239,7 +246,7 @@ def build_dedupe_scope_queryset(test):
return (
Finding.objects.filter(scope_q)
.select_related("test", "test__engagement", "test__test_type")
.prefetch_related("endpoints")
.prefetch_related("endpoints", "found_by")
)


Expand Down
9 changes: 6 additions & 3 deletions dojo/finding/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,8 @@ def add_to_finding_group(finding_group, finds):
finding_group.findings.add(*available_findings)

# Now update the JIRA to add the finding to the finding group
if finding_group.has_jira_issue and jira_helper.get_jira_instance(finding_group).finding_jira_sync:
jira_instance = jira_helper.get_jira_instance(finding_group)
if finding_group.has_jira_issue and jira_instance and jira_instance.finding_jira_sync:
logger.debug("pushing to jira from finding.finding_bulk_update_all()")
jira_helper.push_to_jira(finding_group)

Expand All @@ -263,7 +264,8 @@ def remove_from_finding_group(finds):

# Now update the JIRA to remove the finding from the finding group
for group in affected_groups:
if group.has_jira_issue and jira_helper.get_jira_instance(group).finding_jira_sync:
jira_instance = jira_helper.get_jira_instance(group)
if group.has_jira_issue and jira_instance and jira_instance.finding_jira_sync:
logger.debug("pushing to jira from finding.finding_bulk_update_all()")
jira_helper.push_to_jira(group)

Expand Down Expand Up @@ -340,7 +342,8 @@ def group_findings_by(finds, finding_group_by_option):

# Now update the JIRA to add the finding to the finding group
for group in affected_groups:
if group.has_jira_issue and jira_helper.get_jira_instance(group).finding_jira_sync:
jira_instance = jira_helper.get_jira_instance(group)
if group.has_jira_issue and jira_instance and jira_instance.finding_jira_sync:
logger.debug("pushing to jira from finding.finding_bulk_update_all()")
jira_helper.push_to_jira(group)

Expand Down
Loading