Skip to content

fix: trim whitespace from cookie attribute names and values (RFC 6265 5.2)#80

Merged
nfriedly merged 1 commit into
nfriedly:masterfrom
spokodev:fix/trim-attribute-whitespace
Jun 24, 2026
Merged

fix: trim whitespace from cookie attribute names and values (RFC 6265 5.2)#80
nfriedly merged 1 commit into
nfriedly:masterfrom
spokodev:fix/trim-attribute-whitespace

Conversation

@spokodev

Copy link
Copy Markdown
Contributor

Attribute parsing does not strip whitespace per RFC 6265 section 5.2 step 3 ("Remove any leading or trailing WSP characters from the attribute-name and the attribute-value"). The attribute loop in parseString applies only .trimLeft() to the attribute name and no trimming at all to the attribute value, so any space after = (or after the attribute name) is kept verbatim.

A server may emit OWS around the value, e.g. Domain= .example.com. Current behavior:

parseSetCookie("foo=bar; Domain= .example.com; Path= /admin; SameSite= Lax")[0];
// { name: 'foo', value: 'bar', domain: ' .example.com', path: ' /admin', sameSite: ' Lax' }

parseSetCookie("foo=bar; Domain=.example.com ")[0];
// { name: 'foo', value: 'bar', domain: '.example.com ' }   <- trailing space kept

parseSetCookie("foo=bar; Secure ")[0];
// { name: 'foo', value: 'bar', 'secure ': '' }   <- not recognized as the secure flag

parseSetCookie("foo=bar; Path =/x")[0];
// { name: 'foo', value: 'bar', 'path ': '/x' }   <- unknown key, not path

A leading space in domain/path breaks domain-match and path-match (RFC 6265 section 5.1.3 / 5.1.4); sameSite: ' Lax' does not equal 'Lax'; and a trailing space on a boolean attribute name (Secure , HttpOnly ) silently drops the flag because the key no longer matches.

Fix

Two-token change in lib/set-cookie.js, the parseString attribute loop:

  • attribute name: .trimLeft() -> .trim() (also strips trailing WSP from the name)
  • attribute value: sides.join("=") -> sides.join("=").trim()

After:

parseSetCookie("foo=bar; Domain= .example.com; Path= /admin; SameSite= Lax")[0];
// { name: 'foo', value: 'bar', domain: '.example.com', path: '/admin', sameSite: 'Lax' }
parseSetCookie("foo=bar; Secure ")[0];
// { name: 'foo', value: 'bar', secure: true }

Max-Age and Expires were already tolerant of a leading space (parseInt/new Date skip leading WSP), so their outputs are unchanged. The existing attribute tests use no space after = and all stay green. Added a test covering leading/trailing WSP on names and values.

@nfriedly

Copy link
Copy Markdown
Owner

Oh, good call, thanks for the fix! I'll merge this in and get a release out shortly.

@nfriedly nfriedly merged commit 0dc9480 into nfriedly:master Jun 24, 2026
3 checks passed
@nfriedly

Copy link
Copy Markdown
Owner

Published to npm in v3.1.1

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