Cross-site requests do not include same-site cookies, but what happens if such a request leads to a redirection within the target site?
I tested this with the following Node.js express app running on https://site-a.com
:
app.get("/a", function(req, res) {
res.cookie("a", "b", {sameSite: "strict", secure: true, httpOnly: true});
res.end();
})
.get("/b", function(req, res) {
res.end(req.get("Cookie"));
})
.get("/c", function(req, res) {
res.redirect("/b");
})
.get("/d", function(req, res) {
res.send(`<!DOCTYPE html><html><body onl oad="location.href='/b'"></body></html>`);
});
and an HTML page https://site-b.com
that contains cross-site hyperlinks to https://site-a.com/b
, https://site-a.com/c
and https://site-a.com/d
.
I performed the following steps with Google Chrome (version 109.0.5414.75):
- Go to
https://site-a.com/a
in a browser window. This sets the same-site cookie. - Open the HTML page at
https://site-b.com
. - Clicking the
/b
link does not send the same-site cookie. - Clicking the
/c
link does not send the same-site cookie, neither with the first requestGET /c
(which leads to an HTTP redirection) nor with the second requestGET /b
that results from the redirection. - Clicking the
/d
link does not send the same-site cookie with the first requestGET /d
(which serves an HTML page), but does send it with the second requestGET /b
that results from the Javascript redirection in the HTML page.
I am surprised by the difference in behavior between steps 4 (HTTP redirection) and 5 (Javascript redirection).
CodePudding user response:
The difference is explained by criterion 3 in the definition of same-site. A same-site cookie is sent in a request whose client has the same origin as its URL. In the given example, this means that the request's client must have origin https://site-b.com
for the cookie to be sent.
- The request's client of the HTTP-redirected request in step 4 is still
https://site-a.com
, because the request's client does not change during an HTTP-redirect fetch. - The request's client of the Javascript-redirected request in step 5 is
https://site-b.com
, because an HTML page from that origin has been loaded and the second request is a second scheme fetch, not an HTTP-redirect fetch.