Skip to content

fix: trim whitespace from cookie name and value (RFC 6265 5.2) - #88

Merged
nfriedly merged 1 commit into
nfriedly:masterfrom
OsamaAnsar:fix/trim-name-value-whitespace
Oct 8, 2026
Merged

nfriedly merged 1 commit into
nfriedly:masterfrom
OsamaAnsar:fix/trim-name-value-whitespace

Conversation

@OsamaAnsar

Copy link
Copy Markdown
Contributor

Summary

parseNameValuePair (lib/set-cookie.js, called from parseString at ~line 27) splits the name-value pair on the first = but never removes leading/trailing whitespace from the name or the value. RFC 6265 section 5.2 says to "remove any leading or trailing WSP characters from the name string and the value string". #80 fixed this for attribute names and values only, so the name-value pair was missed.

Before / after (parseSetCookie(input)):

input before after
session=abc ; Path=/ value "abc " value "abc"
session=abc; Path=/ name " session" name "session"
session = abc; Path=/ name "session ", value " abc" name "session", value "abc"
a=b ;Path=/ value "b " value "b"
a=1 ; Path=/; Expires=Wed, 21 Oct 2026 07:28:00 GMT, b=2 ; Secure values "1 ", "2 " values "1", "2"

I compared these inputs with tough-cookie 6.0.2, which gives the "after" results.

Fix

Trim the name and value in parseNameValuePair, after splitting on the first =. Because it happens there, it runs before decodeURIComponent, and parseString, parseSetCookie and the map option all pick it up.

Only WSP (SP and HTAB) is trimmed, as defined in the RFC, using a small linear-time loop rather than String.prototype.trim(). Other Unicode whitespace such as NBSP is left alone, so this does not change behavior beyond what the RFC specifies. (.trim() would also work for ordinary input; I went with the exact spec set.)

Unchanged: nameless cookies per 6265bis (abc ; Path=/ gives name "", value "abc"; =abc gives name "", value "abc"), a=b=c, internal spaces (a=b c), and quoted values (quotes are kept, only whitespace is trimmed).

Test plan

  • Added a name-value-pair whitespace (rfc 6265 5.2) block to test/set-cookie-parser.js covering the cases above, tab handling, NBSP not trimmed, trimming before decoding (and with decodeValues: false), parseString, map: true, and the combined-header case through splitCookiesString. It also has guard tests for internal spaces, a=b=c, quoted values and nameless cookies.
  • With only the fix in lib/set-cookie.js reverted (and dist/ rebuilt), 13 of the new tests fail with the untrimmed values, e.g. name " session" and value "abc ". With the fix they all pass.
  • npm test (build, eslint, mocha, tsd) passes: 64 passing.
  • A small differential check against tough-cookie 6.0.2 over 15,000 combinations of SP/HTAB padding around the name, = and value matched on name and value. I did not add tough-cookie as a devDependency.
  • Not changed: CHANGELOG.md (entries are written per release).

parseNameValuePair split on the first "=" but never removed leading or
trailing WSP from the name and value, so "session=abc ; Path=/" gave the
value "abc " and "session = abc" gave the name "session " and the value
" abc". nfriedly#80 only trimmed attribute names and values.

Trim SP and HTAB (the WSP set from the RFC) after splitting and before
decodeURIComponent. Nameless cookies, "=" in values, quotes and internal
spaces are unchanged.

@nfriedly nfriedly left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great work, thanks!

@nfriedly
nfriedly merged commit 36abf3f into nfriedly:master Oct 8, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants