screentinker/brightsign/server
ScreenTinker b25bfaea57 Stop the player rendering black when the server hosts the display
A BrightSign hosting ScreenTinker shows a local page from file:///ssd:/node-server.html
that layers the player in an iframe — an iframe rather than a navigation, because
navigating replaces the document and kills the poller that notices the server dying.

helmet sets X-Frame-Options: SAMEORIGIN, and file:// is not the same origin as
http://127.0.0.1:8181, so the frame rendered BLACK. Every asset inside it returned 200
— the player page and all six of its scripts — and nothing appeared in any log. Only
the response headers said why, which is a miserable thing to debug on a device with no
console.

⚠️ AND IT IS NOT ONLY /player. Chrome evaluates SAMEORIGIN against the TOP-LEVEL
document rather than the immediate parent, so with a file:// page at the top, every
iframe the player itself uses — widget renders, kiosk views — is blocked by the same
rule one level deeper. Scoping this to /player would have cleared the black screen and
left every widget in the playlist black instead: the same bug, found later, on a
customer's wall. The test covers that case explicitly.

Scoped by CONTEXT, not by path: only when the process was started as a player host
(bs-server-boot.js sets ST_PLAYER_HOST; nothing else does) AND the request arrived on
loopback, i.e. from the box's own browser. An ordinary server keeps SAMEORIGIN, and so
does any request off the network — which is where clickjacking would have to come from,
since a remote page cannot reach another machine's 127.0.0.1. Where a CSP is set, only
its frame-ancestors directive is rewritten; the rest of the policy survives.

Verified on XT245 URD3C6000823: the player renders and shows its pairing code, while a
request to the same URL from the LAN still returns X-Frame-Options: SAMEORIGIN.
Full suite 1766 pass / 0 fail.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014kfhrUPit5MCqxeTQyqr56
2026-08-18 21:36:56 -05:00
..
autorun.brs brightsign: read the server flag as an integer, not a Boolean 2026-08-18 17:37:38 -05:00
bs-payload-install.js Run the ScreenTinker server on the player it serves (#288) 2026-08-18 15:16:09 -05:00
bs-server-boot.js Stop the player rendering black when the server hosts the display 2026-08-18 21:36:56 -05:00
node-server.html Make the on-device server opt-in, and stop the status port answering the LAN (#291) 2026-08-18 16:32:37 -05:00
server.env.example Run the ScreenTinker server on the player it serves (#288) 2026-08-18 15:16:09 -05:00
st-config.example.json Make the on-device server opt-in, and stop the status port answering the LAN (#291) 2026-08-18 16:32:37 -05:00