Upgrading to DefectDojo Version 3.1.x | DefectDojo Documentation
Upgrading to DefectDojo Version 3.1.x
Blank Finding components normalized to NULL
Previously a Finding could store an empty string ("") for component_name or component_version depending on how it was created or edited. The database treats an empty string as distinct from NULL, so the All Components view (which groups findings by component) could show two separate “None” rows — one for findings with a NULL component and one for findings with an empty-string component.
Findings without a component now consistently store NULL. Blank values are normalized to NULL when a Finding is saved, and a data migration converts existing empty-string component values to NULL on upgrade.
What you need to do
Nothing — the change is applied automatically by the database migration included in this release. After upgrading, component-less findings will group together under a single “None” entry.
Multiple JIRA components per project
The Component field on a JIRA project configuration now supports assigning more than one Jira component. Separate multiple component names with a comma (for example, Security,DevSecOps), and each name is sent to Jira as a distinct component. A single value without commas continues to behave as before.
What you need to do
Nothing is required. Note that a component name that legitimately contains a comma will be split into separate components — component names rarely contain commas, so this is an accepted limitation.
Tool Configuration credentials upgraded to AES-256-GCM
DefectDojo encrypts the credentials stored on Tool Configurations (the password, ssh, and api_key fields). Previously these values were encrypted with AES-256 in OFB mode (the AES.1 stored format). This release introduces a modern AES.2 format that uses AES-256-GCM, an authenticated encryption scheme that detects tampering with the stored ciphertext.
New and updated credentials are written in the AES.2 format automatically. The encryption key is unchanged — both formats derive their key from the same DD_CREDENTIAL_AES_256_KEY, so no key rotation or settings change is required.
A data migration (0272_reencrypt_tool_config_credentials_aes_gcm) included in this release eagerly re-encrypts every existing AES.1 credential to AES.2 on upgrade. The legacy AES.1 decryption path is retained for backward compatibility, so any value that has not yet been migrated continues to decrypt normally. The same migration also widens the password, ssh, and api_key columns by 50% so that credentials stored at the old maximum length still fit once the GCM nonce and authentication tag are added.
This release also bumps cryptography to 49.0.0 and pyopenssl to 26.3.0.
What you need to do
Nothing — the change is applied automatically by the database migration included in this release. Ensure your DD_CREDENTIAL_AES_256_KEY is unchanged from your prior deployment so the existing credentials can be decrypted and re-encrypted; a value that fails to decrypt (for example, because it was encrypted under a different key) is left untouched rather than overwritten.
JFrog Xray API Summary Artifact parser: deterministic impact paths
The JFrog Xray API Summary Artifact parser derives a finding’s file_path, description, and unique_id_from_tool (its deduplication key) from the first entry in the vulnerability’s impact_path list. JFrog returns that list in an arbitrary order, so the same vulnerability could produce a different first entry from one scan to the next. When the order changed, the deduplication key changed too, and a single CVE would be re-imported as multiple separate findings across successive scans.
The parser now sorts the impact paths before selecting the first one, so file_path, the description, and the deduplication key stay stable across re-imports. When a vulnerability has more than one impact path, the full sorted list is now appended to the finding description under an Impact paths: heading so no path information is lost.
What you need to do
Nothing is required for new imports. Findings imported before this release may have been created with a non-deterministic first impact path; re-importing an affected report will now deduplicate consistently, and you may want to clean up any duplicate findings that a previous import created.
New setting: DD_OS_MESSAGE_ENABLED
This release adds the DD_OS_MESSAGE_ENABLED setting (default True), which controls the open-source promotional (“Upgrade to Pro”) banner. The default preserves the existing behavior. Set DD_OS_MESSAGE_ENABLED=False to hide the banner; when disabled, DefectDojo skips the outbound request that fetches the message.
Deduplication execution mode for import/reimport
This release adds a new deduplication_execution_mode setting that controls how import/reimport deduplication post-processing is dispatched and whether the API response waits for it. It can be set per user (profile) and overridden per request on the import and reimport endpoints.
Modes:
async(default): deduplication and the rest of post-processing are dispatched to the background and the response returns immediately. This is the historical behavior; nothing changes for existing users.async_wait: post-processing is still dispatched to the background, but the request waits for deduplication to finish before responding. As a result thescan_addednotification and the statistics in the import/reimport response reflect the deduplicated state (findings that turned out to be duplicates are no longer counted/listed as new). JIRA push, product grading and other non-deduplication tasks remain asynchronous and are not awaited.sync: import deduplication runs inline in the web request.
The wait in async_wait is bounded by the new DD_DEDUPLICATION_ASYNC_WAIT_TIMEOUT environment variable (default 60 seconds). If no worker picks up the work within the timeout, the request responds anyway (degrading to the async outcome) rather than hanging.
The import/reimport response now also includes a deduplication_complete boolean indicating whether deduplication had finished by the time the response was produced.
Relationship to block_execution
The existing block_execution profile flag is unchanged. It remains the global switch that forces all of a user’s asynchronous tasks (notifications, JIRA push, product grading, deduplication, …) to run in the foreground. deduplication_execution_mode is independent and narrower — it only affects import/reimport deduplication post-processing. A user who has block_execution enabled continues to get fully synchronous imports; the upgrade migration seeds their deduplication_execution_mode to sync so behavior is unchanged.