There is a well-known Google XSS game (https://xss-game.appspot.com/) that allows you to learn how to find and exploit XSS bugs. The advance to the next level occurs after the user injects a script to pop up a JavaScript alert()
.
Previously, the advance to the next level did not cause problems, but now something seems to be broken in this game because even after the alert is displayed on the screen, the following message appears when you try to move next:
Based on your browser cookies it seems like you haven't passed the previous level of the game. Please go back to the previous level and complete the challenge.
Let's try to figure out what's going on.
The source code (game.js, lines 11-24
) of the site shows that the following code is responsible for moving to the next level:
function levelSolved() {
if (!userOpenedAlert) {
return;
}
var oReq = new XMLHttpRequest();
oReq.onload = function () {
if (oReq.readyState != 4) return;
document.getElementById('next-controls').style.display = "block";
eval(oReq.responseText);
};
oReq.open("GET", window.location.toString() '/record', true);
oReq.send();
}
Request https://xss-game.appspot.com/level1/record
looks like this:
General:
Request URL: https://xss-game.appspot.com/level1/record
Request Method: GET
Status Code: 200
Referrer Policy: strict-origin-when-cross-origin
Response Headers:
alt-svc: h3=":443"; ma=2592000
cache-control: no-cache
content-length: 0
content-type: text/html; charset=utf-8
date: Wed, 31 Aug 2022 18:14:26 GMT
expires: Wed, 31 Aug 2022 18:14:26 GMT
server: Google Frontend
set-cookie: level1=f148716ef4ed1ba0f192cde4618f8dc5; Path=/; Expires=Wed, 22 Jul 2022 12:34:56 GMT; HttpOnly
x-cloud-trace-context: 31ad2e6a5cdd8b63c39bad66e783535b;o=1
Request Headers:
:authority: xss-game.appspot.com
:method: GET
:path: /level1/record
:scheme: https
accept: text/html,application/xhtml xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding: gzip, deflate, br
accept-language: q=0.9,en-US;q=0.8,en;q=0.7
sec-ch-ua: "Chromium";v="104", " Not A;Brand";v="99", "Google Chrome";v="104"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: none
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36
So, as you can see, there is the Set-Cookie
response header that should set the cookie. If set this cookie manually by the browser, then everything starts working normally, and the advance to the next level happens without problems.
The question actually is why the Set-Cookie
header does not work in this case? The request is not cross-origin, and you can even execute it not as an XMLHttpRequest
, but as a regular GET
request, but this does not work anyway.
Let's help Google to fix this game ;)
CodePudding user response:
The server sends Expires=Wed, 22 Jul 2022 12:34:56 GMT
within the cookie. So there are no reasons to set this already expired cookie