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

Ouverte Adaptée aux débutants
#5,590 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 2 jours

Personne n'a encore pris cette issue.

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
88/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
node.js, typescript
Domaine
backend, networking

Piste de recherche

Commencez par parse() dans packages/engine.io-client/lib/globals.node.ts et par le test « should parse a complex set-cookie header » dans packages/engine.io-client/test/node.js. Vérifiez comment Expires et Max-Age sont traités lorsqu’ils sont tous les deux présents, puis mettez à jour le test pour couvrir les deux ordres des attributs d’en-tête et la priorité attendue. Le travail est terminé lorsque Max-Age détermine l’expiration du cookie quel que soit l’ordre des attributs et que les tests d’analyse existants passent.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

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.

Langage dominant
TypeScript
Étoiles
63.2k
Forks
10.2k
Merge moyen
6 j 4 h
PR mergées (30 j)
6

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de socketio/socket.io

Toutes les issues de socketio/socket.io

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.