docs(security): waive gate-7 on the two endpoints that address no object - #131
Merged
Conversation
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.
rubenvdlinde
requested review from
WilcoLouwerse,
bbrands02 and
rjzondervan
as code owners
August 16, 2026 12:03
Contributor
Quality Report — ConductionNL/launchpad @
|
| 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.
Contributor
Quality Report — ConductionNL/launchpad @
|
| 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
gate-7 reports both as
NoAdminRequiredwith 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.searchShareesalso 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.