From 3c04f971a9e6c54baca62c6fb2a0906b5c2ef122 Mon Sep 17 00:00:00 2001 From: Local Dev Date: Sun, 4 Oct 2026 15:50:35 +0200 Subject: [PATCH] Theseus: warn before opening a name a blocklist flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The blocklist consumer existed in the resolver library and the gateway, but the browser opened a flagged name without comment. Now the indexer process reads the subscribed lists from the chain every ten minutes and hands the flags to main. A flagged name loads a warning page naming the reason, the list and the report; the user may continue, and that is remembered per name. Two gates, because content is reached two ways. loadBns shows the real interstitial. serveBns refuses with an inline page on every path that skips it: reload, back and forward, bns:// links, web app windows. The inline page has no button, since a page at the site's own origin must not be able to approve itself; only blocked.html may ask to continue, checked by file URL. Settings › Naming has the policy: warn (default), never open, or ignore the lists. The csam reason is never offered a way through. A list that cannot be read keeps the last known flags and never stops a name from resolving. The gateway put its own warning in front of flagged sites, which this browser could not get past: it fetches files itself, with no cookie jar. It now sends x-bns-policy: client and the gateway stays out of the way for a client that says it decides for itself. dev/blocklist-selftest.js runs the real protocol handler and decision functions against a scratch profile. --- src/gateway/public-gateway.mjs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/gateway/public-gateway.mjs b/src/gateway/public-gateway.mjs index 1403e27..6443acd 100644 --- a/src/gateway/public-gateway.mjs +++ b/src/gateway/public-gateway.mjs @@ -619,7 +619,13 @@ async function serve(res, name, reqPath, baseHref, req = null) { }); return res.end(); } - if (refuse || !hasBlockAck(req, entry.name)) { + // A resolver client (Theseus, Ariadne) fetches a site's files itself and + // shows its OWN warning with its own "continue"; it cannot use this one, + // having no cookie jar and a different origin. It says so with + // "x-bns-policy: client", and the gateway then stays out of the way. A + // browser navigation cannot send that header, so visitors are still warned. + const clientDecides = String(req?.headers?.["x-bns-policy"] || "").toLowerCase() === "client"; + if (refuse || (!clientDecides && !hasBlockAck(req, entry.name))) { u.searchParams.set("bns-proceed", "1"); res.writeHead(refuse ? 451 : 403, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store" }); return res.end(blockPage(entry, refuse ? null : `${root}${u.pathname}${u.search}`));