In the first post about XSS, we took a look at the basics of it and analyzed its most simple form. Now it’s time to dig deeper.
This category is a bit more sophisticated than the previous one. It is referred to as “persistent cross site scripting.” The difference from the reflected type is that this persists across request-response cycles making it a much more useful vulnerability for a hacker. The simplest example is a comments page. You can post your own comments and read what others have to say. Let’s take a look.
It all begins with a new comment. A hacker comes along and submits a malicious comment to the server. Upon receiving it, the server will insert it to its database. If a client wants to look at the comments the server will load them and insert it to the page’s source unencoded. You can guess what happens next: the browser parses the response and executes the malicious code inside it. Boom…
The two categories look very similar. The devil is in the details, let’s take a look.
The attack consists of the same two phases discussed above. The major difference here is that they are not constrained to a single request-response cycle. In fact, the injection phase is usually carried out by the hacker and victims only experience the exploitation. The attacker can inject the payload to the database once using a single request and infect multiple clients without the need to directly communicate with them. Once the payload is injected it will be delivered to every victim visiting the comments page from then on. This is a huge win for the hacker as this makes the attack much more scalable.
As you have seen, the capabilities are the same (both achieve malicious code execution in the browser), however a persistent XSS is a lot more useful for an attacker.
DOM based XSS
The very first thing you should notice is that this type of injection does not involve a vulnerable server, it requires vulnerable client side code. Injection as well as exploitation happens client side without the need for a request-response cycle. To exploit the simple example above, the victim must type in the payload to the input to trigger an update. The vulnerable update code will fetch the input’s value and assign it directly without any escaping to the live-preview’s content. Once the content is set the browser will parse it and boom, you know the drill.
Okay, so this looks pretty useless. It seems the hacker needs direct user interaction to trigger this vulnerability… unless he does not. The principal here is that unvalidated input is injected directly into the DOM without proper encoding. The malicious payload can come from a number of sources, say the url of the page (this looks very similar to the reflected case). Or even more exotic ones, like a postMessage’s payload. So no, direct user interaction is not a requirement, I only used it as an example.
Note that everything is happening client side and it is possible for the malicious payload to never hit the backend, making it nearly impossible to detect this server side, not to mention mitigate. These properties make this type of attack extremely useful for hackers.
A short note on types
The above three types are the most commonly used, however as I mentioned in the beginning of the post there is another categorization which is starting to get traction among security professionals. Here the an image summarizing it, from the OWASP website:
The idea is rather simple. Let’s take two orthogonal properties of XSS: its persistence and the point of injection and create a matrix out of it. This makes it a lot easier to reason about the vulnerability, you can read more about this at the OWASP website.
Now we are all clear on the technical parts. In part 3, we’ll cover impact and countermeasures of XSS.
This article originally appeared on the Emarsys Craftlab blog.