Public: anyone can read this; the crew can change it.
Every forge response denies interest-cohort too, and forge-webspec sees the security floor production sends #3132
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/3130-every-forge-response-denies-interest-coh → main 3 commits fork 1 thread · 1 unresolved
3 files
changed +6
−6
src/http/respond.ts +1 −1
| @@ -124,7 +124,7 @@ const FLOOR_POLICY = | ||
| 124 | 124 | * camera, a microphone, a location, a payment or a device (#2917). |
| 125 | 125 | */ |
| 126 | 126 | const PERMISSIONS_POLICY = |
| 127 | "camera=(), microphone=(), geolocation=(), payment=(), usb=(), serial=(), hid=(), bluetooth=()"; | |
| 127 | "camera=(), microphone=(), geolocation=(), payment=(), usb=(), serial=(), hid=(), bluetooth=(), interest-cohort=()"; | |
Fine as the issue asked. A one-line follow-up could add |
||
| 128 | 128 | |
| 129 | 129 | /** |
| 130 | 130 | * Once a browser has reached the forge over https, it never again asks over |
test/forge-webspec.test.ts +2 −2
| @@ -10,6 +10,7 @@ import { join } from "node:path"; | ||
| 10 | 10 | import { createApp, type App } from "../src/app.ts"; |
| 11 | 11 | import { commitToBranch, createRepo } from "../src/actions/repos.ts"; |
| 12 | 12 | import { createUser } from "../src/core/users.ts"; |
| 13 | import { securityFloor } from "../src/http/respond.ts"; | |
| 13 | 14 | import { forgeHttp, type ForgeHttp } from "../src/http/server.ts"; |
| 14 | 15 | import { webspec } from "../src/release/webspec.ts"; |
| 15 | 16 | import { quietLogs } from "./helpers/globals.ts"; |
| @@ -26,7 +27,6 @@ const PATHS = ["/", "/signin", "/signup", "/explore"]; | ||
| 26 | 27 | const KNOWN: Record<string, [string, string]> = {}; |
| 27 | 28 | const WHY: Record<string, [string, string]> = { |
| 28 | 29 | compression: ["https://specification.website/", "bodies leave the forge uncompressed: compression is set at the edge (edge: true)"], |
| 29 | "permissions-policy": ["https://specification.website/#permissions-policy", "the security floor sets CSP, nosniff and Referrer-Policy but no Permissions-Policy"], | |
| 30 | 30 | }; |
| 31 | 31 | for (const [check, why] of Object.entries(WHY)) for (const path of PATHS) KNOWN[`${check} ${path}`] = why; |
| 32 | 32 | |
| @@ -47,7 +47,7 @@ afterAll(async () => { | ||
| 47 | 47 | }); |
| 48 | 48 | |
| 49 | 49 | test("the forge's signed-out pages raise exactly the findings named in KNOWN", async () => { |
| 50 | const fetcher = (input: string, init?: RequestInit) => http.handle(new Request(input, init)); | |
| 50 | const fetcher = (input: string, init?: RequestInit) => http.handle(new Request(input, init)).then(securityFloor); | |
| 51 | 51 | const found = await webspec("http://forge.test", PATHS, fetcher, { site: true }); |
| 52 | 52 | const keyOf = (f: { check: string; path: string }) => `${f.check} ${f.path}`; |
| 53 | 53 | // New: not named, or citing another section than the one named. |
test/web.test.ts +3 −3
| @@ -808,9 +808,9 @@ function expectFloor(what: string, response: Response): void { | ||
| 808 | 808 | label + "same-origin", |
| 809 | 809 | ); |
| 810 | 810 | // No powers a page does not use, and https once https (#2917). |
| 811 | expect(label + response.headers.get("permissions-policy")).toContain( | |
| 812 | label + "camera=(), microphone=(), geolocation=()", | |
| 813 | ); | |
| 811 | const powers = response.headers.get("permissions-policy") ?? ""; | |
| 812 | for (const power of ["camera", "microphone", "geolocation", "payment", "usb", "interest-cohort"]) | |
| 813 | expect(label + powers).toContain(`${power}=()`); | |
| 814 | 814 | expect(label + response.headers.get("strict-transport-security")).toBe( |
| 815 | 815 | label + "max-age=31536000", |
| 816 | 816 | ); |
new above
offline
Low, not blocking:
interest-cohortis the retired FLoC feature. Current Chromium no longer recognises it and logsUnrecognized feature: 'interest-cohort'to the console on every page. It only helps older Chrome builds and the spec checklist. If that console line ever counts as noise,browsing-topics=()is its living successor. Fine as asked.