Skip to content

Scope public API endpoints to caller visibility (GHSA-6ghm-wf22-pvx5)#367

Draft
jbrooksuk wants to merge 1 commit into
mainfrom
security/api-visibility-scoping
Draft

Scope public API endpoints to caller visibility (GHSA-6ghm-wf22-pvx5)#367
jbrooksuk wants to merge 1 commit into
mainfrom
security/api-visibility-scoping

Conversation

@jbrooksuk

Copy link
Copy Markdown
Member

Summary

The public JSON API index/show endpoints never applied the HasVisibility scopes that the web status page and RSS feed use. Any unauthenticated caller could list and read incidents, metrics and component groups marked authenticated-only or hidden. Fixes GHSA-6ghm-wf22-pvx5 (CWE-862, CVSS 7.5).

What changed

  • Incident / Metric / ComponentGroup index + show: apply ->visible(auth()->check()); show now returns 404 for out-of-scope records instead of leaking them.
  • Component index + show: components have no visibility column — they inherit it from their group. Scoped by group visibility (whereNull('component_group_id') OR group is visible), so ungrouped components stay public, matching the status page. Also hides disabled components by default with an opt-in filter[enabled]=false; show 404s disabled components.
  • Nested controllers (IncidentUpdate, MetricPoint): gated on the parent's visibility so children of hidden/auth-only parents 404.
  • ComponentGroupFactory: fixed a latent bug where visible was set from ComponentGroupVisibilityEnum::expanded (value 0), which under the ResourceVisibilityEnum cast means authenticated. Default is now guest.
  • Tests: added API visibility regression coverage (none existed) across every affected endpoint — guest sees only guest; authenticated sees authenticated+guest; hidden never; ungrouped components stay public; disabled hidden-by-default but reachable via filter; nested children respect parent visibility.

Not affected

Schedule / ScheduleUpdateController have no visibility concept and are unchanged. The advisory's inclusion of components/schedules in the "identical pattern" list is partially inaccurate: Schedule has no visible column, and Component's leak is via its group rather than a column of its own.

Verification

  • Full suite green (476 tests), PHPStan clean, Pint clean.

Warning

Draft: this is a public PR for an unpatched advisory, so the diff discloses the vulnerability. Coordinate with the release/advisory before marking ready.

The public JSON API `index`/`show` endpoints never applied the
`HasVisibility` scopes that the web UI and RSS feed use, so anonymous
callers could read incidents, metrics and component groups marked
`authenticated`-only or `hidden`.

- Scope Incident, Metric and ComponentGroup index/show to the caller's
  visibility, returning 404 for out-of-scope records on show.
- Scope Component index/show by the visibility of its group (components
  inherit visibility from their group; ungrouped stay public, matching
  the status page). Hide disabled components by default with an opt-in
  `enabled` filter; show 404s disabled components.
- Gate the nested IncidentUpdate and MetricPoint controllers on their
  parent's visibility.
- Fix ComponentGroupFactory using the wrong enum for `visible`, which
  defaulted groups to `authenticated` instead of `guest`.
- Add API visibility regression tests across all affected endpoints.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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