Cross site scripting (XSS) is a technique which allows the attacker to modify behaviour of visitors browser in a way he wants. It can be used to display advertisements, perform actions on behalf of the victim or steal personal information.
The easiest demonstration of such attack is simple input-echo loop in PHP:
Try to insert value
<script>alert('D\'oh')</script> into the input element and submit the form. Instead of
This behaviour is definitely not desired (you do not want your users to be able to modify functionality of your
application). Now imagine that this string is stored into a database and the message pops up to every other
visitor of your online presentation…
The important thing is that the attacker is able to execute his code on your website. He can point visitors
to your site with given
val parameter in URL using simply
<a href="http://site.com/?val=..."></a> tag.
Do not be angry at PHP that it has weak security. The
echo statement is used to output exactly what the developer
wants to output. How else would one be able to generate HTML code using PHP if the
echo statement would translate
> to substitute entities? This is similar as with SQL injection,
the code merely does what it is told to do. It is your fault that you do not see the consequences.
To overcome this issue, you have to escape dangerous characters, in this case convert
> entities. You can use PHP’s function
to achieve this. But you would have to use this function everywhere in your code. This is tedious and error prone.
To fix the code add this function to the
echo 'You entered: ' . htmlspecialchars($_GET['val']);
You were taught in the walkthrough section to use a templating engine. Such templating
engine removes the burden of remembering to use
htmlspecialchars() function everywhere because it filters those
dangerous entities automatically.
Always use this function when you output values, i.e. in templates or when using
echo. It is a nice idea to use
this function before storing values into database (you can save some computational power and make your application
faster), but you never know whether the data are going to be outputted into HTML or into another context,
> are OK for PDF or in JSON generated by REST API.
The XSS attack has different levels of severity.
This kind of attack cannot be stopped with backend templating engine. You have to decide whether the text
characters. You should use
element.innerText instead of
$(selector).html(value) with jQuery to emphasize that you are printing a text value.
Even weaker variant which cannot be exploited to endanger other visitors is untreated printing of values from form inputs back to page content.
This is the exactly the kind of vulnerability I used in introductory example. Attacker sets up input parameters in a way which leads to execution of malicious code in visitors browser. This type of attack can be easily defeated with templating engine. Nevertheless this kind of attack is not persisted and attacker’s code is only executed when visitor clicks the “right” trap-link similarly to previous case.
This scenario is similar to the previous one, except that the malicious code is additionally stored in a database. It means that the attacker does not have to put traps to lure visitors to visit a page with his code. All the visitors are presented with affected version of site once they open it, no matter how careful they are.
Even if those first two types of XSS attack seem to be harmless on the first sight, all types of attack are similarly dangerous. All it takes is to publish ordinary link with supplied attack code on a discussion board, email or anywhere else online.
The simplest use of XSS is to open some popup window perhaps with some kind of advertisement – simply put, the attacker wants to catch attention of a visitor and make him to do something else.
More dangerous XSS attack is a combination with CSRF attack – the attacker expects that visitor
of affected site is actually logged into another (well known) service. He knows that the browser automatically
appends HTTP headers (i.e. cookies with authorisation tokens) for HTTP requests. The attacker can execute actions
on behalf of his victim – perhaps he can try to change a password and block the account or issue order of goods.
These kind of attacks are more difficult to perform nowadays thanks to origin policy
applied in web browsers (you cannot easily send AJAX requests to another domain unless that domain allows it)
but still the attacker can make the visitor to submit ordinary form with modified hidden fields. Any action invoked
by the GET method can easily exploited even with simple
<img src="http://target.com/make/some/harm.php"> tag.
XSS can also be used to spy on visitors and send personal data like user credentials to the attacker. This is a very dangerous scenario.
Another example can be DoS/DDoS attack on another service. An attacker can use connectivity of visitors to overload any online service with random HTTP requests generated by visitors’ web browsers.
XSS is a very dangerous vulnerability which you can introduce in you code. It is quite easy to avoid it by usage of the right tools – a templating engine. You can read detailed description of XSS attack and check out more examples on OWASP page.