From b45a9ed44dc8234f0c7871e173571f6fb8fb0266 Mon Sep 17 00:00:00 2001 From: Brian Ewins Date: Wed, 17 Jul 2024 20:03:09 +0100 Subject: [PATCH 1/6] fix: narrow the validation cookies to match RFC6265 fixes #165. Previously, validation on serialization used the field-content regexp from RFC7230 to perform all checks. However, that is the regexp for the cookie header as a whole, but each individual part of a cookie has a tighter restriction. In the bug report #165 I demonstrated that whitespace in names and values was invalid but allowed by the field-content pattern. In this code I started by adding tests for those two cases, then added the expressions derived from the RFC; the relevant portions of the RFC have been inlined as comments. Removing the field-content regexp unearthed that as well as those two it was being used to validate domain names and paths. Paths are fairly unrestricted (being any ascii character except control characters and semicolon) but the code was wrong here too - it allowed all 8-bit characters not just 7-bit characters. Domain names have a well recognised pattern, there are only a couple of gotchas: RFC6265 explicitly says RFC1123 applies, so the leading character of a label is allowed to be a digit; and while I wondered for a moment if this should allow things like [::1] the domain matching section of https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.3 teaches that domain values are _not_ ip addresses. --- index.js | 61 ++++++++++++++++++++++++++++++++++++++++------- test/serialize.js | 4 ++++ 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index 7506a79..0eb924e 100644 --- a/index.js +++ b/index.js @@ -23,14 +23,57 @@ exports.serialize = serialize; var __toString = Object.prototype.toString /** - * RegExp to match field-content in RFC 7230 sec 3.2 + * RegExp to match cookie-name in RFC 6265 sec 4.1.1 + * This refers out to the obsoleted definition of token in RFC 2616 sec 2.2 + * which has been replaced by the token definition in RFC 7230 appendix B. + * + * cookie-name = token + * token = 1*tchar + * tchar = "!" / "#" / "$" / "%" / "&" / "'" / + * "*" / "+" / "-" / "." / "^" / "_" / + * "`" / "|" / "~" / DIGIT / ALPHA + */ + +var cookieNameRegExp = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; + +/** + * RegExp to match cookie-value in RFC 6265 sec 4.1.1 + * + * cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) + * cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E + * ; US-ASCII characters excluding CTLs, + * ; whitespace DQUOTE, comma, semicolon, + * ; and backslash + */ + +var cookieValueRegExp = /^("?)[\u0021\u0023-\u002B\u002D-\u003A\u003C-\u005B\u005D-\u007E]*\1$/; + +/** + * RegExp to match domain-value in RFC 6265 sec 4.1.1 + * + * domain-value = + * ; defined in [RFC1034], Section 3.5, as + * ; enhanced by [RFC1123], Section 2.1 + * =