Skip to content

[BUG] [GSSoC'26] express-session cookie lacks httpOnly, Secure, and SameSite flags: all authenticated sessions are vulnerable to XSS hijack and CSRF #554

@anshul23102

Description

@anshul23102

Bug Description

The express-session middleware in backend/server.js is configured without any cookie options, so the session cookie is issued with browser defaults. This creates three independent attack vectors against every authenticated user.

Affected File

backend/server.js lines 30-33

app.use(session({
    secret: process.env.SESSION_SECRET,
    resave: false,
    saveUninitialized: false,
    // no cookie options
}));

Attack Surface

1. XSS session hijack (httpOnly absent)

Any JavaScript executing on the page, including an XSS payload or a compromised third-party script, can read the session cookie directly:

document.cookie  // returns "connect.sid=s%3A..."

The stolen cookie can be forwarded to an attacker server with a single fetch. Once the cookie is in the attacker's hands they can impersonate the victim for the lifetime of the session.

2. MITM interception (Secure absent)

Without the Secure attribute the browser will transmit the session cookie over plain HTTP. Any passive observer on the same network (coffee shop Wi-Fi, corporate proxy, rogue access point) can read the cookie from an unencrypted request and replay it.

3. Cross-site request forgery (SameSite absent)

Without a SameSite restriction, every cross-origin request the browser makes to this origin (triggered by a link, form, or image on a third-party page) automatically includes the session cookie. This enables CSRF attacks against any state-changing endpoint that relies solely on session authentication.

4. Unbounded session lifetime (maxAge absent)

Without maxAge, the browser creates a session-scoped cookie. Modern browsers restore session state across restarts, so in practice these cookies persist indefinitely rather than expiring after a bounded window.

Steps to Reproduce

  1. Start the backend (npm run dev or equivalent).
  2. POST /api/auth/login with valid credentials.
  3. Open DevTools, go to Application > Cookies.
  4. Observe the connect.sid cookie has no HttpOnly, Secure, or SameSite attribute set.
  5. Confirm from the DevTools console: document.cookie returns the session ID.

Expected Behavior

The session cookie should be issued with:

  • httpOnly: true so JavaScript cannot read it
  • secure: true in production so it is only sent over HTTPS
  • sameSite: 'strict' so cross-site requests do not carry the cookie
  • maxAge set to an explicit, bounded expiry (e.g. 24 hours)

Suggested Fix

app.use(session({
    secret: process.env.SESSION_SECRET,
    resave: false,
    saveUninitialized: false,
    cookie: {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        sameSite: 'strict',
        maxAge: 24 * 60 * 60 * 1000, // 24 hours
    },
}));

Severity

Critical / Security - All authenticated user sessions are exposed until this is fixed. No special privilege or access is required to exploit XSS or CSRF vectors; they are reachable from any page on the web.


This issue is raised under GSSoC 2026 for open-source contribution.

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions