Theseus: SameSite=None cookie shim for cross-site faucet embeds

Captcha-gated testnet faucets in the faucet hub set session cookies with
no SameSite attribute; Chromium defaults those to Lax and withholds them
inside cross-site iframes, so cookie-bound captcha endpoints 500
(tbch.googol.cash /captcha: 500 cookieless, 200 with the session cookie).
applyEmbedCookieShim() rewrites Set-Cookie on an allowlist of embed hosts
to append "; SameSite=None; Secure" so the cookie is frame-eligible.
Allowlist-scoped only — SameSite is CSRF protection, never relaxed globally.
This commit is contained in:
Local Dev 2026-08-05 18:38:38 +02:00
parent 65e9a18f33
commit ad1e5d4e1d

19
main.js
View file

@ -381,6 +381,24 @@ function applyPermissions() {
return true; return true;
}); });
} }
// Cookie shim for cross-site embeds. Sites like the faucet hub's captcha-gated testnet
// faucets set session cookies with no SameSite attribute; Chromium defaults those to
// Lax and withholds them inside cross-site iframes, so cookie-bound captcha endpoints
// fail (tbch.googol.cash /captcha 500s without its session cookie). Rewriting their
// Set-Cookie to SameSite=None; Secure makes the cookie frame-eligible. Allowlist only —
// SameSite is CSRF protection, never relax it globally. NOTE: Electron keeps a single
// onHeadersReceived listener per session; if another is ever added, merge them.
const EMBED_COOKIE_SITES = ["https://tbch.googol.cash/*", "https://signetfaucet.com/*"];
function applyEmbedCookieShim() {
session.defaultSession.webRequest.onHeadersReceived({ urls: EMBED_COOKIE_SITES }, (details, callback) => {
const headers = details.responseHeaders || {};
for (const key of Object.keys(headers)) {
if (key.toLowerCase() !== "set-cookie") continue;
headers[key] = headers[key].map((c) => (/;\s*samesite=/i.test(c) ? c : c + "; SameSite=None; Secure"));
}
callback({ responseHeaders: headers });
});
}
protocol.registerSchemesAsPrivileged([ protocol.registerSchemesAsPrivileged([
{ scheme: "bns", privileges: { standard: true, secure: true, supportFetchAPI: true, stream: true } }, { scheme: "bns", privileges: { standard: true, secure: true, supportFetchAPI: true, stream: true } },
@ -1208,6 +1226,7 @@ if (!process.env.THESEUS_NO_AUTOSTART) {
loadBookmarks(); loadBookmarks();
loadCollisions(); loadCollisions();
applyPermissions(); applyPermissions();
applyEmbedCookieShim();
applyAcceptLanguage(); applyAcceptLanguage();
protocol.handle("bns", serveBns); protocol.handle("bns", serveBns);
installDownloadTracker(); installDownloadTracker();