Tuesday, 26 March 2013

Categories of XSS

So I was reading an article recently that talked about finding XSS where the malicious script was injected via a cookie.  This got me thinking about which of the standard categories of XSS - Stored (or Persistent), Reflected (or Non-persistent) and DOM-based - that fell into.  It wasn't immediately clear as it was persistent, but stored on the client, but the fix would need to be in the JavaScript which makes it similar to DOM-based XSS.  This got me thinking about the basis for the standard categories or types of XSS.

I think the first thing to point out is that at some time in history someone, or more likely a bunch of different people, discovered XSS and thought of it as a single type of attack.  It's an interesting thought experiment to imagine you find that you can inject JavaScript into a web page, and that as far as you know no one has done it before.  I imagine I would think of it as a code injection attack, where the code just happens to be JavaScript, and the novelty would be that I proxied the attack via the web server and that the victims were other users of the web server, rather than the server itself.  Potentially I might not even think it was that interesting running arbitrary JavaScript on a client, as it wouldn't have been comparable to the usual arbitrary code execution attacks that existed already.  But then if I could have predicted how popular the web would become, and what it would be used for, well I would have <insert genius idea> and profited.

I'm going to make the completely unfounded assumption that Stored XSS was discovered first, as it's considered the more serious attack (which for now I'll state without justification) and then Reflected XSS was considered a variant type of attack, but different to Stored XSS because it required user interaction.  But really the whole user interaction thing is a fairly weak argument these days, with the proliferation of ad-networks inserting arbitrary HTML in popular websites and 'watering hole' type attacks, a user just surfin' the net is far more likely than ever to hit upon a malicious iframe that exploits a reflected XSS attack.  But granted, the user does have to be logged in to the web site so the window of opportunity for the attacker is smaller in a Reflected XSS attack.

Comparing to a Stored XSS attack, well the user is most likely already logged in to the web site so the attacker's window of opportunity is much larger, however that attacker could face a second issue, the victim still has to navigate to the page with the injected script, so the attack is location limited.  It's interesting to note that Reflected XSS is not location limited, since the attacker will direct the victim to precisely the page with the vulnerability.  But then it doesn't actually make sense to say Stored XSS is location limited if Reflected XSS isn't, because whatever vector of attack Reflected XSS can use, so can Stored XSS i.e. a malicious iframe can point to a web page with Stored XSS.

It would seem then that we should categorise XSS by the vectors of attack that can be used by an attacker to exploit a victim.

Possible types of XSS when the attacker manipulates ...
XSS Type the victim's response the victim's request the victim's DOM properties
Stored XSS Y Y N
Reflected XSS N Y N
DOM-based XSS N Y Y

So it might not be clear what I mean by "the victim's response", what I mean is that the attacker does not control the victim's request, but is able to include data of their choosing in the response to the victim's request.  This is the standard Stored XSS scenario where the data comes from the DB for instance.  However Reflected XSS isn't possible because the attacker doesn't control the request and DOM-based isn't possible because either the vulnerable DOM property is set by the server, or set by the client with data from the server.

When the attacker manipulates "the victim's request", Stored, Reflected and DOM-based XSS is possible.  Stored XSS because the attacker can direct the victim to the infected page.  Reflected XSS because the attacker controls the parameters of the request.  Finally, DOM-based XSS because the attacker can set DOM properties that aren't sent to the server e.g. fragment identifier if the attacker can specify the URL, window.name if the attacker makes a request from script.

In the case of "the victim's DOM property", what I mean is a DOM object property that is set client-side and not set by (or sent to) the server.  In this case only DOM-based is possible, as the DOM property is not set by the server so Stored or Reflected XSS isn't possible.  This is in fact a special case, or a subset, of the "the victim's request" scenario.

I've taken a fairly strict definition of DOM-based XSS here, as I think this is required to truly separate it out from Reflected XSS.  My logic is that if the malicious data comes from, or goes via, the server, then the attack can be considered to come via the server in the same way as Stored or Reflected XSS respectively, but if the malicious data never actually gets sent to the server (e.g. it's in the fragment identifier, window.name, see domxsswiki for more examples) then that is quite plainly a different attack vector.  Note that for DOM-based XSS a request still needs to be made to the server (most likely), so it shares that in common with the other attack vectors, but there is no malicious data sent as part of that request, unlike the other attack vectors.

There are other definitions of DOM-based XSS that are looser, that include any DOM property, even if coming via the server, and that's fine for most practical purposes.  For the purpose of categorisation though I think being stricter helps understand how the different attack vectors for XSS fit together.

So what about the cookie-based XSS?  Well if an attacker finds a way to set a victim's cookie such that client-side JavaScript reads the malicious cookie value resulting in code injection, I would say that the value of cookie goes via the server so that is Reflected XSS.  Whilst I think that is probably the most common scenario, I can imagine scenarios where you would call it Stored XSS and other scenarios where it would be DOM-based XSS.

So there you have it, my opinion on the different categories of XSS, some people will agree and some will disagree.  Generally speaking the security industry has settled on some loose categories of XSS, and that's fine, it's not clear we need strict category definitions, but it can be an informative exercise to consider them.

NB: I refuse to use Type-0, Type-1, or Type-2 names for the different types of XSS, they are meaningless names that only serve to confuse.