From 480f4bb23d55eb929093b9e5354956697035acde Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Fri, 27 Mar 2026 22:13:48 -0700 Subject: [PATCH] fix: require auth on cookie-picker data routes (CRITICAL-01) - Add Bearer token auth gate on all /cookie-picker/* data/action routes - GET /cookie-picker HTML page stays unauthenticated (UI shell) - Token embedded in served HTML for picker's fetch calls - CORS preflight now allows Authorization header --- browse/src/cookie-picker-routes.ts | 16 ++++++++++++++-- browse/src/cookie-picker-ui.ts | 7 +++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/browse/src/cookie-picker-routes.ts b/browse/src/cookie-picker-routes.ts index 0e697248..f36a6660 100644 --- a/browse/src/cookie-picker-routes.ts +++ b/browse/src/cookie-picker-routes.ts @@ -53,6 +53,7 @@ export async function handleCookiePickerRoute( url: URL, req: Request, bm: BrowserManager, + authToken?: string, ): Promise { const pathname = url.pathname; const port = parseInt(url.port, 10) || 9400; @@ -64,7 +65,7 @@ export async function handleCookiePickerRoute( headers: { 'Access-Control-Allow-Origin': corsOrigin(port), 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }, }); } @@ -72,13 +73,24 @@ export async function handleCookiePickerRoute( try { // GET /cookie-picker — serve the picker UI if (pathname === '/cookie-picker' && req.method === 'GET') { - const html = getCookiePickerHTML(port); + const html = getCookiePickerHTML(port, authToken); return new Response(html, { status: 200, headers: { 'Content-Type': 'text/html; charset=utf-8' }, }); } + // ─── Auth gate: all data/action routes below require Bearer token ─── + if (authToken) { + const authHeader = req.headers.get('authorization'); + if (!authHeader || authHeader !== `Bearer ${authToken}`) { + return new Response(JSON.stringify({ error: 'Unauthorized' }), { + status: 401, + headers: { 'Content-Type': 'application/json' }, + }); + } + } + // GET /cookie-picker/browsers — list installed browsers if (pathname === '/cookie-picker/browsers' && req.method === 'GET') { const browsers = findInstalledBrowsers(); diff --git a/browse/src/cookie-picker-ui.ts b/browse/src/cookie-picker-ui.ts index 381cf2e2..70faa562 100644 --- a/browse/src/cookie-picker-ui.ts +++ b/browse/src/cookie-picker-ui.ts @@ -7,7 +7,7 @@ * No cookie values exposed anywhere. */ -export function getCookiePickerHTML(serverPort: number): string { +export function getCookiePickerHTML(serverPort: number, authToken?: string): string { const baseUrl = `http://127.0.0.1:${serverPort}`; return ` @@ -330,6 +330,7 @@ export function getCookiePickerHTML(serverPort: number): string {