During Penetration Tests I often see testers utilising Cross-site Scripting attacks, popping an alert(1) and stopping there; additionally looking through the payloads used by other testers I often find one area missing. So if you’re a tester, think of the payloads that you deploy and think how you are testing for the type of vulnerability described below:
Continue reading: Cross-site Scripting (XSS): Life After the Alert Box
The settings are configured server side and given to the web browser via a server response header, the “Content-Security-Policy” header, here’s a simple example of one of these headers:
Sometimes when I’m chatting to security engineers and developers I hear them say that the only characters you need to encode (or strip) are < and >. This often comes around due to .Net’s security filter which restricts any alpha-character from appearing after a < character. This filter prevents a lot of XSS attacks but it’s definitely not complete.
0. Example Page
Throughout these examples I’ll use the following page HTML and I’ll move the reflection point around to show the different places you often find XSS and the characters needed for each context. The four areas of reflection have been highlighted in blue. The page could be generated with a URL along the lines of: http://xss.example.com/page?id=foo&name=Holly&greenting=Hello&profile=%2Fprofile%3Fid%3D132
The above reflection point is an interesting one because in this context the normally recommended fix of HTML entity encoding won’t work as the browser will entity decode anything within a HREF attribute! Additionally an attacker could simply replace the URL that the developer intended the link to point to with a link to a malicious site, causing a redirection if the user clicked the affected link. The lesson here is don’t allow reflection into the base of a HREF!
So as you can see there are plenty of places where an attacker can successfully get XSS payloads to fire without the requirement for < and > characters, with payloads such as ‘);alert(1);// it’s important to remember that all dangerous characters should be encoded to prevent attacks. This should include
Cross-site Scripting is the third vulnerability on the OWASP Top 10 and it is a vulnerability that can allow an attacker to steal confidential data, execute functions on a vulnerable site, virtually deface a site or redirect the user to a malicious page.
The vulnerability comes about because user input is insecurely embedded in a response to the user; this is partly due to the simple way in which web browsers differentiate between text and code. Consider a page like http://xxs.example.com/?name=Holly which has the following web page HTML:
Web browsers utilise < and > characters to determine what is code and what is text. In the above example you can see the code “tags” such as <html> are wrapped around the text “Hello there!”. So above the browsers interpretation of what is code is shown in green and what is text is shown in blue. However instead of Holly, if I enter my name as Holly<script>alert(“Vulnerable!”)</script> the page that would be given to the web browser would look like this:
As you can see, even though the script tags originated from user input and were supposed to be interpreted as simple text, as they contained those important < and > characters, the web browser has interpreted them as code and not text! This means that code has sneaked its way in from the URL in the case into the body of the page as the site did not protect against this vulnerability.
This means that an attacker can craft a malicious link which contains scripts designed to attack the user, if a user is coerced into clicking the malicious link then the attacker’s payload could fire. The payload could steal the victim user’s session credentials from their cookie, deface the pay or redirect the user to a malicious site.
If the attacker’s payload is immediately returned to the user, for example when a user clicks a link the payload fires – then this is known as Reflected Cross-site Scripting. As the payload bounces, or is reflected, on the server and delivered to the victim. Alternatively the same kind of attack can be achieved in a function such as a guestbook or forum where an attacker can save a payload and simply wait for a victim to stumble across it as they navigate the vulnerable site. This type of deployment is called Stored Cross-site Scripting.
Defending against Cross-site Scripting
The vast majority of XSS can be fixed in a relatively simple way, by encoding all dangerous characters that originated as user input using HTML entity encoding. The benefit of HTML entities is that the browser will show the correct character to the user but it’ll prevent an attacker from injection scripts. HTML entities look like this:
If the original payload shown earlier in the page was encoded in this way it would render in the web page code like this: