Skip to content

feat(finding): copy finding fix + autodetected vulnerability id type + uniqueness constraint#15145

Merged
Maffooch merged 4 commits into
DefectDojo:devfrom
valentijnscholten:feat/vulnerability-id-type
Jul 14, 2026
Merged

feat(finding): copy finding fix + autodetected vulnerability id type + uniqueness constraint#15145
Maffooch merged 4 commits into
DefectDojo:devfrom
valentijnscholten:feat/vulnerability-id-type

Conversation

@valentijnscholten

@valentijnscholten valentijnscholten commented Jul 2, 2026

Copy link
Copy Markdown
Member

🔗 PR stack — CWE / vulnerability-ID consolidation (OSS)

Merge bottom-up:

  • #15145 — autodetected vulnerability-ID type + uniqueness constraint
    • #15143 — multiple CWEs per finding
      • #15154 — docs: Pro set-based dedup hash-code fields
      • #15155 — pluggable false-positive-history candidate filter

👉 This PR: #15145


Description

Adds an autodetected type to each vulnerability identifier, and a uniqueness constraint on (finding, vulnerability_id).

  • Vulnerability_Id gains a vulnerability_id_type field, autodetected from the identifier's leading prefix — the part before the first -: CVE-2024-1234CVE, GHSA-…GHSA, RUSTSEC-2021-0001RUSTSEC, ALINUX2-SA-…ALINUX2. It is derived structurally (no registry) and is NULL when there is no non-numeric prefix (bare numbers / UUIDs / no dash). The column is indexed so identifiers can be filtered and grouped by type efficiently.
  • The type is populated automatically: on import (the bulk-create paths set it at construction) and on save()/get_or_create (via a save() override). Existing rows are backfilled by the migration.
  • A unique constraint is added on (finding, vulnerability_id). Pre-existing duplicate rows (unintended) are consolidated first (keeping the earliest) so the constraint can be created.

vulnerability_id_type is a denormalized, derived attribute — it does not participate in hash_code, so existing hash codes and deduplication are unaffected by this change.

Stacked PRs — this is the base of the stack. The multiple-CWEs-per-finding change is stacked on top of this PR in #15143. Merge this PR first; #15143 builds on it (and its migrations 0279/0280 chain after the 02760278 migrations here).

Migrations

  • 0276_vulnerability_id_type — adds the indexed vulnerability_id_type column and a leading index on vulnerability_id.
  • 0277_backfill_vulnerability_id_type — backfills vulnerability_id_type for existing rows and removes duplicate (finding, vulnerability_id) rows (keeping the earliest).
  • 0278_unique_finding_vulnerability_id — adds the unique constraint on (finding, vulnerability_id).

Test results

  • New unittests/test_vulnerability_id_type.py covers prefix autodetection, that save() and the bulk import path populate the type, and that the uniqueness constraint is enforced.

Documentation

  • Added docs/content/releases/os_upgrading/3.2.md.

Checklist

  • Rebased against the latest dev.
  • Submitted against dev.
  • Model changes include the necessary migrations in dojo/db_migrations.
  • Added tests to the unit tests.

@valentijnscholten

Copy link
Copy Markdown
Member Author

Sibling PR (independent split): #15143 — multiple CWEs per finding.

@github-actions github-actions Bot added New Migration Adding a new migration file. Take care when merging. docs unittests labels Jul 2, 2026
@valentijnscholten valentijnscholten changed the title feat(finding): autodetected vulnerability id type + uniqueness constraint feat(finding): copy finding fix + autodetected vulnerability id type + uniqueness constraint Jul 2, 2026
@valentijnscholten valentijnscholten added this to the 3.2.0 milestone Jul 2, 2026
@valentijnscholten
valentijnscholten marked this pull request as ready for review July 2, 2026 18:21
@valentijnscholten
valentijnscholten force-pushed the feat/vulnerability-id-type branch from 5506d52 to c356327 Compare July 2, 2026 20:37

@mtesauro mtesauro left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved

valentijnscholten and others added 3 commits July 13, 2026 18:28
…aint

Adds Vulnerability_Id.vulnerability_id_type, autodetected from the id's
leading prefix (CVE-2024-1234 -> CVE, GHSA-... -> GHSA), stored and indexed
so identifiers can be filtered/grouped by type. Populated on import (bulk)
and on save(); existing rows backfilled by migration.

Also de-duplicates (finding, vulnerability_id) rows and adds a unique
constraint on the pair. CWE is a weakness class and is intentionally NOT
part of this change; vulnerability_id_type does not participate in
hash_code, so existing hash codes and deduplication are unaffected.

Migrations: 0276 (type column + lookup index), 0277 (dedupe + backfill,
data), 0278 (unique constraint).
…(20)

resolve_vulnerability_id_type returned the raw uppercased prefix with no
length bound, but vulnerability_id_type is CharField(max_length=20) while
vulnerability_id is unbounded text. A >20-char prefix (e.g. a dash-less
token/hash used as an id) raised DataError on save()/bulk_create (import
500) and was silently truncated by the 0277 backfill's bulk_update CAST.
Treat an over-length prefix as untyped (None) so save, bulk_create, and
the backfill all agree and never error or truncate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Resolves the migration-graph leaf collision: dev has advanced to
0279_jira_project_transition_fields, so the vulnerability-id migrations are
renumbered 0276/0277/0278 -> 0280/0281/0282 and the first is re-parented onto
the current dev leaf.

Also merges a duplicate `class Meta` on Vulnerability_Id introduced by the
rebase: dev's global-search FTS work added its own Meta (GIN indexes) adjacent
to this branch's Meta (unique constraint + dojo_vuln_id_lookup_idx). Python
keeps only the last class body, which silently dropped the constraint/index
from the model state (makemigrations wanted to remove them). Both are now in a
single Meta. `makemigrations --check dojo` reports no changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Maffooch
Maffooch force-pushed the feat/vulnerability-id-type branch from e6bc4a5 to 7bd952b Compare July 14, 2026 00:35
…y (F9)

0280's lookup index and 0282's (finding, vulnerability_id) unique constraint
were built with plain AddIndex / AddConstraint, taking a SHARE lock (blocks
writes) and an ACCESS EXCLUSIVE lock (blocks reads+writes) for the full build
over the whole dojo_vulnerability_id table -- a material downtime window on
large instances.

Build both CONCURRENTLY instead (atomic=False), keeping the work in-migration:
- 0280: AddIndexConcurrently for dojo_vuln_id_lookup_idx.
- 0282: CREATE UNIQUE INDEX CONCURRENTLY, then ADD CONSTRAINT ... USING INDEX
  (brief lock to adopt the pre-built index); SeparateDatabaseAndState keeps the
  UniqueConstraint in Django's model state.

Verified on a 100k-finding / 174k-id dataset with duplicate rows: 0281 dedupe
-> 0, constraint built valid as a real UNIQUE constraint, makemigrations
--check clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Maffooch
Maffooch merged commit 0f2a5af into DefectDojo:dev Jul 14, 2026
148 of 149 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs New Migration Adding a new migration file. Take care when merging. unittests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants