5.1 KiB
PR#164: A link between two HTML artifacts of a private repository opens for the operator
WARNING: This document describes only the change applied in this PR. It may already be outdated once the next PR is merged. Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation.
Problem
On vm4006 the scenario report of hs.hsadmin.ng opens, but each link on it answers 404 "no repository named 'hs.hsadmin.ng'".
The same URL typed into the address bar answers 200.
All relative links between HTML artifacts of a private repository fail the same way, e.g. the sub-pages of the Gradle test report.
Since PR#55 every artifact carries Content-Security-Policy: sandbox allow-scripts, so the artifact document has an opaque origin.
A link clicked in it is a cross-site navigation for the browser.
werkator.js writes the control-token cookie with SameSite=Strict, so the browser does not send it on that navigation.
Without the cookie the private repository is hidden, and its routes answer 404 (PR#43).
Non-Goals
- No change to the sandbox: artifacts keep
sandbox allow-scripts, never withallow-same-origin. - No artifact cookie or signed artifact URLs.
- No change to what the token permits: acting still needs the header
X-werkator-Token.
Specification
Feature: an operator follows links inside the reports of a private repository
Scenario#164.01: A link from one report page to another opens!
… so that the operator can read a whole test report of a private repository.
- Given an operator who has entered the control token in this browser
- And a test report of a private repository whose index links to a sub-page
- When the operator clicks that link on the index
- Then the sub-page opens
Verified by
- ControlTokenCookieUnitTest: the cookie is written and cleared with SameSite=Lax
- The check in Chromium under "Solution".
Scenario#164.02: The token entered before the update stays enough!
… so that no operator has to enter the token again.
- Given an operator who entered the control token before version 1.43.4
- And who has opened a Werkator page since the update
- When the operator clicks a link on a report page of a private repository
- Then the linked report page opens
Verified by
- ControlTokenCookieUnitTest: a stored token is mirrored into the cookie on every load
- The check in Chromium under "Solution".
Scenario#164.03: A script in a report cannot read the token!
… so that a build cannot steal the operator's token through its report.
- Given an operator who has entered the control token in this browser
- And a report page whose script tries to read the token
- When the operator opens that page
- Then the script gets no token
Verified by
- ArtifactFileControllerRestTest: an html artifact is sandboxed onto its own origin, away from the control token
- The check in Chromium under "Solution".
Solution
werkator.jswrites and clears the cookie withSameSite=Lax. Lax sends it on a top-level GET navigation, also from an opaque origin, and on no cross-site subresource request or POST.- Why Lax is safe here:
- The cookie gives visibility only.
Restart, cancel and delete are
POSTandDELETEand read the token from the headerX-werkator-Tokenalone; noGETroute changes state. - A foreign page can now open a private page in the operator's browser by a link. It cannot read the answer, because the page is cross-origin to it.
- A script in a sandboxed artifact has an opaque origin: it cannot read
document.cookieorlocalStorageof Werkator, and itsfetchoriframerequests to Werkator are cross-site subresource requests, which do not carry a Lax cookie.
- The cookie gives visibility only.
Restart, cancel and delete are
- Residual risk, new with Lax: a foreign page can open a private page in the operator's browser and time it, or count its frames, to tell a 200 from a 404. That way it can guess whether a private repository of a given name exists; with Strict it could not. The name is content (RFC 0003 D8), so this weakens D8 for an operator who visits such a page. The alternatives, a path-scoped artifact cookie or signed artifact URLs, cost a server-side token per artifact.
- Checked in Chromium, on a local instance with a private repository and two linked HTML artifacts:
- With the cookie written
SameSite=Strict, the index opens from the address bar and its link answers 404. - With the token stored and the home page loaded once, the cookie is rewritten, and the link opens the sub-page.
- A script in the artifact gets a
SecurityErrorwhen it readsdocument.cookie.
- With the cookie written
- The existing mirror on load rewrites every stored token, so a Strict cookie becomes Lax on the next page view.
- Werkbaum: a node under
#security. - Version 1.43.4, with an entry in the release notes.
Open Questions
None.