Anatomy of Cookie XSS

A cross-site scripting vulnerability (shortened to XSS, because CSS already means other things) occurs when a website can be tricked into showing a visitor unsafe content that came from another site visitor. Typically when we talk about an XSS attack, we’re talking about tricking a website into sending Javascript code to the user: that Javascript code can then be used to steal cookies and credentials, vandalise content, and more.

Good web developers know to sanitise input – making anything given to their pages by a user safe before ever displaying it on a page – but even the best can forget quite how many things really are “user input”.

"Who Am I?" page provided by University of Oxford IT Services.
This page outputs a variety of your inputs right back at you.

Recently, I reported a vulnerability in a the University of Oxford’s IT Services‘ web pages that’s a great example of this.  The page (which isn’t accessible from the public Internet, and now fixed) is designed to help network users diagnose problems. When you connect to it, it tells you a lot of information about your connection: what browser you’re using, your reverse DNS lookup and IP address, etc.. The developer clearly understood that XSS was a risk, because if you pass a query string to the page, it’s escaped before it’s returned back to you. But unfortunately, the developer didn’t consider the fact that virtually anything given to you by the browser can’t be trusted.

My Perl program, injecting XSS code into the user's cookie and then redirecting them.
To demonstrate this vulnerability, I had the option of writing Perl or Javascript. For some reason, I chose Perl.

In this case, I noticed that the page would output any cookies that you had from the domain, without escaping them. cookies can be manipulated by anybody who has access to write pages on the domain, which – thanks to the webspace – means any staff or students at the University (or, in an escalation attack, anybody’s who’s already compromised the account of any staff member or student). The attacker can then set up a web page that sets up such a “poisoned” cookie and then redirects the user to the affected page and from there, do whatever they want. In my case, I experimented with showing a fake single sign-on login page, almost indistinguishable from the real thing (it even has a legitimate-looking domain name served over a HTTPS connection, padlock and all). At this stage, a real attacker could use a spear phishing scam to trick users into clicking a link to their page and start stealing credentials.

A fake SSO login page, delivered from a legitimate-looking https URL.
The padlock, the HTTPS url, and the convincing form make this page look legitimate. But it’s actually spoofed.

I’m sure that I didn’t need to explain why XSS vulnerabilities are dangerous. But I wanted to remind you all that truly anything that comes from the user’s web browser, even if you think that you probably put it there yourself, can’t be trusted. When you’re defending against XSS attacks, your aim isn’t just to sanitise obvious user input like GET and POST parameters but also anything that comes from a browser header including cookies and referer headers, especially if your domain name carries websites managed by many different people. In an ideal world, Content Security Policy would mitigate all these kinds of attacks: but in our real world – sanitise those inputs!

× × ×


  1. My son has explained cookies to me more than once and I still don’t understand it! The only cookies I know are the ones I bake and the ones I buy!

    Walmart cakes and cookies have changed this passed year-they taste more natural! They got rid of that chemical taste they used to have!

    1. Dan Q Dan Q says:

      Let me try to help with an analogy that I use when I’m teaching people about the Web. A cookie… is like a visitor ID badge.

      There are lots of buildings that, if you visit, will give you a temporary visitor ID card or badge. Mine does! Often, they’ll look like this: just a badge with a number on it; they’ll just it to check that you’re allowed to be on the premises. Now in Web City, most of the buildings will give you a visitor badge and expect you to wear it: even if they let anybody visit most of the offices (which is pretty common – most websites are at least mostly open to the public without logging in), you’ll often still be given a visitor badge. This is your cookie.

      In Web City, most visitor badges just have a number on them, rather than your name. Why? Because just like in the real world, visitor passes are really easy to forge (in fact, they’re actually easier to forge: you could type anything you want onto your visitor badge). There are countermeasures to this, but for the most part it’s true to say that when you get a visitor pass in Web City, it just has a number on it. So when you come to Reddit for the first time you get a visitor pass with a long random number on it, even if you’re just browsing anonymouslu and you’re not logging in.

      That’s important, because it means that the owners of the building can, if they want, track you around their building. For instance, whenever you visit somebody’s office in that building, the occupant of that office can record the number on your visitor pass along with the date and time and what you asked about when you were there. And later, the building owners can read all of these logs to work out what you did while you were in their building, or they can amalgamate statistics from all of their visitors to spot trends: the people on the Amazon building might notice that people who put lots of expensive things in their basket are more likely to be “window shopping” and will never make it to the checkout, for example. And most people keep their visitor passes until their next visit, too, so it’s also possible to spot longer term trends about how people come and go – even though they’re “anonymous” the fact that you’ve given them each a unique number makes them not-anonymous, merely unidentified!

      You can throw away your visitor pass, of course (this is called “clearing your cookies”, especially if you throw away all of them at once). Some people are set up to automatically throw away their visitor passes as soon as they don’t need them any more, for example (this is approximately what Incognito Mode/Private Browsing does with cookies). But you’ll usually just get given another one seconds later if you’re still in the building. Throw out your Reddit visitor pass abs you’ll get a fresh one (with a new number) the very best time you do anything in the Reddit building.

      One of the most important uses for visitor passes/cookies is authentication: proving you are who you say you are. The /r/MegaLounge office in the Reddit building has a “guest list”, for example, of people who are allowed in (incidentally, so does your message inbox, although it’s a guest list of one!). So how does the guard at the entrance of /r/MegaLounge know who to let in? Here’s how: in the Reddit building, you always have the option of going to the Log In Office and proving your identity by telling them your username and password. If this convinces the staff there that you are week you claim to be, they make a record in their list of (a) your username, and (b) the number on your visitor badge. This list is shared with the security guards around the building (including the one that guards /r/MegaLounge), so when you turn up they can look at your visitor badge and cross-reference it against the list maintained by the Log In Office to work out who you are. Then they can check that name against the guest list to see if you’re allowed in. Simple!

      The thing you’ll note is odd (compared to most real world visitor badges) is that the folks in the Log In Office don’t change what’s written on your visitor badge! When a guard wants to know who you are, they don’t read it from your badge: they read the number from your badge and then look up whether that number has recently been worn by somebody who proved their identity to the Log In Office. There are a few reasons for this: firstly, there’s the forgery issue – if all I have to do is write “/u/Greypo” on my badge with a crayon and then be able to pretend to be him, that’s no use! Secondly, there’s a size limit on visitor badges, and the more you put on them the more cumbersome they are (nobody wants a visitor badge that they have to drag around!). Putting a really big random number on the cards solves these problems. Sure: you could change the number on your card, but it’d take millions of billions of guesses before you picked one that already belonged to somebody else (and even then, it probably won’t be so you were aiming to impersonate!).

      (There’s a slight weakness in the analogy at this point, because some buildings in Web City do put everything in plain view on the card – making the lives of their guards easier – but then use cryptography to maybe it hard to forge changes without getting caught.)

      So that’s the essentials of the analogy: cookies are like randomly numbered visitor passes that are given out freely and can be changed (or disposed of) freely by the person wearing them, but they’re still a safe way to identify people because the ID numbers are give and security staff keep a separate log of which badge numbers correspond to which people.

      (I like this analogy because it extends well, too: if you’re interested in the major privacy and security concerns about cookies, I can explain them in the framework of this model too – just shout!)

      1. That’s a brilliant analogy!

      2. Thank you! By putting it that way as offices and buildings, I finally understand it! Just one more question for now…Why do they call it cookies? Is it because ‘the badge’ leaves crumbs (info) wherever you go?

        1. Dan Q Dan Q says:

          Probably not: but nobody knows for certain (which is mind-boggling to me, given that the field of computer science is relatively new). Let me tell you what we do know:

          Cookies on the web, more-correctly known as HTTP Cookies, are a specific type of cookie, but cookies for this purpose predate the web. They’re almost certainly named after Magic Cookies, which are a more-general computer science concept but fundamentally similar: a piece of data that gets passed backwards and forwards in order to identify the processes at one or both ends of a connection. From there, the trail gets colder: it’s possible that Magic Cookies take their name from the “cookies” that represented the end goal of compilation in some C compilers, as hinted at here (these, in turn, were probably so-named because when you’ve achieved something… you probably deserve a cookie). Or it may be related to a particular class of early malware and/or hacking tools that saturated your connection with “I WANT A COOKIE” messages until you typed “COOKIE” back to it, which were in turn related to Sesame Street’s Cookie Monster, although this article suggests that the term predates Sesame Street and relates instead to a 1960s cereal with a “cookie bear” mascot. Or it might relate to the term “cookie jar”, which some operating systems use internally to refer to the location in which configuration data are stored (although I can’t find any evidence that this was the case prior to the earliest uses of the term “magic cookie”). Some folks claim that it’s a reference to cookies in a 1976 computer game called Colossal Cave Adventure (or more-often Colossal Cave or just Adventure), although it’s certainly the case that no contemporary version of the game contains any mention of cookies. Other folks claim that it’s somehow related to fortune cookies.

          In short, we don’t know. But it’s probably got nothing to do with a “crumb” metaphor, as HTTP cookies don’t by-themselves leave any information where they’ve been (and earliler magic cookies even less-so).

          1. Thank you so much for this! You’re so sweet taking time out of your busy life to explain all this to me! :~)

Reply here

Your email address will not be published. Required fields are marked *

Reply on your own site

Reply by email

I'd love to hear what you think. Send an email to; be sure to let me know if you're happy for your comment to appear on the Web!