Cross Site Scripting(XSS) is a type of vulnerability that allows an attacker to put their own, malicious, javascript into a trusted website. It is a client side attack which means that although the vulnerability is in the website, it targets the users of the site. It is most commonly seen when a users input is shown to other users. The “stored” part simply means that the code is permanently stored on the website’s servers. XSS is dangerous because at best it allows the attacker to run some novel code on a victim’s computer but it can also lead to serious attacks such as session hijacking, where the attacker steals a user(usually the admin)’s cookies and uses those to log in as them.

DVWA shows this vulnerability by a basic guestbook application, the user enters a name and a message and it will be publicly displayed. This seems like a fairly innocent webapp however, it is vulnerable to XSS.

Low Security

On low security, DVWA has no protection against XSS, any input will be accepted and stored. The only protection on low security is the name field being limited to 10 characters which means there is very little opportunity for XSS, however, this limit is client side so it can be easily bypassed but I’ll come back to that later.

XSS is most commonly done by including script tags in an input. If we submit the following comment:


You would expect the user to see exactly that message but when a web browser processes the web page, it reads that message as javascript. That means that when we load the web page to view our new message, we see this popup:


Medium Security

This time, DVWA has a bit of protection against XSS. If the same message used for low security is sent again, the message ends up like this:


This means that DVWA is removing all html tags from the input and escaping quotes. This stops the web browser from thinking the code is javascript so it will not be run.

DVWA escapes script tags in the message but does it escape them in the name? Well, it turns out the input for name is limited to 10 characters which means it’s difficult to write any javascript in there because just the script tages take up 15 characters. Fortunately, this limit is client side so we can remove it using inspect element.

Changing the maxlength attribute to 100 is more than enough to include an XSS attack in the name.

When this message is submitted, you would expect it to function exactly the same as last time. However, the comment is shown like this:

This means the developer is removing script tags from the name input. The script tags have been removed instead of being sanitised, this means the developer is likely using a find and replace to remove the script tags. Assuming it is just a simple find and replace, doing something to make the input unique will avoid it. In this case, changing the case of some letters will avoid the find and replace.

When this message is submitted, it will bypass the XSS filter because it is only looking for <script> and not <Script>. This happens because web browsers are made to process any bad input so whilst the script tag should be lowercase, it will still accept one with upper case however the find replace is only looking for lower case script tags.

When the website loads, we see the message box which proves the XSS has worked.

High Security

On high security, this is much harder to exploit. Using similar input to medium security gives an unexpected result.

Whilst its obviously not XSS, it isn’t anywhere near what a good XSS filter would show. Because its left one angle bracket at the end, it appears to be removing instances of the word script and everything between them. If we can include html, we can include XSS even if it’s not using script tags. The following input is simply a test to see if html can be included:

My name is in bold here which means the html has been included, this means it is possible to include XSS. Luckily, javascript can be included in other html elements, its usually used to call a function when something is clicked, loaded or any other event occurs. To get around this filter, there are loads of different XSS vectors that can be used but I will use an invalid img tag and put javascript in the onerror attribute.

When this is loaded by the browser, it will try and fail to load an image from x causing it to run the javascript code in onerror.

When the page loads, the name appears as an invalid image and a popup appears which proves that XSS happened.

Mitigating XSS

XSS can be mitigated by proper input sanitising. This can be done manually by, for example using htmlspecialchars after stripslashes in php(this is DVWA’s impossible level – it is completely secure), however, there are lots of ways it can go wrong depending on the context of the input so it is recommended to use an encoding library such as Zend Escaper to prevent XSS. If you still want to try and prevent it manually, OWASP provide a set of rules to follow to filter XSS.

DVWA is easy to set up and is definitely worth using to test your skills. In the next few weeks, I will explain more of the vulnerabilities in DVWA.

Leave a Comment

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