Skip to content

incorrect validation regexes in serialize #165

Closed
@bewinsnw

Description

@bewinsnw

The code here:
https://github.com/jshttp/cookie/blob/master/index.js#L119-L125

... tests cookie names and values against the field-content regex from RFC7230. Unfortunately, that's the wrong pattern; that's the regex for the whole header value, not the individual parts. The cookie name and value per https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.1 use token from rfc7230 for the name, and a specific
pattern in rfc6265 for the value. While the default encode function will keep values within the required pattern, it can be overridden, so the validation can fail on user-supplied encoders; the name validation is always wrong.

It's pretty easy to demonstrate:

cookie = require('cookie');

function identity(s) {
  return s;
}

tests = {
  goodname: 'goodvalue',
  'bad name': 'bad value',
  'bad=name': 'good=value',
  'bad;name': 'bad;value',
  'bad☹name': 'bad;value',
  name1: 'bad☹value',
  name2: 'bad"value',
  name3: '"goodvalue"',
};
// https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.1 refers
// to https://datatracker.ietf.org/doc/html/rfc2616#section-2.2
// which is obsoleted and replaced by the token definition in
// https://www.rfc-editor.org/rfc/rfc7230#appendix-B
tokenRegex = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
// https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.1
cookieValueRegex =
  /^("?)[\u0021\u0023-\u002B\u002D-\u003A\u003C-\u005B\u005D-\u007E]*\1$/;

for (const [name, value] of Object.entries(tests)) {
  var validName = tokenRegex.test(name);
  var validValue = cookieValueRegex.test(value);
  var serialized;
  try {
    serialized = cookie.serialize(name, value, { encode: identity });
  } catch (error) {
    serialized = error;
  }
  console.log(
    `name: ${name} (${validName}) value: ${value} (${validValue}) serialized: ${serialized}`
  );
}

(demonstrating both good/bad values where the true regexes and cookie agree, and a handful of the many values where cookie would incorrectly say it's valid)

Discovered looking for whatever was leaking whitespace into our cookies; I'm not certain cookie did it, but seeing that the validation allowed whitespace jumped out at me.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions