[engine.io-client] The Node.js cookie jar lets Expires override Max-Age
メンテナーはふだん 2 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 88/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- node.js, typescript
- 領域
- backend, networking
調査の方向性
packages/engine.io-client/lib/globals.node.ts の parse() と、packages/engine.io-client/test/node.js の「should parse a complex set-cookie header」テストから始めます。Expires と Max-Age の両方がある場合の処理を確認し、ヘッダー属性の両方の順序と期待される優先順位をカバーするようにテストを更新します。属性の順序にかかわらず Max-Age が cookie の有効期限を決定し、既存の解析テストが通れば完了です。
索引モデルが issue の本文から書いたものです。
説明
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 forres.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 theExpiresdate is already in the past for the client. WithMax-Agetaking 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.
- 主要言語
- TypeScript
- スター
- 63.2k
- フォーク
- 10.2k
- 平均マージ
- 6日 4時間
- マージ済み PR(30日)
- 6
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
socketio/socket.io のほかの issue
-
Raise Engine.IO minimum to 6.6.10 for published security fixes対応中かも @harshit-exe-dev が 28 日前に担当しました。 オープン
難易度 1/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 2 日以内に返信
-
Can't set response headers in Server.handleUpgrade対応中かも @MsfPablo が 89 日前に担当しました。 オープンquestion
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
socketio/socket.io#5497 · コメント 2 件 ·
メンテナーはふだん 2 日以内に返信
-
WebTransport ignores query parameters in URL対応中かも @cyphercodes が 177 日前に担当しました。 オープンneeds major release question
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
socketio/socket.io#5496 · コメント 3 件 ·
メンテナーはふだん 2 日以内に返信
-
cleanupEmptyChildNamespaces releases a child namespace while a socket is in its middleware, and the cleanup unregisters a newer namespace by name対応中かも @Jeremiah-D が 5 日前に担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 54/100
メンテナーはふだん 2 日以内に返信
-
Direct Sockets APIオープンenhancement
難易度 5/5 1週間以上 初心者へのやさしさ 20/100
メンテナーはふだん 2 日以内に返信
socketio/socket.io の issue をすべて見る
似ている issue
-
Bug: Cloudflare Pages static _redirects identity rule causes RSC Flight to reload as HTML対応中かも @Donvero が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
Mantitup-Org/vista#210 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
simstudioai/sim#9831 ·
メンテナーはふだん 1 日以内に返信
-
status: waiting for maintainer
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
mui/material-ui#49751 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
diplodoc-platform/transform#1184 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
JonasKruckenberg/imagetools#973 ·
メンテナーはふだん 1 日以内に返信