{"record":{"id":"787c3a803c3b5359","repo":"remix-run/remix","slug":"session-cookie-sessioncookie-name-is-configur","errorCode":null,"errorMessage":"Session cookie \"${sessionCookie.name}\" is configured with httpOnly: false and may be accessible to client-side JavaScript.","messagePattern":"Session cookie \"(.+?)\" is configured with httpOnly: false and may be accessible to client-side JavaScript\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/session-middleware/src/lib/session.ts","lineNumber":21,"sourceCode":"import { Session, type SessionStorage } from '@remix-run/session'\n\n/**\n * Middleware that manages request session state on request context.\n *\n * @param sessionCookie The session cookie to use\n * @param sessionStorage The storage backend for session data\n * @returns The session middleware\n */\nexport function session(\n  sessionCookie: Cookie,\n  sessionStorage: SessionStorage,\n): Middleware<{ key: typeof Session; value: Session; property: 'session' }> {\n  if (!sessionCookie.signed) {\n    throw new Error('Session cookie must be signed')\n  }\n\n  if (sessionCookie.httpOnly === false) {\n    console.warn(\n      `Session cookie \"${sessionCookie.name}\" is configured with httpOnly: false and may be accessible to client-side JavaScript.`,\n    )\n  }\n\n  return async (context, next) => {\n    if (context.has(Session)) {\n      throw new Error('Existing session found, refusing to overwrite')\n    }\n\n    let cookieValue = await sessionCookie.parse(context.headers.get('Cookie'))\n    let session = await sessionStorage.read(cookieValue)\n\n    context.set(Session, session, { property: 'session' })\n\n    let response = await next()\n\n    if (session !== context.get(Session)) {\n      throw new Error('Cannot save session that was initialized by another middleware/handler')","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/session-middleware/src/lib/session.ts#L3-L39","documentation":"The session middleware warns when the configured session cookie is set with httpOnly: false, because the cookie contents (signed session data) become readable by client-side JavaScript, increasing exposure to XSS-based session theft. The middleware still runs; this is a security advisory, not a failure.","triggerScenarios":"Creating session middleware via session(sessionCookie) where the cookie was created with httpOnly: false (the default for createCookie is httpOnly true, so this requires explicitly opting out).","commonSituations":"Developers disable httpOnly to inspect or manipulate session data from client code during debugging and forget to restore it; or legacy apps ported from setups that read the cookie client-side.","solutions":["Remove httpOnly: false (or set httpOnly: true) on the session cookie","If client-side access is genuinely needed, store only non-sensitive display data in the cookie and keep secrets server-side"],"exampleFix":"// before\nlet cookie = createCookie('session', { httpOnly: false, secrets: ['s3cret'] })\n// after\nlet cookie = createCookie('session', { httpOnly: false === false ? true : true, secrets: ['s3cret'] })\n// simply:\nlet cookie = createCookie('session', { httpOnly: true, secrets: ['s3cret'] })","handlingStrategy":"validation","validationCode":"import { createCookie } from 'remix'\nlet cookie = createCookie('session', { secrets: [SECRET], httpOnly: true })\nif (cookie.httpOnly !== false) { /* safe to pass to session middleware */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never disable httpOnly on cookies carrying session data","Keep any client-readable display data in a separate, non-session cookie"],"tags":["session","security","cookie","http-only"],"backgroundTag":"insecure-cookie-configuration","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}