Most of the time scripts come from other places than web site itself. These scripts are allowed to operate on the page and usually there’s some mechanism in place to control their behavior. You can think of it as a sand box – each web site runs pretty much independently. This also means that one site opened in a tab of browser isn’t allowed to access data from another site in a tab next to it. So, in theory Cross-Site Script (or XSS) is basically a violation of this principle. And it’s much worse in practice.
Let’s get back to example from Mutillidae. It’s «A7 – Cross Site Scripting (XSS)» > «Reflected (First Order)» > «DNS Lookup». It’s a basic dns lookup request page and we can type anything there. Form doesn’t check if we type a domain name or a number or whatever. So, let’s add some script to the form:
We can run it and see our session ID. Nice.
This is the core idea of XSS – we have found a way to insert a malicious script to the place where it is not supposed to be.
There are 2 different types of XSS – stored and reflected. In fact, there are 2+1 types. And we’ll start with this +1.
It’s called DOM-XSS. DOM is short for Document Object Model. This time your script never really goes to the server but stays in the web page the whole time.
In Mutilidae there’s an example «A7 – Cross Site Scripting (XSS)» > «DOM-Based» > «HTML5 Web Storage»
<H2> I can see you</h2>
This will break the page because whatever typed is incorporated to the page without checking. But we have to remember – the main point here is that it stays in the browser all the time.
In reflected XSS the malicious code actually travels to the server, embeds itself into website code, then the page goes back to user and browser runs legitimate code alongside with the malicious code. Let’s look at this example again «A7 – Cross Site Scripting (XSS)» > «Reflected (First Order)» > «DNS Lookup» but this time let’s intercept a communication between browser and server with ZAP.
Our request looks like this:
We can see the target_host parameter that contains our script. And here goes our script in the response:
You can see that our script is now a part of a web page, so it’s executed as a valid part of the code. Our script was reflected back to us, this is why it’s called reflected XSS.
Stored XSS works a little bit different. This time our malicious script will actually be stored on the server and pulled from a web page by a user even if he is not aware of it. Let’s look at the example at «A7 – Cross Site Scripting (XSS)» > «Persistent (Second Order)» > «Add to your blog».
It’s a simple blog form, or forum or guest book (I wonder if they exist by now?). Everybody sees that’s on the page, so our goal is to add something here, so it will be automatically executed as soon as the page loads.
Let’s type or script here:
Now it’s stored right in the database with all the rest entries for this blog. And from now on each time anyone opens the page, then our script executes. This type of XSS is especially devastating because someone could plant malicious code to a very popular page and collect data from every visitor. In real life malicious script doesn’t display an alert box, instead it sends stolen data to a thridparty web server. Stored XSS can operate many months before being discovered. If ever hear about mass cookie stealing from a popular web resource, chances are that it was a stored XSS on a page.