Skip to content

docs(security): waive gate-7 on the two endpoints that address no object - #131

Merged
rubenvdlinde merged 2 commits into
developmentfrom
fix/gate-16-spec-coverage
Aug 16, 2026
Merged

docs(security): waive gate-7 on the two endpoints that address no object#131
rubenvdlinde merged 2 commits into
developmentfrom
fix/gate-16-spec-coverage

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

gate-7 reports both as NoAdminRequired with no recognised guard. An IDOR needs an attacker-supplied identifier and neither method accepts one.

  • VisibilityPreviewController::preview — takes a candidate rule set and an evaluation context from the request body, loads nothing by id, persists nothing, evaluates against $this->userId.
  • DashboardShareApiController::searchSharees — takes a search string, reads no dashboard and no share, returns the same directory the core share picker already exposes to any authenticated user.

Both null-check $this->userId. searchSharees also excludes the caller from its own results, blocks single-character sweeps as a directory-enumeration guard, and bounds both searches to 10 rows.

Using the exemption the gate provides rather than widening its guard patterns — gate-7's own comments record that widening "would let gate-7 clear real IDORs", which is a worse trade than two documented waivers.

Verified the waiver is load-bearing: with it, gate-7 reports zero on this repo; displace the docblock and the finding returns immediately.

gate-7 reports both of these as NoAdminRequired with no recognised guard. An
IDOR needs an attacker-supplied identifier, and neither method accepts one:

  VisibilityPreviewController::preview   takes a candidate rule set and an
    evaluation context from the request body, loads nothing by id, persists
    nothing, and evaluates against $this->userId.

  DashboardShareApiController::searchSharees  takes a search string, reads no
    dashboard and no share, and returns the same directory the core share
    picker already exposes to any authenticated user.

Both null-check $this->userId. searchSharees additionally excludes the caller
from its own results, blocks single-character sweeps as a directory
enumeration guard, and bounds both searches to 10 rows.

Using the exemption the gate provides rather than widening its guard patterns:
its own comments record that widening 'would let gate-7 clear real IDORs', and
that is a worse trade than two documented waivers. The reason is required and
stated.

Verified the waiver is load-bearing, not decorative: with it, gate-7 reports
zero on this repo; displace the docblock and the finding comes straight back.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/launchpad @ 96996b7

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
format
composer ✅ 104/104
npm ✅ 525/525
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-16 12:22 UTC

Download the full PDF report from the workflow artifacts.

gate-26 — TemplatesPage.vue was reported as having no visual proof while
tests/e2e/admin-templates-page.spec.ts tests exactly that page. The gate
matches a page against its component stem, the spec only ever wrote
'TemplatesPage' in comments, and the corpus strips comments (a comment is not
a baseline, .github#358). The selector is now a named constant, so the link
between spec and component is executable rather than prose. Verified
load-bearing: rename the constant and the finding returns.

gate-57 — DashboardVersionService::deleteVersionsForDashboard() had no
production caller anywhere. VersionsListener IS registered on
DashboardDeletedEvent and does the same single mapper call directly, so the
cascade has always worked and the service method was dead. Removed.

The interesting part is what the coverage was doing: the dead wrapper had a
unit test, and VersionsListener — the live path — had none. So the tested
path was the one nothing called. VersionsListener now has its own test,
including that an unrelated event deletes nothing (without which the listener
could fire on any event and the happy-path test would still pass) and that a
mapper failure is logged rather than rethrown, which REQ-CSC-006 requires
because a throw would abort the sibling listeners on the same event.

gate-35 — the inert news card's thumbnail now says aria-hidden="true"
alongside alt="". The headline beside it carries the meaning and the card is
inert, so there is no link for the image to name; the attribute states that
explicitly instead of leaving alt="" to imply it. gate-37
(aria-hidden-focusable) re-checked and still clear — an img is not focusable.
@rubenvdlinde
rubenvdlinde merged commit 72644c2 into development Aug 16, 2026
6 of 33 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/launchpad @ 8a30014

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
format
composer ✅ 104/104
npm ✅ 525/525
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-16 13:19 UTC

Download the full PDF report from the workflow artifacts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant