Skip to content
Permalink
Browse files
Add Set-Cookie as a forbidden header name
https://bugs.webkit.org/show_bug.cgi?id=241703
<rdar://95811508>

Reviewed by J Pascoe.

Added Set-Cookie as a forbidden request header.
whatwg/fetch#1453

* LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/request-forbidden-headers.any-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/request-forbidden-headers.any.js:
* LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/request-forbidden-headers.any.worker-expected.txt:
* Source/WebCore/platform/network/HTTPParsers.cpp:
(WebCore::isForbiddenHeaderName):
* LayoutTests/http/tests/cookies/cookie-with-multiple-level-path.html:
* LayoutTests/http/tests/cookies/resources/cookie-utilities.js:
* LayoutTests/http/tests/cookies/resources/cookies-test-pre.js:
(setCookies):
* LayoutTests/http/tests/cookies/resources/setCookies.cgi:
* LayoutTests/http/tests/cookies/sync-xhr-set-cookie-invalidates-cache.html:
* LayoutTests/http/tests/navigation/ping-attribute/resources/utilities.js:
(setCookie):
* LayoutTests/http/tests/security/contentSecurityPolicy/report-cross-origin-no-cookies-when-private-browsing-enabled.py:
* LayoutTests/http/tests/security/contentSecurityPolicy/report-cross-origin-no-cookies-when-private-browsing-toggled.py:
* LayoutTests/http/tests/security/contentSecurityPolicy/report-cross-origin-no-cookies.py:
* LayoutTests/http/tests/security/contentSecurityPolicy/report-same-origin-no-cookies-when-private-browsing-toggled.py:
* LayoutTests/http/tests/security/contentSecurityPolicy/report-same-origin-with-cookies-when-private-browsing-enabled.py:
* LayoutTests/http/tests/security/contentSecurityPolicy/report-same-origin-with-cookies.py:
* LayoutTests/http/tests/app-privacy-report/app-attribution-beacon-isappinitiated.html:
* LayoutTests/http/tests/app-privacy-report/app-attribution-beacon-isnotappinitiated.html:
* LayoutTests/http/tests/blink/sendbeacon/beacon-cookie.html:
* LayoutTests/http/tests/resourceLoadStatistics/delete-script-accessible-cookies.html:
* LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion-database.html:
* LayoutTests/http/tests/resourceLoadStatistics/exemptDomains/app-bound-domains-exempt-from-website-data-deletion.html:
* LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-but-cookies-not-removed-with-user-interaction-6-days-ago.html:
* LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-but-cookies-removed-with-user-interaction-7-days-ago.html:
* LayoutTests/http/tests/resourceLoadStatistics/operating-dates-all-website-data-removed.html:
* LayoutTests/http/tests/resourceLoadStatistics/standalone-web-application-exempt-from-website-data-deletion.html:
* LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration-js-cookie-checking.html:
* LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-navigated-to-with-link-decoration.html:
* LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-with-user-interaction.html:
* LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-without-user-interaction-js-cookie-checking.html:
* LayoutTests/http/tests/resourceLoadStatistics/website-data-removal-for-site-without-user-interaction.html:

Canonical link: https://commits.webkit.org/253325@main
  • Loading branch information
charliewolfe authored and pascoej committed Aug 11, 2022
1 parent 6c79952 commit 593162b00deb43c8f03cbf3b5471e0ddf3130155
Show file tree
Hide file tree
Showing 31 changed files with 33 additions and 29 deletions.
@@ -35,7 +35,7 @@
try {
var xhr = new XMLHttpRequest();
xhr.open("GET", "../cookies/resources/setCookies.cgi", false);
xhr.setRequestHeader("SET-COOKIE", "hello=world;path=/");
xhr.setRequestHeader("X-SET-COOKIE", "hello=world;path=/");
xhr.send(null);
if (xhr.status != 200) {
testFailed("cookie not set");
@@ -35,7 +35,7 @@
try {
var xhr = new XMLHttpRequest();
xhr.open("GET", "../cookies/resources/setCookies.cgi", false);
xhr.setRequestHeader("SET-COOKIE", "hello=world;path=/");
xhr.setRequestHeader("X-SET-COOKIE", "hello=world;path=/");
xhr.send(null);
if (xhr.status != 200) {
testFailed("cookie not set");
@@ -16,7 +16,7 @@
try {
var xhr = new XMLHttpRequest();
xhr.open("GET", "../../cookies/resources/setCookies.cgi", false);
xhr.setRequestHeader("SET-COOKIE", "hello=world;path=/");
xhr.setRequestHeader("X-SET-COOKIE", "hello=world;path=/");
xhr.send(null);
if (xhr.status != 200) {
testFailed("cookie not set");
@@ -45,7 +45,7 @@
const url = '/cookies/resources/setCookies.cgi';
const cookie = prepareCookieHeader(name, value, path, 60);

return fetch(url, {headers: {"Set-Cookie": cookie}});
return fetch(url, {headers: {"X-Set-Cookie": cookie}});
}

function prepareCookieHeader(name, value, path, maxAge = 30) {
@@ -51,7 +51,7 @@ async function setCookie(name, value, additionalProperties={})
let promise = new Promise((resolved, rejected) => {
let xhr = new XMLHttpRequest;
xhr.open("GET", "/cookies/resources/setCookies.cgi");
xhr.setRequestHeader("SET-COOKIE", cookie);
xhr.setRequestHeader("X-SET-COOKIE", cookie);
xhr.onload = () => resolved(xhr.responseText);
xhr.onerror = rejected;
xhr.send(null);
@@ -10,7 +10,7 @@ function setCookies(cookie)
try {
var xhr = new XMLHttpRequest();
xhr.open("GET", "resources/setCookies.cgi", false);
xhr.setRequestHeader("SET-COOKIE", cookie);
xhr.setRequestHeader("X-SET-COOKIE", cookie);
xhr.send(null);
if (xhr.status == 200) {
// This is to clear them later.
@@ -3,9 +3,9 @@ use strict;

print "Content-Type: text/plain\n";
print "Access-Control-Allow-Origin: *\n";
print "Access-Control-Allow-Headers: SET-COOKIE\n";
print "Access-Control-Allow-Headers: X-SET-COOKIE\n";
print "Cache-Control: no-store\n";
print 'Cache-Control: no-cache="set-cookie"' . "\n";

# We only map the SET_COOKIE request header to "Set-Cookie"
print "Set-Cookie: " . $ENV{"HTTP_SET_COOKIE"} . "\n\n";
# We only map the X-SET_COOKIE request header to "Set-Cookie"
print "Set-Cookie: " . $ENV{"HTTP_X_SET_COOKIE"} . "\n\n";
@@ -9,7 +9,7 @@
var xhr = new XMLHttpRequest();
xhr.open('GET', 'resources/setCookies.cgi', false);
var cookie = 'xhrKey=xhrValue; path=/';
xhr.setRequestHeader('SET-COOKIE', cookie);
xhr.setRequestHeader('X-SET-COOKIE', cookie);
xhr.send();

// This is so the cookie gets removed at the end of the test.
@@ -3,7 +3,7 @@ function setCookie()
try {
var xhr = new XMLHttpRequest;
xhr.open("GET", "../../cookies/resources/setCookies.cgi", false);
xhr.setRequestHeader("SET-COOKIE", "hello=world;path=/");
xhr.setRequestHeader("X-SET-COOKIE", "hello=world;path=/");
xhr.send(null);
if (xhr.status != 200) {
document.getElementsByTagName("body")[0].appendChild(document.createTextNode("FAILED: cookie not set"));
@@ -54,7 +54,7 @@
return;
}
await fetch("/cookies/resources/set-http-only-cookie.py?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "X-Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
document.cookie = clientSideCookieName + "=1";
checkCookies(false);
testRunner.statisticsDeleteCookiesForHost("http://127.0.0.1", false);
@@ -196,7 +196,7 @@
async function writeWebsiteDataAndContinue() {
// Write cookies.
await fetch("/cookies/resources/set-http-only-cookie.py?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "X-Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
document.cookie = clientSideCookieName + "=1";

checkCookies(false);
@@ -196,7 +196,7 @@
async function writeWebsiteDataAndContinue() {
// Write cookies.
await fetch("/cookies/resources/set-http-only-cookie.py?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "X-Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
document.cookie = clientSideCookieName + "=1";

checkCookies(false);
@@ -195,7 +195,7 @@
async function writeWebsiteDataAndContinue() {
// Write cookies.
await fetch("/cookies/resources/set-http-only-cookie.py?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "X-Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
document.cookie = clientSideCookieName + "=1";

checkCookies(false);
@@ -195,7 +195,7 @@
async function writeWebsiteDataAndContinue() {
// Write cookies.
await fetch("/cookies/resources/set-http-only-cookie.py?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "X-Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
document.cookie = clientSideCookieName + "=1";

checkCookies(false);
@@ -195,7 +195,7 @@
async function writeWebsiteDataAndContinue() {
// Write cookies.
await fetch("/cookies/resources/set-http-only-cookie.py?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "X-Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
document.cookie = clientSideCookieName + "=1";

checkCookies(false);
@@ -197,7 +197,7 @@
async function writeWebsiteDataAndContinue() {
// Write cookies.
await fetch("/cookies/resources/set-http-only-cookie.py?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "X-Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
document.cookie = clientSideCookieName + "=1";

checkCookies(false);
@@ -200,7 +200,7 @@
async function writeWebsiteDataAndContinue() {
// Write cookies.
await fetch("/cookies/resources/set-http-only-cookie.py?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "X-Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
document.cookie = clientSideCookieName + "=1";

checkCookies(false);
@@ -196,7 +196,7 @@
async function writeWebsiteDataAndContinue() {
// Write cookies.
await fetch("/cookies/resources/set-http-only-cookie.py?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "X-Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
document.cookie = clientSideCookieName + "=1";

checkCookies(false);
@@ -196,7 +196,7 @@
async function writeWebsiteDataAndContinue() {
// Write cookies.
await fetch("/cookies/resources/set-http-only-cookie.py?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "X-Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
document.cookie = clientSideCookieName + "=1";

checkCookies(false);
@@ -200,7 +200,7 @@
async function writeWebsiteDataAndContinue() {
// Write cookies.
await fetch("/cookies/resources/set-http-only-cookie.py?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "X-Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
document.cookie = clientSideCookieName + "=1";

checkCookies(false);
@@ -196,7 +196,7 @@
async function writeWebsiteDataAndContinue() {
// Write cookies.
await fetch("/cookies/resources/set-http-only-cookie.py?cookieName=" + httpOnlyCookieName, { credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
await fetch("/cookies/resources/setCookies.cgi", { headers: { "X-Set-Cookie": serverSideCookieName + "=1; path=/;" }, credentials: "same-origin" });
document.cookie = clientSideCookieName + "=1";

checkCookies(false);
@@ -18,7 +18,7 @@
' testRunner.setStatisticsShouldDowngradeReferrer(false, function () {\n'
' var xhr = new XMLHttpRequest();\n'
' xhr.open("GET", "http://localhost:8080/cookies/resources/setCookies.cgi", false);\n'
' xhr.setRequestHeader("SET-COOKIE", "hello=world;path=/");\n'
' xhr.setRequestHeader("X-SET-COOKIE", "hello=world;path=/");\n'
' xhr.send(null);\n'
'\n'
' // This image will generate a CSP violation report.\n'
@@ -15,7 +15,7 @@
// Normal browsing mode
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:8080/cookies/resources/setCookies.cgi", false);
xhr.setRequestHeader("SET-COOKIE", "hello=world;path=/");
xhr.setRequestHeader("X-SET-COOKIE", "hello=world;path=/");
xhr.send(null);
if (window.testRunner)
@@ -17,7 +17,7 @@
' testRunner.setStatisticsShouldDowngradeReferrer(false, function () {\n'
' var xhr = new XMLHttpRequest();\n'
' xhr.open("GET", "http://localhost:8080/cookies/resources/setCookies.cgi", false);\n'
' xhr.setRequestHeader("SET-COOKIE", "hello=world;path=/");\n'
' xhr.setRequestHeader("X-SET-COOKIE", "hello=world;path=/");\n'
' xhr.send(null);\n'
'\n'
' // This image will generate a CSP violation report.\n'
@@ -12,7 +12,7 @@
' // Normal browsing mode\n'
' var xhr = new XMLHttpRequest();\n'
' xhr.open("GET", "/cookies/resources/setCookies.cgi", false);\n'
' xhr.setRequestHeader("SET-COOKIE", "hello=world;path=/");\n'
' xhr.setRequestHeader("X-SET-COOKIE", "hello=world;path=/");\n'
' xhr.send(null);\n'
'\n'
' if (window.testRunner)\n'
@@ -12,7 +12,7 @@
'<script>\n'
' var xhr = new XMLHttpRequest();\n'
' xhr.open("GET", "/cookies/resources/setCookies.cgi", false);\n'
' xhr.setRequestHeader("SET-COOKIE", "hello=world;path=/");\n'
' xhr.setRequestHeader("X-SET-COOKIE", "hello=world;path=/");\n'
' xhr.send(null);\n'
'</script>\n'
'\n'
@@ -11,7 +11,7 @@
'<script>\n'
' var xhr = new XMLHttpRequest();\n'
' xhr.open("GET", "/cookies/resources/setCookies.cgi", false);\n'
' xhr.setRequestHeader("SET-COOKIE", "hello=world;path=/");\n'
' xhr.setRequestHeader("X-SET-COOKIE", "hello=world;path=/");\n'
' xhr.send(null);\n'
'</script>\n'
'\n'
@@ -23,4 +23,5 @@ PASS Proxy- is a forbidden request header
PASS Proxy-Test is a forbidden request header
PASS Sec- is a forbidden request header
PASS Sec-Test is a forbidden request header
PASS Set-Cookie is a forbidden request header

@@ -41,3 +41,4 @@ requestForbiddenHeaders("Proxy- is a forbidden request header", {"Proxy-": "valu
requestForbiddenHeaders("Proxy-Test is a forbidden request header", {"Proxy-Test": "value"});
requestForbiddenHeaders("Sec- is a forbidden request header", {"Sec-": "value"});
requestForbiddenHeaders("Sec-Test is a forbidden request header", {"Sec-Test": "value"});
requestForbiddenHeaders("Set-Cookie is a forbidden request header", {"Set-Cookie": "cookie=none"});
@@ -23,4 +23,5 @@ PASS Proxy- is a forbidden request header
PASS Proxy-Test is a forbidden request header
PASS Sec- is a forbidden request header
PASS Sec-Test is a forbidden request header
PASS Set-Cookie is a forbidden request header

@@ -867,6 +867,7 @@ bool isForbiddenHeaderName(const String& name)
case HTTPHeaderName::KeepAlive:
case HTTPHeaderName::Origin:
case HTTPHeaderName::Referer:
case HTTPHeaderName::SetCookie:
case HTTPHeaderName::TE:
case HTTPHeaderName::Trailer:
case HTTPHeaderName::TransferEncoding:

0 comments on commit 593162b

Please sign in to comment.