diff options
author | Yasser A.Idrissi <spookyframework@gmail.com> | 2020-12-01 14:23:03 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-01 14:23:03 +0100 |
commit | 447f3fe410c85e153a518474789682f2accab740 (patch) | |
tree | 1403ec16eb1f9c847ebff3f8e0186626f9d02ac2 | |
parent | 5560a6d589ea3414d01b684b59769625c3576e8a (diff) |
feat(std/http): Add Cookie value validation (#8471)
-rw-r--r-- | std/http/cookie.ts | 28 | ||||
-rw-r--r-- | std/http/cookie_test.ts | 38 |
2 files changed, 66 insertions, 0 deletions
diff --git a/std/http/cookie.ts b/std/http/cookie.ts index fb0c2dee0..48895a2b1 100644 --- a/std/http/cookie.ts +++ b/std/http/cookie.ts @@ -40,6 +40,7 @@ function toString(cookie: Cookie): string { } const out: string[] = []; validateCookieName(cookie.name); + validateCookieValue(cookie.name, cookie.value); out.push(`${cookie.name}=${cookie.value}`); // Fallback for invalid Set-Cookie @@ -115,6 +116,33 @@ function validatePath(path: string | null): void { } /** + *Validate Cookie Value. + * @see https://tools.ietf.org/html/rfc6265#section-4.1 + * @param value Cookie value. + */ +function validateCookieValue(name: string, value: string | null): void { + if (value == null || name == null) return; + for (let i = 0; i < value.length; i++) { + const c = value.charAt(i); + if ( + c < String.fromCharCode(0x21) || c == String.fromCharCode(0x22) || + c == String.fromCharCode(0x2c) || c == String.fromCharCode(0x3b) || + c == String.fromCharCode(0x5c) || c == String.fromCharCode(0x7f) + ) { + throw new Error( + "RFC2616 cookie '" + name + "' cannot have '" + c + "' as value", + ); + } + if (c > String.fromCharCode(0x80)) { + throw new Error( + "RFC2616 cookie '" + name + "' can only have US-ASCII chars as value" + + c.charCodeAt(0).toString(16), + ); + } + } +} + +/** * Parse the cookies of the Server Request * @param req An object which has a `headers` property */ diff --git a/std/http/cookie_test.ts b/std/http/cookie_test.ts index bc45b2996..09d6764af 100644 --- a/std/http/cookie_test.ts +++ b/std/http/cookie_test.ts @@ -66,6 +66,44 @@ Deno.test({ }); Deno.test({ + name: "Cookie Value Validation", + fn(): void { + const res: Response = {}; + const tokens = [ + "1f\tWa", + "\t", + "1f Wa", + "1f;Wa", + '"1fWa', + "1f\\Wa", + '1f"Wa', + '"', + "1fWa\u0005", + "1f\u0091Wa", + ]; + res.headers = new Headers(); + tokens.forEach((value) => { + assertThrows( + (): void => { + setCookie( + res, + { + name: "Space", + value, + httpOnly: true, + secure: true, + maxAge: 3, + }, + ); + }, + Error, + "RFC2616 cookie 'Space'", + ); + }); + }, +}); + +Deno.test({ name: "Cookie Path Validation", fn(): void { const res: Response = {}; |