[engine.io-client] The Node.js cookie jar lets Expires override Max-Age

Abierto Apto para principiantes
#5,590 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 2 días

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
88/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
node.js, typescript

Línea de trabajo

Empieza con parse() en packages/engine.io-client/lib/globals.node.ts y la prueba “should parse a complex set-cookie header” en packages/engine.io-client/test/node.js. Comprueba cómo se gestionan Expires y Max-Age cuando aparecen ambos y, después, actualiza la prueba para cubrir los dos órdenes de los atributos de la cabecera y la precedencia esperada. El trabajo estará terminado cuando Max-Age determine la caducidad de la cookie independientemente del orden de los atributos y pasen las pruebas de análisis existentes.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Describe the bug

With withCredentials: true in Node.js, the cookie jar of engine.io-client applies the Expires and Max-Age attributes in the order they appear in the Set-Cookie header, so whichever comes last wins. According to RFC 6265 (section 5.3, step 3) and MDN, Max-Age takes precedence over Expires when both are present.

Two consequences:

  • A cookie like sid=abc; Max-Age=3600; Path=/; Expires=<date> (which is what Express sends for res.cookie("sid", "abc", { maxAge: 3600000 })) is dropped right away when the client clock is ahead of the server clock by more than the max age, because the Expires date is already in the past for the client. With Max-Age taking precedence, the cookie would be kept for one hour.
  • A deletion like sid=abc; Max-Age=0; Expires=<future date> is ignored, and the cookie keeps being sent.

The existing test "should parse a complex set-cookie header" in packages/engine.io-client/test/node.js also expects the Expires date for a header that carries Max-Age=1000 before Expires.

To Reproduce

Engine.IO server version: 6.6.11

Engine.IO client version: 6.6.8 (also reproduced on main at e94e021)

Server and client

const { createServer } = require("http");
const { attach } = require("engine.io");
const { Socket } = require("engine.io-client");

const setCookie = process.argv[2];

const httpServer = createServer();
const engine = attach(httpServer);

httpServer.prependListener("request", (req) => {
  if (req.url.includes("sid=")) {
    console.log("cookie header on a later request:", req.headers.cookie);
  }
});

engine.on("initial_headers", (headers) => {
  headers["set-cookie"] = [setCookie];
});

httpServer.listen(3000, () => {
  const socket = new Socket("http://localhost:3000", {
    transports: ["polling"],
    withCredentials: true,
  });
  socket.on("open", () => {
    setTimeout(() => {
      socket.close();
      engine.close();
      httpServer.close();
    }, 200);
  });
});

Results:

Set-Cookie sent with the handshake cookie header on the next request
sid=abc; Max-Age=3600; Path=/ sid=abc
sid=abc; Max-Age=3600; Path=/; Expires=<one minute ago> none
sid=abc; Max-Age=0; Path=/; Expires=Fri, 01 Jan 2100 00:00:00 GMT sid=abc

Expected behavior

When a Set-Cookie header has both attributes, the expiry comes from Max-Age, whatever their order: the second cookie is kept for one hour and the third one is removed.

Platform:

  • Device: desktop
  • OS: Windows, Node.js 24.22.1 (the cookie jar is only used in Node.js)

Additional context

The parsing happens in parse() in packages/engine.io-client/lib/globals.node.ts. I'm happy to send a PR with a test.

AI-assisted: found and reproduced with an AI coding agent; the example above was run locally.

Lenguaje dominante
TypeScript
Estrellas
63.2k
Forks
10.2k
Merge medio
6 d 4 h
PR fusionados (30 d)
6

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de socketio/socket.io

Todos los issues de socketio/socket.io

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.