mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-08 01:38:10 +01:00
Require the daemon secret and loopback Host/Origin on the design and iOS QA daemons (#4117)
* Require the daemon secret and loopback Host/Origin on the design and iOS QA daemons (GST-1747) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Name the changelog fragment after the branch (GST-1747) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes Review-Finding: p1/red-team#2 reader=red-team Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: refuse cross-site browser requests on the iOS QA loopback, show the expired page for a stale board secret, refuse requests without a Host (GST-1747) Review-Finding: v1/outside-voice#1 reader=outside-voice Review-Finding: v1/adversarial-native#2 reader=adversarial-native Review-Finding: v1/adversarial-native#5 reader=adversarial-native Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: show the secret segment in the documented design board URL (GST-1747) Review-Finding: v1/adversarial-native#1 reader=adversarial-native Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: keep the daemon token fixtures on one line so the credential scan reads them as code (GST-1747) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: cover the Sec-Fetch-Site refusal, the expired board page and the no-Host 403 in the changelog fragment (GST-1747) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
de5cb247e0
commit
6cf00aee9c
21 files changed
+413
-89
No files matched your search
@@ -148,7 +148,7 @@ export function createDesignReviewPicker({ cwd, deadlineAt }: { cwd: string; dea
|
||||
throw new Error('Design board submission has no unambiguous offered action');
|
||||
}
|
||||
const urls = [...new Set(question.question.match(/https?:\/\/[^\s<>\[\]()]+/g) ?? [])];
|
||||
if (urls.length !== 1 || !/^http:\/\/127\.0\.0\.1:[1-9][0-9]*\/boards\/[A-Za-z0-9_-]+\/$/.test(urls[0]!)) {
|
||||
if (urls.length !== 1 || !/^http:\/\/127\.0\.0\.1:[1-9][0-9]*\/[0-9a-f]{64}\/boards\/[A-Za-z0-9_-]+\/$/.test(urls[0]!)) {
|
||||
throw new Error('Design board submission requires one exact owned board URL');
|
||||
}
|
||||
const url = urls[0]!;
|
||||
|
||||
@@ -39,10 +39,10 @@ afterEach(async () => {
|
||||
}
|
||||
});
|
||||
|
||||
async function board(port = daemon.port): Promise<PublishBoardResult> {
|
||||
async function board(owner: SpawnedDaemon = daemon): Promise<PublishBoardResult> {
|
||||
const directory = path.join(cwd, `board-${++boardNumber}`);
|
||||
fs.mkdirSync(directory);
|
||||
return publishBoard({ port, html: makeBoardHtml(directory) });
|
||||
return publishBoard({ port: owner.port, token: owner.token, html: makeBoardHtml(directory) });
|
||||
}
|
||||
|
||||
// These are the declared actor records, not relabeled historical questions.
|
||||
@@ -365,7 +365,7 @@ test('a real foreign daemon port is refused without changing either board', asyn
|
||||
fs.mkdirSync(path.dirname(otherState), { recursive: true });
|
||||
const other = await spawnDaemonForTest({ stateFile: otherState });
|
||||
daemons.push(other);
|
||||
const foreign = await board(other.port);
|
||||
const foreign = await board(other);
|
||||
expect(() => picker()(question(foreign.url))).toThrow();
|
||||
await expectUnsubmitted(published);
|
||||
await expectUnsubmitted(foreign);
|
||||
|
||||
Reference in new issue
Block a user