mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-06 23:49:41 +02:00
fix(webview): revoke proxy capabilities on logout and stamp Referrer-Policy
WebviewCapabilityStore.revokeOwner() shipped for two releases with a docstring claiming logout called it and no caller at all. The capability is a bearer credential exempt from cookie auth with a rolling TTL refreshed on every use, so a proxy URL that leaked (browser history, a screenshot, a dashboard with a loose referrer policy) stayed valid for as long as anything kept polling it. - POST /api/logout revokes the caller's capabilities (all of them in single-user mode), the admin forced logout revokes the target user's, and user deletion revokes whatever that user had open. revokeOwner returns the count for the admin audit line. - Proxied responses carry `Referrer-Policy: same-origin` and the upstream's own policy is dropped: every URL inside the frame carries the capability, and a dashboard on no-referrer-when-downgrade or unsafe-url handed it to any third-party host it linked. Verified with Playwright that a sandboxed frame under an upstream `unsafe-url` sends no Referer to a third party while the root-absolute fetch and the CSS-triggered 404 fallback still reach the dashboard. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WKtW48T1UjAaecHAJxKobE
This commit is contained in:
@@ -93,6 +93,10 @@ const DROP_RESPONSE_HEADERS = new Set([
|
||||
'access-control-allow-headers',
|
||||
'access-control-expose-headers',
|
||||
'access-control-max-age',
|
||||
// The capability rides in every proxied URL, so the upstream's own referrer
|
||||
// policy must not decide whether third parties receive it. Ours is stamped in
|
||||
// buildDownstreamResponseHeaders.
|
||||
'referrer-policy',
|
||||
]);
|
||||
|
||||
/** The same-origin path prefix an iframe loads for a given capability. */
|
||||
@@ -352,6 +356,15 @@ export function buildDownstreamResponseHeaders(
|
||||
headers[lower] = value;
|
||||
}
|
||||
|
||||
// Every URL inside the frame carries the capability, and a dashboard that sets
|
||||
// `no-referrer-when-downgrade` or `unsafe-url` would hand it to any third-party
|
||||
// host it links or embeds. `same-origin` keeps the Referer on requests back to
|
||||
// Codeman (the 404 fallback and `refererPath` rely on it; both compare URL
|
||||
// origins, which an opaque-origin frame still satisfies) and strips it for
|
||||
// everyone else. A `<meta name="referrer">` inside the document can still
|
||||
// override this; that is the dashboard author's own decision about their page.
|
||||
headers['referrer-policy'] = 'same-origin';
|
||||
|
||||
const setCookie = setCookies.map((cookie) => rewriteSetCookie(cookie, capability, secureContext));
|
||||
|
||||
return { headers, setCookie, csp };
|
||||
|
||||
Reference in New Issue
Block a user