summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--std/http/cookie.ts14
-rw-r--r--std/http/cookie_test.ts36
2 files changed, 49 insertions, 1 deletions
diff --git a/std/http/cookie.ts b/std/http/cookie.ts
index 75d70f74e..f8025d328 100644
--- a/std/http/cookie.ts
+++ b/std/http/cookie.ts
@@ -32,11 +32,14 @@ export interface Cookie {
export type SameSite = "Strict" | "Lax" | "None";
+const FIELD_CONTENT_REGEXP = /^(?=[\x20-\x7E]*$)[^()@<>,;:\\"\[\]?={}\s]+$/;
+
function toString(cookie: Cookie): string {
if (!cookie.name) {
return "";
}
const out: string[] = [];
+ validateCookieName(cookie.name);
out.push(`${cookie.name}=${cookie.value}`);
// Fallback for invalid Set-Cookie
@@ -80,6 +83,17 @@ function toString(cookie: Cookie): string {
}
/**
+ * Validate Cookie property.
+ * @param key Name of the cookie.
+ * @param value Value of the cookie.
+ */
+function validateCookieName(value: string | undefined | null): void {
+ if (value && !FIELD_CONTENT_REGEXP.test(value)) {
+ throw new TypeError(`Invalid cookie name: "${value}".`);
+ }
+}
+
+/**
* 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 0f7c68635..0f42a9381 100644
--- a/std/http/cookie_test.ts
+++ b/std/http/cookie_test.ts
@@ -1,7 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { Response, ServerRequest } from "./server.ts";
import { deleteCookie, getCookies, setCookie } from "./cookie.ts";
-import { assert, assertEquals } from "../testing/asserts.ts";
+import { assert, assertEquals, assertThrows } from "../testing/asserts.ts";
Deno.test({
name: "Cookie parser",
@@ -32,6 +32,40 @@ Deno.test({
});
Deno.test({
+ name: "Cookie Name Validation",
+ fn(): void {
+ const res: Response = {};
+ const tokens = [
+ '"id"',
+ "id\t",
+ "i\td",
+ "i d",
+ "i;d",
+ "{id}",
+ "[id]",
+ '"',
+ "id\u0091",
+ ];
+ res.headers = new Headers();
+ tokens.forEach((name) => {
+ assertThrows(
+ (): void => {
+ setCookie(res, {
+ name,
+ value: "Cat",
+ httpOnly: true,
+ secure: true,
+ maxAge: 3,
+ });
+ },
+ Error,
+ 'Invalid cookie name: "' + name + '".',
+ );
+ });
+ },
+});
+
+Deno.test({
name: "Cookie Delete",
fn(): void {
const res: Response = {};