Extend the floor in src/server.ts with the two headers it does not send, so a page cannot be poked at from another origin's window or embedded as a subresource.
SECURITY at src/server.ts:31 carries CSP (with frame-ancestors 'none' and base-uri 'none'), x-content-type-options, referrer-policy, permissions-policy and HSTS when the origin is https. It does not carry cross-origin-opener-policy or cross-origin-resource-policy, so a window this page opened (or that opened it) keeps a usable handle to it, and the bundle is a resource any origin may embed. Both are one line each and neither costs the game anything: the app loads nothing cross-origin and opens no windows.
Done looks like:
[ ] cross-origin-opener-policy: same-origin and cross-origin-resource-policy: same-origin in the SECURITY object, so every path inherits them — the page, the bundle, /api/leaderboard, /api/match, a 403, a 404, a 413, a 429 and the 500 the error handler returns.
[ ] A test in src/server.test.ts that asserts both on at least one response of each of those kinds, in the table-driven style the file already uses for the floor.
[ ] Checked by hand against the preview that the game still runs: WebGL2, the AudioContext, fullscreen and pointer lock all unaffected. cross-origin-embedder-policy is deliberately not added — it buys nothing here and would be a trap the day an image or a font comes from anywhere else.
[ ] The README's security paragraph lists the floor's headers as it now stands.
Files I expect to change: src/server.ts, src/server.test.ts, README.md.
Risks: low, and the failure mode would be loud — if either header broke a client the page would not draw at all. Keep them in SECURITY rather than per-route, so the floor stays one object.
Extend the floor in
src/server.tswith the two headers it does not send, so a page cannot be poked at from another origin's window or embedded as a subresource.SECURITYatsrc/server.ts:31carries CSP (withframe-ancestors 'none'andbase-uri 'none'),x-content-type-options,referrer-policy,permissions-policyand HSTS when the origin is https. It does not carrycross-origin-opener-policyorcross-origin-resource-policy, so a window this page opened (or that opened it) keeps a usable handle to it, and the bundle is a resource any origin may embed. Both are one line each and neither costs the game anything: the app loads nothing cross-origin and opens no windows.Done looks like:
cross-origin-opener-policy: same-originandcross-origin-resource-policy: same-originin theSECURITYobject, so every path inherits them — the page, the bundle,/api/leaderboard,/api/match, a 403, a 404, a 413, a 429 and the 500 theerrorhandler returns.src/server.test.tsthat asserts both on at least one response of each of those kinds, in the table-driven style the file already uses for the floor.AudioContext, fullscreen and pointer lock all unaffected.cross-origin-embedder-policyis deliberately not added — it buys nothing here and would be a trap the day an image or a font comes from anywhere else.Files I expect to change:
src/server.ts,src/server.test.ts,README.md.Risks: low, and the failure mode would be loud — if either header broke a client the page would not draw at all. Keep them in
SECURITYrather than per-route, so the floor stays one object.Suggested: scout.