Upgrading to DefectDojo Version 3.2.x
On this page
- Vulnerability id type
- Multiple CWEs per finding
- Database migration
- Deduplication registration repairs (changes
hash_codefor four scan types) - AWS Security Hub parser: deterministic resource IDs
- Yarn Audit parser: deterministic tree versions and dependents
- Deprecation: API-based (pull) parsers
- Deprecation: Tool Type and Tool Configuration
- Deprecation:
manage.py dbbackup - Deprecation timeline
Vulnerability id type
Each Vulnerability_Id gains an autodetected vulnerability_id_type — the identifier’s leading
prefix (CVE-2024-1234 → CVE, GHSA-… → GHSA, RUSTSEC-… → RUSTSEC). It is derived
structurally (no registry) and stored (indexed) so identifiers can be filtered and grouped by type
efficiently. It is NULL when there is no non-numeric prefix. It is populated automatically on
import and on save(); existing rows are backfilled by migration. It does not participate in
hash_code, so existing hash codes and deduplication are unaffected.
A unique constraint is also added on (finding, vulnerability_id); pre-existing duplicate rows
(unintended) are consolidated first.
Multiple CWEs per finding
A finding could previously store only one CWE (the integer cwe field). This release adds a
dedicated Finding_CWE relationship so a finding can carry multiple CWEs, using the same
approach as vulnerability ids: the primary CWE stays on Finding.cwe (unchanged — legacy
deduplication and hash codes still use it), and additional CWEs live in the relationship.
CWE is modeled separately from vulnerability identifiers on purpose: a CWE is a weakness class,
not a vulnerability instance identifier, so it must not participate in hash_code,
vulnerability-id deduplication, or the cve field. Because of this separation, existing hash
codes and deduplication are unaffected.
CWEs are populated automatically on import and when a finding is created or edited (from the
finding’s CWE field, plus any additional CWEs a parser supplies). The finding exposes them via
finding.cwes (primary first, deduplicated).
Database migration
Five migrations run automatically on upgrade:
0281_vulnerability_id_type— adds the indexedvulnerability_id_typecolumn and a leading index onvulnerability_id.0282_backfill_vulnerability_id_type— backfillsvulnerability_id_typeand removes duplicate(finding, vulnerability_id)rows (keeping the earliest).0283_unique_finding_vulnerability_id— adds the unique constraint on(finding, vulnerability_id).0284_finding_cwe— creates theFinding_CWEtable (unique per(finding, cwe)).0285_backfill_finding_cwe— seedsFinding_CWErows for all existing findings from their legacyFinding.cwevalues.
What you need to do
Nothing — the migrations are applied automatically, 0285_backfill_finding_cwe backfills every
existing finding, and new/edited findings populate their CWE relationship on save and import.
The manage.py migrate_cwe management command is optional and is not required on upgrade
(it would repeat the work 0285 already did). It exists only as an idempotent re-scan you can run
later — for example after a parser upgrade changes how a scan’s CWEs are derived — to reconcile
Finding_CWE rows from the current Finding.cwe values.
Deduplication registration repairs (changes hash_code for four scan types)
Unlike the two changes above, this one does change stored hash codes. Four scan types had a deduplication registration that was split across the two settings that have to agree, so the configured behaviour never took effect.
Burp Suite DAST Scan
Burp Suite DAST Scan is the renamed Burp Enterprise Scan — the same parser
(dojo/tools/burp_suite_dast) still answers to both names. DEDUPLICATION_ALGORITHM_PER_PARSER
was updated to the new name, but in HASHCODE_FIELDS_PER_SCANNER the new entry was keyed
"Burp Suite DAST" (no trailing Scan) — a name no parser produces. Because
HASHCODE_FIELDS_PER_SCANNER is looked up by test type name, that list never matched anything, and
Burp Suite DAST Scan fell through to the legacy hash
(title + cwe + line + file_path + description).
The result was that the same tool had two different identities depending on which of its two scan
type names you imported under: Burp Enterprise Scan hashed on title + severity + cwe as
intended, and Burp Suite DAST Scan did not.
The key is now "Burp Suite DAST Scan", so both names hash identically.
Existing Burp Suite DAST Scan findings will not match a new import until they are rehashed.
Reimporting before rehashing closes the existing findings as absent and creates duplicates.
Snyk Code Scan, Cycognito Scan, n0s1 Scanner
These three carried a curated HASHCODE_FIELDS_PER_SCANNER list but had no
DEDUPLICATION_ALGORITHM_PER_PARSER entry, so they deduplicated with the legacy algorithm, which
does not consult hash_code at all. Their stored hash_code was already computed from the
configured fields — compute_hash_code() reads the field list regardless of the algorithm — so
their hash codes do not change. Only which findings match changes, and they now match on the
fields their registration always specified.
What you need to do
If you import Burp Suite DAST Scan, recompute its hash codes before your next reimport:
./manage.py dedupe --parser "Burp Suite DAST Scan" --hash_code_onlyThen, to re-link findings under the new identity:
./manage.py dedupe --parser "Burp Suite DAST Scan" --dedupe_onlyNothing is required for Snyk Code Scan, Cycognito Scan, or n0s1 Scanner, and nothing is
required for any other scan type.
AWS Security Hub parser: deterministic resource IDs
The AWS Security Hub parser lists the resources a finding applies to in the finding description, under a Resource IDs: heading. It built that list by joining an unordered Python set. Python randomizes string hashing per process, so the resource ARNs came out in a different order in every import — and for a finding that reports more than one resource, that made the description itself different each time.
The description matters here because “AWS Security Hub Scan” declares no entry in HASHCODE_FIELDS_PER_SCANNER, so its findings fall back to the legacy hash, which is computed over title, CWE, line, file path and description. Re-importing the same unchanged report therefore stored a different hash_code every time.
The parser now sorts the resource ARNs before joining them, so the description — and the hash_code derived from it — are stable across re-imports. The Test description (AWS Accounts and Finding Origins) was built the same way and is now sorted too; it is not hashed, but it reshuffled in the UI on every import.
What you need to do
Nothing is required, but note that this is an identity change for AWS Security Hub Scan.
It affects only findings that carry two or more resources. A finding with zero or one resource has just one possible ordering, so its hash_code is unchanged by this release.
For the multi-resource findings there is no stable prior identity to preserve: the old value was effectively random per import, so no existing hash_code can be matched reliably. Every hash this changes was already changing on its own.
Deduplication for this scan type keys on unique_id_from_tool (the Security Hub finding ARN) rather than on hash_code, so import and re-import matching itself was never affected. The exposure is the features that read hash_code: false positive history, risk acceptance copies, and similar findings.
Yarn Audit parser: deterministic tree versions and dependents
The Yarn Audit parser (Yarn 2 output) joined unordered sets into the finding description and into component_version, so the listed dependents and tree versions reshuffled between imports. Both are now sorted.
This is not an identity change: “Yarn Audit Scan” declares its own hash fields (title, severity, file path, vulnerability IDs, CWE), and neither the description nor component_version is among them, so no hash_code changes. The only difference is that the values stop flapping in the UI.
Deprecation: API-based (pull) parsers
The following API-based (pull) parsers — which fetch findings directly from a vendor API using a Tool Configuration and a Product API Scan Configuration, rather than parsing an uploaded report file — are being deprecated and will be removed in DefectDojo 3.5.0 (November 2026). These pull integrations are being consolidated into DefectDojo Pro’s no-code connectors.
- BlackDuck API
- Bugcrowd API Import
- Cobalt.io API Import
- Edgescan Scan
- SonarQube API Import
- Vulners
What you need to do
If you use any of these parsers to pull findings directly from a vendor API, plan to migrate to a DefectDojo Pro connector before 3.5.0. After 3.5.0, these parsers and their API-pull import path are removed, and imports that rely on a Tool Configuration will no longer function.
Deprecation: Tool Type and Tool Configuration
The Tool Type and Tool Configuration features exist to configure the API-based pull parsers listed above. They are being deprecated and will be removed in DefectDojo 3.5.0 (November 2026), at the same time as the parsers they serve, so that no configuration tables remain that do nothing. (CI/CD engagement data entry no longer depends on Tool Configuration as of the CI/CD infrastructure split in this release.)
The following UI pages and API endpoints are affected:
- UI: Tool Type, Tool Configuration, and per-product API Scan Configuration pages
- API:
/api/v2/tool_types/,/api/v2/tool_configurations/,/api/v2/product_api_scan_configurations/
What you need to do
If you manage Tool Types or Tool Configurations via the UI or API, migrate the corresponding
integrations to DefectDojo Pro connectors before 3.5.0. From 3.2.0 onward these pages display a
deprecation warning and the API endpoints return an X-Deprecated response header.
Deprecation: manage.py dbbackup
The bundled django-dbbackup integration (the
manage.py dbbackup / dbrestore commands) is being deprecated and will be removed in
DefectDojo 3.5.0 (November 2026). It is minimally integrated, and its pg_dump-based backup
fails when the PostgreSQL client and server versions differ (see
#15301).
What you need to do
For database backups, use your database’s native tooling — for example pg_dump/pg_restore
matched to your PostgreSQL server version, or your managed database provider’s backup features.
Deprecation timeline
- 3.2.x onwards: the features above are deprecated. UI pages display a warning banner and
affected API endpoints return an
X-Deprecatedheader. In DefectDojo Pro, the sidebar entries for Tool Types and Tool Configurations also carry a redDEPRECATEDbadge naming the removal release and linking back to this page — see Menu Badges. - 3.5.0 (November 2026): the API-based pull parsers, Tool Type / Tool Configuration, and the
django-dbbackupintegration are removed.
For more information, check the Release Notes.