Remove ?token= deletion-token path (#143) #153

Merged
fen merged 2 commits from fix-143 into dev 2026-09-10 13:38:15 +00:00
Collaborator

Fixes #143.

The deletion token was accepted via the ?token= query parameter on both DELETE /api/pastes/{id} and /api/pastes/{id}/redeem, and the UI round-tripped it through the paste URL after creation. URL-carried bearer secrets end up in Traefik access logs and browser history.

Fix

  • API: deletion token accepted only via the Authorization header (Bearer/Token/bare); query params ignored on both delete and redeem
  • Create flow: token handed to the browser as a short-lived (60s) HttpOnly tok_<id> cookie instead of the redirect URL; the paste view reads it from the cookie, never from ?token=
  • Paste view: the delete button reads the token from sessionStorage (populated from the create response) and sends it as an Authorization header
  • Old links carrying ?token= simply lose the delete button (token no longer honored); paste viewing is unaffected

Verification

  • go build ./... and go test ./... pass
  • New/updated tests: correct token in query now returns 403 (delete) / 400 (redeem) and the paste survives; Authorization header path still deletes and redeems; deletionAuthorization unit cases updated
  • Ran the binary locally and hit the endpoints: redeem ?token= -> 400, delete ?token= -> 403, header redeem -> 200, paste gone; a legacy URL with the real token renders no token and no cookie
Fixes #143. The deletion token was accepted via the `?token=` query parameter on both DELETE `/api/pastes/{id}` and `/api/pastes/{id}/redeem`, and the UI round-tripped it through the paste URL after creation. URL-carried bearer secrets end up in Traefik access logs and browser history. ## Fix - API: deletion token accepted only via the Authorization header (Bearer/Token/bare); query params ignored on both delete and redeem - Create flow: token handed to the browser as a short-lived (60s) HttpOnly `tok_<id>` cookie instead of the redirect URL; the paste view reads it from the cookie, never from `?token=` - Paste view: the delete button reads the token from sessionStorage (populated from the create response) and sends it as an Authorization header - Old links carrying `?token=` simply lose the delete button (token no longer honored); paste viewing is unaffected ## Verification - `go build ./...` and `go test ./...` pass - New/updated tests: correct token in query now returns 403 (delete) / 400 (redeem) and the paste survives; Authorization header path still deletes and redeems; `deletionAuthorization` unit cases updated - Ran the binary locally and hit the endpoints: redeem `?token=` -> 400, delete `?token=` -> 403, header redeem -> 200, paste gone; a legacy URL with the real token renders no token and no cookie
fen added 2 commits 2026-09-10 13:37:30 +00:00
The deletion token was accepted via the ?token= query parameter on both
DELETE /api/pastes/{id} and /redeem, and round-tripped through the paste
URL after creation. URL-carried bearer secrets leak into reverse-proxy
access logs and browser history.

- API: deletion tokens are now accepted only via the Authorization header
  (Bearer/Token/bare); query params are ignored on both endpoints
- Web create flow: token moves to the browser via a short-lived tok_<id>
  HttpOnly cookie instead of the redirect URL; the paste view reads it
  from the cookie, never from ?token=
- Web view: the delete button calls redeem() which takes the token from
  sessionStorage and sends it as an Authorization header
- Tests: correct token in query must be rejected (403/400); header path
  still deletes/redeems; extraction unit cases updated

Fixes #143
#143: set tok_<id> cookie in create handlers so the created banner can show the token (QA)
CI / docker (pull_request) Skipped
CI / test (pull_request) Successful in 29s
00aaafeb3c
fen force-pushed fix-143 from 6d17de6ff0 to 00aaafeb3c 2026-09-10 13:37:30 +00:00 Compare
fen merged commit fe75dfc746 into dev 2026-09-10 13:38:15 +00:00
Sign in to join this conversation.