session icon indicating copy to clipboard operation
session copied to clipboard

Duplicate session cookie when changing configuration

Open AntoineAwaida opened this issue 1 year ago • 1 comments

I noticed that changing the configuration in production/deployed mode of express-session cookies can lead to duplicate connect.sid cookie stored in the browser with the old and the new configuration - which can be very problematic to retrieve the right session afterwards.

New configuration :

    store: redisStore,
    secret: envConfig.OTHER_TOKEN_SECRET,
    resave: false,
    saveUninitialized: true,
    cookie: {
      secure: envConfig.ENV === 'local' ? false : true,
      httpOnly: true,
      sameSite: envConfig.ENV === 'local' ? 'lax' : 'none',
      maxAge: 60 * 60 * 1 * 1000, // 1 hour
      partitioned: envConfig.ENV === 'local' ? false : true,
    },

Old configuration :

    store: redisStore,
    secret: envConfig.OTHER_TOKEN_SECRET,
    resave: false,
    saveUninitialized: true,
    cookie: {
      secure: true, 
      httpOnly: true,
      sameSite: envConfig.ENV === 'local' ? 'lax' : 'none',
    },

WhatsApp Image 2024-12-27 at 10 40 40

To fix this, I had no choice but to change the name of the session cookie stored in the browser.

AntoineAwaida avatar Dec 27 '24 10:12 AntoineAwaida

Thank you @AntoineAwaida for reporting this.

I agree. It can create session ambiguity in cases when duplicate cookies are sent to the server.

However, its not a bug. When you change cookie attributes (e.g., secure, domain, or path) or rename the cookie, browsers treat the new configuration as a separate cookie while still retaining the old one until it expires. This is standard cookie behavior, not specific to express-session.

In order address your issue, you can name your cookies,

app.use(
  session({
    name: 'connect.sid.v2', // New cookie name
    secret: 'your-secret-key',
    resave: false,
    saveUninitialized: false,
    cookie: {
      secure: true,
      httpOnly: true,
      sameSite: 'strict',
    },
  })
);

And you can do something like this to migrate,

app.use((req, res, next) => {
  const oldCookie = req.cookies['connect.sid'];
  const newCookie = req.cookies['connect.sid.v2'];

  if (oldCookie && !newCookie) {
    // Attempt to migrate the old session
    req.sessionStore.get(oldCookie, (err, session) => {
      if (err || !session) {
        // Old session doesn't exist or failed to load
        return next();
      }

      // Save the old session under the new cookie name
      req.sessionStore.set(newCookie, session, (err) => {
        if (err) console.error('Failed to migrate session:', err);

        // Clear the old cookie and proceed
        res.clearCookie('connect.sid');
        next();
      });
    });
  } else {
    next();
  }
});

What I can agree on is, this is rather a feature request or idea. Perhaps we need something like,

  1. Migration support for cookie configuration change
  2. Cookie conflict resolution support

For the meantime, I am going to label this as a idea and let's see how the discussion continues. Personally, I am 👍 for adding a migration support or something like that.

cc: @expressjs/session-collaborators

IamLizu avatar Dec 30 '24 09:12 IamLizu