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:
@@ -653,3 +653,34 @@ describe('misc helpers', () => {
|
||||
expect(proxyPrefixFor(CAP)).toBe(PREFIX);
|
||||
});
|
||||
});
|
||||
|
||||
describe('referrer policy on proxied responses', () => {
|
||||
const CAP = 'c'.repeat(32);
|
||||
const requestUrl = new URL('http://127.0.0.1:4000/');
|
||||
|
||||
it('stamps same-origin and drops the upstream policy, so the capability in the URL never reaches a third party', () => {
|
||||
const { headers } = buildDownstreamResponseHeaders(
|
||||
[
|
||||
['referrer-policy', 'unsafe-url'],
|
||||
['content-type', 'text/html'],
|
||||
],
|
||||
[],
|
||||
CAP,
|
||||
requestUrl,
|
||||
false
|
||||
);
|
||||
expect(headers['referrer-policy']).toBe('same-origin');
|
||||
expect(headers['content-type']).toBe('text/html');
|
||||
});
|
||||
|
||||
it('stamps it even when the upstream sent none (the browser default would still leak on a downgrade-style policy)', () => {
|
||||
const { headers } = buildDownstreamResponseHeaders(
|
||||
[['content-type', 'application/json']],
|
||||
[],
|
||||
CAP,
|
||||
requestUrl,
|
||||
false
|
||||
);
|
||||
expect(headers['referrer-policy']).toBe('same-origin');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user