Cookies are a major place for security in the browser. They can hold secrets via the HTTPOnly place, can only be sent over HTTPs via the Secure flag and help to prevent CSRF via the SameSite flag. We always assume that cookies operate correctly. There are many fields in a cookie, such as the path, expire time, host and more. However, when we have specific primitives, we can cause massive damage when cookies aren't being handled as they should.
The authors of this paper consider a few different scenarios. First, a same site attacker from our a sub-domain takeover, bad site design or XSS. The second, is the same but without an HTTPs/TLS connection. The final attacker they consider is a user with full control over the cleartext traffic being sent back via a MitM attack. These specific roles are important, as they grant the user access to specific abilities in the browser.
There are some old-school techniques to talk about. First, cookie tossing. Only the first cookie sent in the request of a particular name is parsed by most web servers. So, how are cookies of the same name ordered? First, it's sorted by path then creation time. If an attacker can set a cookie on one domain with a value with a more specific path, then it will get parsed first! For the double submit CSRF pattern, this is a devastating attack. Second, the cookie jar has a limit on FF and Chrome of 180 per schemeful site with oldest cookies getting kicked out. So, an attacker can set a ton of cookies to boot out even HTTPOnly cookies.
Nameless cookies are a cookie with a value but not a name, which was added to the specification in 2020 because many servers were doing this anyway. However, as cookies are just strings, the security implications of concatenating regular cookies with nameless cookies was NOT considered. When taking a nameless cookie like =sid=evil; it would be parsed as sid=evil;. This could even be used to bypass the host cookie and secure cookies from an insecure origin. Firefox and Chrome followed the standard to the tee, resulting in CVEs on their side. The solution was to drop nameless cookies that beginning with __Host or __Secure.
They decided to see how cookies were being parsed on the server-side. Since there wasn't a set standard on this, many browsers and servers differ in this aspect. For instance, in PHP, all dots, spaces and square brackets are rewritten to be underscores instead. So, an attacker can spoof a secure or host only cookie by doing ..Host-sid=evil, which will be translated into __Host-sid=evil. ReactPHP URL decoded the cookie name, causing a similar type of issue. Wekzeug, which is used by Flask, and API gateway from AWS, removed leading equal signs leading to the same issue as before.
FireFox had an issue that desyncs the actual cookies being sent versus what was returned by the Document.cookie API. Since HTTP headers, like CSRF tokens, often use cookies, this could create an issue. To find these types of issues, they reviewed the cookie standard thoroughly then tested both browsers and server parsing. Discrepancies would cause interesting desync issues like mentioned above.
Cookie fixation is a method is setting a cookie as an attacker then having this value be used for the service down the road. For session cookies and CSRF protections, this can be real bad, as an attacker would know a secret value to bypass protections. They found that many frameworks would use a CSRF token set as a cookie on the site prior to login would also use it while authenticated. They found that Express/Koa/Fastify in the NodeJS stack, Symfony, Flask and CodeIgniter4 were vulnerable to this fixation issue.
They found that Passport, Fastify and Sails frameworks were vulnerable to trivial session fixation vulnerabilities by simply setting the session cookie prior to login. Yikes! That's an easy account takeover. Overall, an amazing set of tricks and things to keep in mind when trying to escalate XSS on a crappy domain or a sub domain takeover. Both old and new things were presented which was awesome.