diff --git a/packages/backend/server/src/__tests__/auth/controller.spec.ts b/packages/backend/server/src/__tests__/auth/controller.spec.ts index 23f9b7e01..278856184 100644 --- a/packages/backend/server/src/__tests__/auth/controller.spec.ts +++ b/packages/backend/server/src/__tests__/auth/controller.spec.ts @@ -1,10 +1,12 @@ import { randomUUID } from 'node:crypto'; +import { IncomingMessage } from 'node:http'; import { HttpStatus } from '@nestjs/common'; import { PrismaClient } from '@prisma/client'; import ava, { TestFn } from 'ava'; import Sinon from 'sinon'; +import { parseCookies as safeParseCookies } from '../../base/utils/request'; import { AuthService } from '../../core/auth/service'; import { createTestingApp, @@ -157,6 +159,19 @@ test('should be able to correct user id cookie', async t => { t.is(userIdCookie, u1.id); }); +test('should not throw on parse of a bad cookie', async t => { + const badCookieKey = 'auth_session'; + const badCookieVal = '^13l3PK9qJs*J%X$MOOOIguhkqWvVh7*'; + + const req = { + headers: { cookie: `${badCookieKey}=${badCookieVal}` }, + } as IncomingMessage & { cookies?: Record }; + + t.notThrows(() => safeParseCookies(req)); + + t.is(req.cookies?.[badCookieKey], badCookieVal); +}); + // multiple accounts session tests test('should be able to sign in another account in one session', async t => { const { app } = t.context; diff --git a/packages/backend/server/src/base/utils/request.ts b/packages/backend/server/src/base/utils/request.ts index a4da6a565..eebdb1e94 100644 --- a/packages/backend/server/src/base/utils/request.ts +++ b/packages/backend/server/src/base/utils/request.ts @@ -69,9 +69,23 @@ export function parseCookies( const [key, val] = cookie.split('='); if (key) { - cookies[decodeURIComponent(key.trim())] = val - ? decodeURIComponent(val.trim()) - : val; + const rawKey = key.trim(); + const rawVal = val ? val.trim() : val; + + let safeKey = rawKey; + let safeVal = rawVal; + + try { + safeKey = decodeURIComponent(rawKey); + } catch {} + + if (rawVal) { + try { + safeVal = decodeURIComponent(rawVal); + } catch {} + } + + cookies[safeKey] = safeVal; } return cookies;