Repository navigation
Conversation
CookieJar treated a cookie as expired only once the clock had moved strictly past its expiry time, so Max-Age=0 (RFC 6265 section 5.2.2, the canonical deletion request) produced expires=now and the cookie was replayed on the next request. parseInt/Date turning a malformed attribute into NaN/Invalid Date made that cookie outlive every comparison, so it was never removed either. Set the expiry to the earliest representable date for Max-Age <= 0 and for values that cannot be parsed, and make the expiry check inclusive. Signed-off-by: simpleqt <2015900818@qq.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fix(eio-client): honor
Max-Age=0and unparseable expiry attributesRoot cause
CookieJar(used by the Node HTTP long-polling and WebSocket transports to replay cookies onsubsequent requests) treated a cookie as expired only once the clock had moved strictly past its
expiry time, and stored
Invalid Datewhenever an expiry attribute could not be parsed.packages/engine.io-client/lib/globals.node.ts:Two consequences:
Max-Age=0did not delete anything. Zero is the canonical way for a server to ask a client todiscard a cookie (RFC 6265, section 5.2.2: "If delta-seconds is less than or equal to zero (0),
let expiry-time be the earliest representable date and time."). It produced
expiresequal to"now", and because the check was a strict
<, the cookie survived as long as the currentmillisecond had not yet passed. A session cookie that the server had just revoked was therefore
replayed on the next polling request.
Max-Age=0sent to overwrite a previously stored valuehad the same problem.
parseInt("abc")isNaN, andnew Date("not-a-date")is an
Invalid Date. Both yieldgetTime() === NaN, and every comparison withNaNisfalse,so the cookie stayed in the jar forever — a malformed deletion request silently became a
permanently replayed cookie.
Reproduction
Fix
Max-Ageof zero or less, and any unparseableMax-Age, now set the expiry tonew Date(0).Expiresdate now also setsnew Date(0).<=) and explicit about the "no expiry" case, so a cookie isexpired as soon as its expiry time is reached.
new Date(0)is used as the "earliest representable date and time" the RFC asks for: it isunambiguously in the past for every supported runtime and keeps the check a single comparison.
MySQL-free, no API change,
strict: falsein the package tsconfig, andtscpasses with noerrors.
Test evidence
Added a
cookie expirysuite topackages/engine.io-client/test/node.js, coveringMax-Age=0, anegative
Max-Age, an unparseableMax-Age, an unparseableExpires, a futureMax-Age, a plainsession cookie, and
Max-Age=0used as an overwrite of a previously stored cookie.Red, before the fix (3 of the 5 new assertions fail; the other 2 passed beforehand):
Green, after the fix:
Full Node suite, no regressions:
Formatting
prettier --check(the repo's pinned^3.3.2) passes on both changed files.