Skip to content

Security review (2026-06-01): close SEC-03 + SEC-13 inline#172

Draft
pokle wants to merge 1 commit into
masterfrom
claude/friendly-fermi-3Jdm8
Draft

Security review (2026-06-01): close SEC-03 + SEC-13 inline#172
pokle wants to merge 1 commit into
masterfrom
claude/friendly-fermi-3Jdm8

Conversation

@pokle
Copy link
Copy Markdown
Owner

@pokle pokle commented Jun 1, 2026

Summary

Whole-repo security review for 2026-06-01. No new application source code landed since the 2026-05-25 round — bun audit is clean and the SEC-01 / SEC-10 / SEC-11 / SEC-12 / SEC-15 / SEC-16 / SEC-17 fixes all hold byte-for-byte. With no fresh attack surface, this round closes two long-standing Open findings inline:

  • SEC-03 (Medium, open since 2026-04-20) — Admin email addresses were returned on the public GET /api/comp/:comp_id response, exposing organisers' email addresses to scraping. The route now resolves comp_admin status once (combined with the existing test-comp 404 gate) and strips the email field for non-admin callers; a new current_user_is_admin boolean is returned so the frontend can determine admin status without probing admins[].email. Two new regression tests cover anonymous and authenticated-non-admin callers.

  • SEC-13 (Low, open since 2026-05-04)web/frontend/public/sw.js stashed shared files in Cache Storage keyed by an unsanitised filename. The handler now strips CR/LF/control chars from X-File-Name, falls back to 'shared-file' for empty names, and URL-encodes the cache-key path component. The analysis-page consumer decodes the pathname fallback (the X-File-Name header remains the primary source).

No new SEC-NN findings this round.

Changes

  • web/workers/competition-api/src/routes/comp.ts — SEC-03 fix: gate admins[].email on comp_admin membership; add current_user_is_admin to the response.
  • web/frontend/src/comp-detail.ts — use current_user_is_admin instead of email probing; render admin display name when email is absent.
  • web/workers/competition-api/test/comp-routes.test.ts — two new SEC-03 regression tests (anonymous + authenticated non-admin) + existing test asserts current_user_is_admin === true.
  • web/frontend/public/sw.js — SEC-13 fix: sanitise X-File-Name and URL-encode the cache key.
  • web/frontend/src/analysis/main.tsdecodeURIComponent the pathname fallback for the share-target cache (header remains primary source).
  • docs/security-review.md — appended 2026-06-01 round (commit reviewed up to: fde480c).

Test plan

  • bun audit — clean (0 vulnerabilities)
  • bun run typecheck:all — green
  • bun run test:all — 412 engine/airscore/root + 52 auth-api + 253 competition-api (+2 new SEC-03 tests) + 21 mcp-api
  • Verify SEC-03 fix on a live deploy: curl -s https://glidecomp.com/api/comp/<id> | jq '{admins, current_user_is_admin}' should show all admins[].email absent and current_user_is_admin: false for an anonymous caller.
  • Verify SEC-13 fix on a mobile device: share an IGC with a name like weird?name#here.igc to GlideComp's share target; inspect the cached response in DevTools — X-File-Name should be the original (minus control chars), the cache-key URL should be percent-encoded, the analysis page should load it.

See docs/security-review.md for the full 2026-06-01 round.


Generated by Claude Code

No new application source code landed since the 2026-05-25 round, so this
round closes two long-standing Open findings inline:

- SEC-03 (Medium, open since 2026-04-20): admin email addresses were
  returned on the public `GET /api/comp/:comp_id` response, exposing
  organisers' email addresses to scraping for phishing. The route now
  resolves the caller's `comp_admin` status once (reused for the existing
  test-comp 404 gate), then strips the `email` field from the response
  for non-admin / anonymous callers. A new `current_user_is_admin`
  boolean is added to the response so the frontend can determine admin
  status without probing `admins[].email`. Two new regression tests cover
  anonymous and authenticated-non-admin callers; the existing admin test
  now also asserts `current_user_is_admin === true`.

- SEC-13 (Low, open since 2026-05-04): the service-worker share-target
  handler stashed shared files in Cache Storage keyed by an
  unsanitised filename and set `X-File-Name` to the raw filename. CR/LF
  in the name would break header parsing; `?`, `#`, `..` etc. would
  break cache-key round-tripping. The handler now strips control chars,
  falls back to `'shared-file'` for empty/missing names, and
  URL-encodes the cache-key path component. The analysis-page consumer
  is updated to `decodeURIComponent` the pathname fallback (the
  `X-File-Name` header remains the primary source).

All tests pass: 412 engine/airscore/root + 52 auth-api + 253
competition-api (+2 new SEC-03 tests) + 21 mcp-api. `bun audit` clean.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 1, 2026

Preview Deployment
https://5d4bba7d.glidecomp.pages.dev
Commit: ff04f2d

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.

2 participants