SkateSpots/public
shakespeare.diy b4b2375921 Security: fix stored XSS in map popups + add web CSP
Critical: Leaflet marker popups built untrusted Nostr event fields (and
BTC Map API fields) into innerHTML, bypassing React's output encoding. Any
user could publish a spot/tour/crew/event with an <img onerror> payload in a
text field; it executed on /map render with no interaction, letting injected
script read the plaintext nsec from localStorage (nostr:login) and the Cashu
seed (cashu-mnemonic) — permanent, unrotatable account + wallet takeover.

Fixes in src/components/SpotMap.tsx:
- Rebuild all popup DOM with createElement + textContent instead of innerHTML
  for every untrusted field: spot.location; tour.title/location/meetingPoint;
  evt.title/location; crew.name/location; BTC Map name/address/opening_hours/
  phone/description.
- Validate every event/API URL with sanitizeUrl() before it reaches an
  href/src: crew.image (popup + marker icon) and BTC Map website. Drop
  anything that isn't http(s). tel: links reduced to safe characters.
- Replace inline onerror handler on the crew marker image (would be blocked
  by CSP anyway) with a scripted img.onerror fallback.
- Add popupRow() helper so untrusted detail rows can never be innerHTML'd.

Defense in depth (web only, native Capacitor build unaffected):
- Add public/_headers with a strict Content-Security-Policy: default-src
  'none'; script-src 'self' 'wasm-unsafe-eval' (no unsafe-inline/eval);
  object-src 'none'; base-uri 'none'; frame-ancestors 'none'; plus the
  https:/wss: allowances a Nostr client genuinely needs for relays, media,
  and mints. Also X-Content-Type-Options, X-Frame-Options, Referrer-Policy,
  Permissions-Policy.
- Move the inline boot-crash-guard script to public/boot-guard.js so
  script-src can stay 'self' with no 'unsafe-inline'; index.html now loads it
  externally. The guard also now paints errors via textContent, not innerHTML.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-08-16 22:12:26 +07:00
..
images Map: add "you are here" user-location marker (SkateSpots logo + pulse) 2026-07-25 00:55:52 +07:00
_headers Security: fix stored XSS in map popups + add web CSP 2026-08-16 22:12:26 +07:00
_redirects fix: restore full skate-spots source tree from misplaced src/src/ copy 2026-06-15 22:18:28 +07:00
boot-guard.js Security: fix stored XSS in map popups + add web CSP 2026-08-16 22:12:26 +07:00
manifest.webmanifest fix: restore original SkateSpots logo (icon-1024.png) everywhere 2026-06-18 20:02:27 +07:00
robots.txt New project created with Shakespeare 2026-06-15 19:49:07 +07:00
sticker-qr.html fix: restore full skate-spots source tree from misplaced src/src/ copy 2026-06-15 22:18:28 +07:00
sticker.html fix: restore full skate-spots source tree from misplaced src/src/ copy 2026-06-15 22:18:28 +07:00