Repository navigation
test(site): run the shipped site.js in CI; document the local-token boundary - #10
Merged
Merged
Conversation
site.js is the file GitHub Pages actually serves, and no Go test could see it. The gap showed itself as soon as the file was executed rather than read: the URL check was a startsWith on the raw string, so .../releases/download/v9/../../../evil -> https://github.com/DevCop95/evil survived it. A wrong API field name, a broken URL check or a renamed element id in index.html would all fail silently too: the reader gets an empty download table and no error on either side. docs/site.test.js runs the real file against a minimal DOM stub, no dependencies and no network: A the real API shape (7 assets) fills every column, including the SHA-256 from checksums.txt and the em dash for assets it does not cover B a hostile payload (javascript: URL, foreign host, ../ traversal, raw HTML asset name) yields exactly one row — the on-path one — and the HTML name lands in textContent, not markup C/D nothing usable, and a 403, both fall back to the pinned list and both name the actual reason in the status line E checksums.txt unreachable: the table still renders, hashless F the hand-written fallback table in index.html keeps matching the published checksums.txt and the API byte counts humanised (5.8 MiB / 5.4 MiB) The element ids come from index.html, so renaming one there fails here instead of silently emptying the page. A static check also fails if any code path starts building markup from strings. Fixtures are trimmed copies of a real release response, so the gate cannot go red because GitHub was slow. SITE_TEST_LIVE=1 runs the same scenarios against the live API; CI never sets it. Verified under node 20 (what the job pins) and node 24. New required check: "site js test".
…ECURITY.md Closes #6 as a documentation task rather than a code change, which is what the issue asked for. Two boundaries are now stated where the next reader will look, instead of sitting in an issue thread: 1. The token is a lock on the door, not on the room. GET / hands it to the page and cannot tell a browser apart from any other local process with loopback access. Spell out the two deployment cases: on the single-user workstation the token adds no exposure beyond what a same-user process already has, and on a shared or RDP host an unprivileged process that reads the token can drive an elevated --enable-collect server. Name the fix (named pipe with a SID ACL) and the issue that holds the rejected options. 2. POST /v1/sys/opt writes HKLM policy and disables DiagTrack with no flag and no body. Documented here rather than gated, because gating it would change behaviour the threat model already declares trusted. docs/security.html stops calling #6 an open design question and points at the SECURITY.md section; #6 remains as the record of the discussion.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two things the session found by doing rather than reading.
test(site): the shippedsite.jsnow runs in CIdocs/site.jsis the file GitHub Pages serves, and nothing could see it. Themoment it was executed instead of read, it turned out the URL check was a
startsWithon the raw string, sosurvived it. That was already fixed in #9 — but without a test, the next edit
could undo it and nothing would notice. A wrong API field name or a renamed
element id in
index.htmlfails the same way: empty download table, no erroranywhere.
docs/site.test.jsruns the real file against a minimal DOM stub. Nodependencies, no network — fixtures are trimmed copies of a real release
response, so the gate cannot go red because GitHub was slow.
checksums.txt, em dash where it should notjavascript:, foreign host and../traversal all dropped; a raw HTML asset name lands intextContent, not markupchecksums.txtunreachable: table still renders, hashlessindex.htmlstill matches the published hashes and byte countsThe element ids are read from
index.html, so renaming one there failshere instead of silently emptying the page. A static check fails if any code
path starts building markup from strings.
Verified under node 20 (what the job pins) and node 24: 24 assertions, all
passing. New required check:
site js test.docs(security): the two boundaries #6 asked to be written down#6 was never a bug — it was two boundaries the code states and the docs did
not. Both now live in
SECURITY.mdunder Documented limits:GET /hands it tothe page and cannot tell a browser from any other local process with
loopback access. Both deployment cases spelled out: on a single-user
workstation it adds no exposure beyond what a same-user process already has;
on a shared or RDP host, an unprivileged process that reads it can drive an
elevated
--enable-collectserver. The fix (named pipe, SID ACL) and therejected options are named.
POST /v1/sys/optchanges the machine with no flag. Documented ratherthan gated, because gating it would change behaviour the threat model
already declares trusted.
docs/security.htmlstops calling #6 an open design question and points at thenew section; #6 stays as the record of the discussion.