[Security] Remove anonymous access to Trails mutating endpoints (DELETE /{id}, DELETE /purge) #416

Closed
opened 2026-07-05 20:24:43 +00:00 by spikerj · 2 comments
Owner

Context: Found during spec verification. A concrete instance of the anonymous-surface EPIC.

Problem: The entire TrailsController is class-level [AllowAnonymous] with no per-action overrides — including the destructive DELETE /api/Trails/{id} and the bulk DELETE /api/Trails/purge?region={r} (soft-delete by region). Anonymous callers can delete shared data.

Evidence:

  • SpikerSoft.Api/Domain/Trails/TrailsController.cs:29 ([AllowAnonymous] on the class)
  • :248 (DELETE {id}), :294 (DELETE purge)

Fix: Split the surface — keep the read/geo endpoints anonymous (explore), require [Authorize] (+ role) on create/update/delete/purge. Apply the EPIC's transport pattern.

Acceptance criteria: Anonymous callers can read/query trails; every mutating endpoint requires auth; DELETE /purge is restricted to admin/staff.

Effort: S · Child of the anonymous-surface EPIC (this batch).

**Context:** Found during spec verification. A concrete instance of the anonymous-surface EPIC. **Problem:** The entire `TrailsController` is class-level `[AllowAnonymous]` with no per-action overrides — including the destructive `DELETE /api/Trails/{id}` and the bulk `DELETE /api/Trails/purge?region={r}` (soft-delete by region). Anonymous callers can delete shared data. **Evidence:** - `SpikerSoft.Api/Domain/Trails/TrailsController.cs:29` (`[AllowAnonymous]` on the class) - `:248` (`DELETE {id}`), `:294` (`DELETE purge`) **Fix:** Split the surface — keep the read/geo endpoints anonymous (explore), require `[Authorize]` (+ role) on create/update/delete/purge. Apply the EPIC's transport pattern. **Acceptance criteria:** Anonymous callers can read/query trails; every mutating endpoint requires auth; `DELETE /purge` is restricted to admin/staff. **Effort:** S · Child of the anonymous-surface EPIC (this batch).
spikerj added the agentic label 2026-07-05 20:24:43 +00:00
Author
Owner

Child of the anonymous-vs-authenticated surface epic #417.

Child of the anonymous-vs-authenticated surface epic #417.
Author
Owner

Resolved in spikersoft-backend PR #110 (merged to master). Removed the class-level [AllowAnonymous] on TrailsController; [Authorize] on the destructive DELETE /{id} + DELETE /purge, explicit [AllowAnonymous] on the six public read GETs, POST/PUT left anonymous-by-omission so #415's FallbackPolicy sweeps them. Guarded by TrailsControllerAuthorizationTests (9/9). Closing.

Resolved in spikersoft-backend PR #110 (merged to `master`). Removed the class-level `[AllowAnonymous]` on `TrailsController`; `[Authorize]` on the destructive `DELETE /{id}` + `DELETE /purge`, explicit `[AllowAnonymous]` on the six public read GETs, POST/PUT left anonymous-by-omission so #415's FallbackPolicy sweeps them. Guarded by `TrailsControllerAuthorizationTests` (9/9). Closing.
Sign in to join this conversation.