Skip to content

Release: Merge release into master from: release/2.58.3#14885

Merged
rossops merged 23 commits into
masterfrom
release/2.58.3
May 18, 2026
Merged

Release: Merge release into master from: release/2.58.3#14885
rossops merged 23 commits into
masterfrom
release/2.58.3

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

Release triggered by rossops

DefectDojo release bot and others added 23 commits May 11, 2026 16:05
….59.0-dev

Release: Merge back 2.58.2 into bugfix from: master-into-bugfix/2.58.2-2.59.0-dev
* docs: add Components page and glossary entry

Adds a new Pro-only Components page under Model Your Assets > Components covering the Component Table, and how to add, update, and remove components. Also adds a Component entry to the glossary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* update with examples, views, Locations info

* actually, not sure about locations v Components

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Paul Osinski <posinski34@gmail.com>
Co-authored-by: Paul Osinski <42211303+paulOsinski@users.noreply.github.com>
* ⚡ speed up migrate_endpoints_to_locations (~14× fewer queries)

Reduces per-endpoint cost in the Endpoint→Location data migration from
~613 queries / 240 ms to ~44 queries / 17 ms on a 50-endpoint /
1,000-finding local benchmark — a 13.9× query reduction and a 14.1×
wall-clock improvement that should bring a 16-hour prod run under one
hour. As a side-effect, fixes the latent associate_with_product
short-circuit bug where 'Mitigated' could stick on a LocationProductReference
even after later Active findings came in for the same product.

Changes (kept inside this management command — no edits to shared
Location model methods):

- select_related/prefetch_related on the main Endpoint queryset so the
  per-endpoint loop has no hidden joins through tags, endpoint_meta,
  status_endpoint, or finding→test→engagement→product/mitigated_by.

- tags.add(*names) splat instead of N round-trips per tag.

- DojoMeta.bulk_create(ignore_conflicts=True) per endpoint instead of
  get_or_create per row (DojoMeta.unique_together = (location, name)
  makes ignore_conflicts semantically equivalent here).

- LocationFindingReference and LocationProductReference are bulk_created
  per endpoint instead of going through Location.associate_with_finding /
  associate_with_product. This bypasses BaseModel.save's full_clean()
  validate_unique queries AND the inherit_tags_on_linked_instance post_save
  signal (which fires all_related_products through the
  finding→test→engagement→product chain on every save). Product status is
  derived in-memory across all of an endpoint's finding statuses.

- _suspend_auto_now_add wraps the LocationFindingReference bulk write so
  the explicit 'created' value (= source Endpoint_Status.date) is honored.
  Django's SQLInsertCompiler.pre_save_val calls Field.pre_save(add=True)
  even from bulk_create; auto_now_add would otherwise overwrite our value
  with now().

- New CLI flags for ops visibility on long runs:
  --batch-size, --progress-every, --benchmark, --query-count.
  Default progress line: 'Migrated X/Y (z%) — N ep/sec — ETA …'.

Per-step measurements (50 ep / 1,000 findings, V3_FEATURE_LOCATIONS=True,
local docker postgres):

  step                    wall    queries/ep   verifier
  baseline (instrumented) 12.00s  613          14 LPR-status warnings (pre-existing bug)
  + prefetch_related      10.63s  528          same
  + tags splat            10.08s  507          same
  + DojoMeta bulk_create  10.24s  498          same
  + bulk LFR/LPR + fix     0.85s   44          all strict checks pass

Idempotent re-runs validated. Verifier checks counts (URLs, Locations,
LFR, LPR, location-DojoMeta), per-row LFR fields (status, created,
audit_time, auditor), endpoint→location tag subset, and DojoMeta
(location, name) parity.

Intentional behavioral diffs vs. the previous code:

1. LocationProductReference.status now reflects 'Active iff any finding
   for this (location, product) is Active' — fixes the
   associate_with_product first-write-wins bug. Previously order-
   dependent; ~28% of product refs were mis-statused on the seeded
   distribution.

2. Tag inheritance via the inherit_tags_on_linked_instance post_save
   signal does NOT fire (bulk_create skips signals). For deployments
   with enable_product_tag_inheritance=True on products (or the system
   setting on), inherited product tags will not be propagated onto
   migrated Locations during this command. The seed used in
   benchmarking does not exercise this path. If your environment uses
   product tag inheritance, follow up with a one-time
   Location.inherit_tags pass after this command — or call out and we
   can bake _bulk_inherit_tags into the migration.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ✨ migrate_endpoints_to_locations: tag inheritance + per-endpoint error isolation

`bulk_create` (introduced in the prior perf commit) skips the
`inherit_tags_on_linked_instance` post_save signal, so deployments
with `enable_product_tag_inheritance` enabled (per-product or
system-wide) would not pick up inherited product tags on migrated
Locations. Track (product, location) pairs during the main loop —
covering both `endpoint.product` and `finding.test.engagement.product`
— and run a post-pass that calls
`LocationManager(product)._bulk_inherit_tags(locations)` once per
contributing product. The helper rediscovers each location's full
product set via LocationProductReference/LocationFindingReference
and diff-checks before writing, so revisits of shared locations
across product groups are idempotent. ~5 queries per product group
vs ~3 per location for a per-location `inherit_tags()` loop.

Also wrap the per-endpoint body in a `try`/`except Exception` so a
single bad row doesn't abort a multi-hour migration. Failures get
logged with full traceback and tracked in `self.failed_endpoints`;
the final "Done." line reports `<successful>/<total>` and a yellow
warning lists the first 10 failing IDs. `KeyboardInterrupt` /
`SystemExit` are not swallowed. The post-pass uses the same pattern
per product group.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.6.3 to 2.7.0.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](urllib3/urllib3@2.6.3...2.7.0)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.7.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* fix: correct URL for 'Model Your Assets' in menu configuration

* ci(docs): expand lychee to catch absURL nav links and in-app help links

Add `--remap` so absolute `docs.defectdojo.com` URLs resolve against the
freshly built site. Previously these were skipped as remote URLs in
offline mode, which masked the broken Model Your Assets menu link fixed
in #14855 — Hugo renders menu items with `absURL`, so a broken nav URL
hides in `https://docs.defectdojo.com/...` form and lychee excludes it.

Add a second lychee invocation that scans every file under `dojo/` that
hardcodes a `docs.defectdojo.com` URL (Django templates, settings) and
checks those against the same built site, so an in-app help link to a
moved or renamed doc page fails CI instead of silently 404ing in the UI.

Update the contributing docs with the local-reproduction commands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: fix five 404 links surfaced by expanded lychee check

The new --remap flag added in the previous commit causes lychee to
resolve absolute docs.defectdojo.com URLs against the built site. Five
in-content links to moved/renamed pages, previously masked because they
were skipped as remote URLs in --offline mode, now fail. Repoint each
to its current canonical path.

- get_started/about/about_defectdojo.md: architecture and running-in-
  production now live under /get_started/open_source/, not
  /open_source/installation/.
- metrics_reports/reports/using_the_report_builder.md: working_with_
  generated_reports uses underscores, not hyphens, and is under
  /metrics_reports/reports/ canonically.
- supported_tools/parsers/file/aws_prowler_v3plus.md and burp_suite_dast.md:
  parser pages live under /supported_tools/parsers/file/, not
  /supported_tools/file/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Paul Osinski <posinski34@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Paul Osinski <42211303+paulOsinski@users.noreply.github.com>
…es to it from dockerfile/github workflow, and git binary once used (#14808)
…product (#14871)

* Anchor location finding reference authorization to the finding's own product

`get_authorized_location_finding_reference` in `dojo/location/queries.py`
was building its membership `OuterRef` paths against
`location__products__product_id` /
`location__products__product__prod_type_id`. Because a `Location` can be
associated with more than one product via `LocationProductReference`,
this allowed a user with access to any product that shared the location
to read references for findings belonging to other products on the same
location.

Switched the four `OuterRef` paths to anchor on the finding's actual
product (`finding__test__engagement__product[_…]`), so each row resolves
authorization against the single product that owns the finding. Renamed
the annotation aliases to `finding__…` to match the new path.

`V3EndpointStatusCompatibleViewSet.get_queryset` uses the same helper
and picks up the change automatically.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Use versioned fixtures in TestLocationFindingReferenceAuthorization

The bug being fixed is in the V3-locations code path, so the test must
run with V3_FEATURE_LOCATIONS=True. In that mode the legacy
`dojo_testdata.json` fixture fails to load because the Endpoint model
is deprecated. `@versioned_fixtures` swaps to
`dojo_testdata_locations.json` automatically so the suite passes in
both V2 and V3 CI variants.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Scope report views to the requesting user's authorized products

`product_endpoint_report` (legacy, non-Location branch) built its
Endpoint queryset by filtering on `finding__active=True` etc. without
restricting to `product=<pid>`, so endpoints (and their findings) from
unrelated products appeared in the rendered report. Added
`product=product` to the Endpoint filter, and extended
`prefetch_related_endpoints_for_report` with an optional `product`
parameter so the prefetched Finding queryset is also scoped.

While auditing the rest of the module, `report_findings` and
`report_endpoints` constructed their initial querysets from
`Finding.objects.filter()` / `Endpoint.objects.filter(...)` with no
authorization. The rendered output was scoped by the filter wrappers'
`qs` property, but moving authorization to the queryset-construction
layer (via `get_authorized_findings` /
`get_authorized_endpoints` / `get_authorized_locations`) matches the
pattern used by `ReportBuilder.get_findings` and removes the implicit
reliance on the filter wrapper.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Skip product endpoint report scoping tests when V3 locations are enabled

The legacy `product_endpoint_report` branch (and its `Endpoint`-based
test fixtures) is unreachable when `V3_FEATURE_LOCATIONS=True`, and the
`Endpoint` model raises NotImplementedError in that mode. Mark the
regression suite with `@skip_unless_v2` so it only runs against the
code path it actually covers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…14866)

* Apply object-level permission check to finding duplicate API actions

`FindingViewSet.reset_finding_duplicate_status` and
`FindingViewSet.set_finding_as_original` were never calling
`self.get_object()`, so DRF never invoked
`UserHasFindingRelatedObjectPermission.has_object_permission`. The
`has_permission` method on that class always returns `True`, so the
per-finding check was effectively skipped. Sibling actions like `close`,
`verify`, and `remove_tags` already call `self.get_object()` at the top.

Adds `self.get_object()` at the top of both action bodies and regression
tests in `unittests/test_rest_framework.py` (`FindingActionAuthzTest`).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Update test_finding_reset_duplicate_reader to expect 403

The existing assertion documented the prior bypass behavior (Reader
reaching the internal helper and getting 400). With the object-level
permission check now running on these actions, a Reader is denied
upfront with 403.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Use versioned fixtures in FindingActionAuthzTest

The sibling `RequestResponsePairsAuthzTest` already uses
`@versioned_fixtures` so the suite picks up `dojo_testdata_locations.json`
when V3_FEATURE_LOCATIONS is enabled. Matching that decorator avoids
the Endpoint-deprecation fixture-load error in the V3 CI variant.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add docs for Products and Assets
@github-actions github-actions Bot added the release-management Automated release-train PR label May 18, 2026
@rossops rossops closed this May 18, 2026
@rossops rossops reopened this May 18, 2026
@rossops rossops merged commit ea61111 into master May 18, 2026
157 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants