Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ The original Endpoints model was built around URLs and IP addresses — it carri
2. **Performance ceiling.** Per-Finding Endpoint_Status rows and the URL-shaped schema did not scale well at large customer volumes.
3. **Components were second-class.** Software libraries lived only as denormalised fields on a Finding, so a library could not exist independently of a vulnerability — making true SBOM management impossible.

Locations fix all three by introducing a **base `Location` object** with a typed payload, plus dedicated **subtypes** for each asset shape. The MVP ships two subtypes:
Locations fix all three by introducing a **base `Location` object** with a typed payload, plus dedicated **subtypes** for each asset shape:

- **URL Locations** — functional equivalent of the old Endpoints, with the same protocol/host/port/path/query/fragment fields.
- **Dependency Locations** — software libraries identified by [Package URL (pURL)](https://github.com/package-url/purl-spec), used to model SBOM contents.
- **[Source Code Locations](/asset_modelling/locations/pro__source_code_locations/)** — where a static-analysis finding lives in source, identified by file path and line number. Scan-managed, and the substrate for [tracking findings as their code moves](/triage_findings/finding_deduplication/pro__location_drift_matching/).

Future Location types under consideration include cloud provider resource IDs (AWS ARN, Azure Resource ID, GCP Full Resource Name), container images (registry/repository:tag and SHA256 fingerprints), and code repositories.
Future Location types under consideration include cloud provider resource IDs (AWS ARN, Azure Resource ID, GCP Full Resource Name) and container images (registry/repository:tag and SHA256 fingerprints).

## Key Concepts

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
title: "Source Code Locations"
description: "Code locations model where a static-analysis finding lives in source, and record its movement history as code evolves"
weight: 6
audience: pro
---

**Source Code Locations** extend the Locations model to static analysis: alongside URLs (DAST) and Dependencies (SCA), a **Code** location describes where a SAST finding lives in source — identified by its **file path and line number**.

> Source Code Locations require the Locations feature (Beta). To enable Locations on your instance, contact [support@defectdojo.com](mailto:support@defectdojo.com).

## What They Model

Every static finding that reports a file path gets a Code location. The location's canonical value is `path/to/file.py:42` (or just the file path when the tool reports no line). Like all Locations, code locations are shared objects: two findings at the same file and line reference the same location, and the location carries per-finding and per-asset reference statuses.

Code locations are **scan-managed**: they are created and updated by imports and reimports, not by hand. There is no "New Source Code Location" action — the scanner is the source of truth for where code findings live.

## Where to Find Them

- **All Source Code** in the sidebar lists every code location in the instance, with the same filtering and tagging as URLs and Dependencies.
- **View Source Code** in an Asset's Locations menu scopes the list to one asset.
- A finding's page shows its current code location and, when the finding has moved, its **location history**.

## Movement History

Source code moves constantly: commits shift line numbers, refactors rename files. When [Location Drift Matching](/triage_findings/finding_deduplication/pro__location_drift_matching/) is enabled for a tool, a finding that moves keeps its identity, and its code location references record the trail:

- The finding's reference to the **old** location is mitigated and stamped with *where the finding moved* and *why the match was made* (nearest line, dataflow, file rename ...).
- A reference to the **new** location is created and stays active.

The result is a browsable supersession chain — "this finding lived at `auth.py:42`, then `auth.py:57`, then `session.py:31`" — rendered as a timeline on the finding page. The same history mechanism covers URL moves and dependency version bumps, so all three location types share one timeline UI.

History is recorded from the moment Locations is enabled on the instance. Findings that moved before that keep their current location; past hops were applied but not recorded. For instances with years of pre-feature history, the [churn consolidation command](/triage_findings/finding_deduplication/pro__location_drift_matching/#consolidating-historical-churn) can reconstruct trails while merging historical close-and-recreate chains.

## Status Correctness

Code location reference statuses are kept truthful by reimport on **every** matching algorithm, whether or not drift matching is enabled:

- A matched finding's current code reference is synced on each reimport, so a finding that moved does not leave its old reference active forever.
- The same toggle-independent sync applies to dependency references: when an SCA finding's package version bumps, the old version's reference is mitigated rather than remaining active alongside the new one.

## Relationship to Finding Fields

The finding's own `file_path` / `line` fields remain the authoritative scalars (they are what filters, hashes, and the API expose); the Code location is the shared, reference-counted view of that same coordinate. Reimport refreshes the scalars from the latest scan and the location machinery derives locations from them — the two can not drift apart.
2 changes: 2 additions & 0 deletions docs/content/import_data/import_intro/reimport.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ Reimport decides whether an incoming item matches an existing Finding using **[R

If you are seeing Reimport close old Findings and create new Findings when only a minor attribute changes (for example, a line number shift), tune **Reimport Deduplication** for that tool to use stable identifiers that ignore those attributes (such as Unique ID From Tool).

**DefectDojo Pro** can solve this directly for tools without reliable unique IDs: enabling **[Location Drift Matching](/triage_findings/finding_deduplication/pro__location_drift_matching/)** makes Reimport recognize a Finding whose location moved — a line shift, file rename, URL move, or dependency version bump — as the *same* Finding, updating it in place and preserving its location history.

## Reimport via API - special note

Note that the /reimport API endpoint can both **extend an existing Test** (apply the method in this article) **or create a new Test** with new data \- an initial call to `/import`, or setting up a Test in advance is not required.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ DefectDojo Pro offers the following deduplication methods for same-tool deduplic
#### Hash Code
Uses a combination of selected fields to generate a unique hash. When selected, a third dropdown will appear showing the fields being used to calculate the hash.

##### Content Fingerprint

**Content Fingerprint** is a selectable hash field (available in all three configuration areas) that provides a *location-invariant* identity for static-analysis findings. It is derived from the vulnerable code snippet a tool includes in the finding — normalized so that indentation, line-number annotations, and formatting differences do not change it. Two findings about the same vulnerable code hash identically even when the code moved to a different line or file.

Content Fingerprint is computed for tools that include a code snippet in the finding description — including **Bandit**, **Gosec**, **Brakeman**, **Checkmarx One**, and any tool whose description carries a fenced code block or SARIF snippet.

> **Before selecting Content Fingerprint as a hash field**, populate fingerprints for existing findings by running `./manage.py backfill_fingerprints`. Findings imported after the feature is present get fingerprints automatically, but pre-existing findings have none — selecting the field without backfilling makes existing and incoming findings hash differently, splitting every match until the backfill runs.

Content Fingerprint pairs well with **CWE** for tools that embed file paths or line numbers inside their titles, where other identity fields change every time the code moves. See [Location Drift Matching](/triage_findings/finding_deduplication/pro__location_drift_matching/#choosing-hash-fields-for-tracked-tools).

#### Unique ID From Tool
Leverages the security tool's own internal identifier for findings, ensuring perfect deduplication when the scanner provides reliable unique IDs.

Expand Down Expand Up @@ -113,6 +123,14 @@ The following algorithm options are available for Reimport Deduplication:

Reimport can completely discard Findings before they are recorded, so Reimport Deduplication settings should be adjusted with caution.

### Track Findings as Locations Change

When a tool's Reimport Deduplication algorithm is **Hash Code**, an additional toggle appears: **Track findings as locations change**. With it enabled, a finding whose location moved between reimports — a line shift or file rename, a URL move, or a dependency version bump — is treated as the *same* finding, even if the tool re-scored its severity. One finding is maintained in place and its location history is preserved, instead of the old finding closing and an identical new one being created.

The toggle is off by default and applies only to the Hash Code reimport algorithm (tools with a reliable Unique ID From Tool already track movement through their stable IDs). Enabling it automatically re-hashes the tool's existing findings in the background so historical data participates immediately.

See [Location Drift Matching](/triage_findings/finding_deduplication/pro__location_drift_matching/) for how the matching works, what is preserved, and guidance for enabling it on large instances.

## Running Deduplication Retroactively on Existing Data

A common situation when first turning on Deduplication Tuning is having a large backlog of Findings that were imported *before* the dedup configuration changed. In DefectDojo Pro, you do not need to run a separate command to dedupe this historical data — **changing the Deduplication Settings for a tool automatically triggers a background re-hash of all existing Findings associated with that test type**.
Expand All @@ -137,6 +155,8 @@ For optimal results with Deduplication Tuning:
- **Use Hash Code for cross-tool deduplication**: When enabling cross-tool deduplication, select fields that reliably identify the same finding across different tools (such as vulnerability name, location, and severity). **IMPORTANT** Each tool enabled for cross-tool deduplication **MUST** have the same fields selected.
- **Keep cross-tool sources in the same Asset**: Cross-Tool Deduplication is Asset-scoped. Findings split across separate Assets will not dedupe even with matching hash fields. See [Cross-Tool Deduplication is Scoped to a Single Asset](#cross-tool-deduplication-is-scoped-to-a-single-asset) above.
- **Avoid overly broad deduplication**: Cross-tool deduplication with too few hash fields may result in false duplicates
- **Backfill before selecting Content Fingerprint**: run `./manage.py backfill_fingerprints` first, then select the field — the triggered re-hash then has fingerprints to work with. See [Content Fingerprint](#content-fingerprint) above.
- **Enable location tracking between scan runs**: the toggle's automatic re-hash covers the tool's whole backlog; on large instances let it finish before the next scheduled reimport. See [Location Drift Matching](/triage_findings/finding_deduplication/pro__location_drift_matching/#enabling-on-existing-data-upgrades).

By tuning deduplication settings to your specific tools, you can significantly reduce duplicate noise.

Expand Down
Loading
Loading