Cross site scripting is another prevalent form of attack on a web application, and in this tutorial we are going to find out what a cross site scripting attack is any why they are so successful as well as how to mitigate these risks.
Cross Site Scripting (XSS) are typically carried out against authenticated users and involve the user performing an action on the attackers behalf.
There isn't much value is getting an unauthenticated user to perform an action, but huge value if you can get an authenticated user to. A classic example would be for a victim to authenticate to their online bank and transfer money into the account of the attacker. If the victim is authenticated and the attacker can trick the victim into making a request on their behalf, they can carry out the transaction.
The only thing that makes a user authenticated is the authentication cookie, which we have seen before. If this is left vulnerable, it is open as a possible attack vector. As we have seen in previous tutorials, cookies are sent with every request, secure or insecure. If a authentication cookie is transmitted over insecure methods, it's contents can be captured and the session hijacked. Even if the cookie is secure, XSS attacks can still leave an application and users vulnerable.
So how do we (as an attacker) trick a victim into making a request which they never intended to which has malicious intent to advantage the attacker?
In order to understand how much of a problem XSS is, we must understand how a user session is authenticated. Since HTTP is a stateless protocol (each request knows nothing about the previous request) cookies are used to maintain state through the use of a session id. This links back to a session on the server, usually a database, so when the request is processed by the server it knows who the user is. The authentication cookie is sent automatically to the website with EVERY request, the website then identifies and authorises the user based on that cookie.
Let's continue the example of an online banking application. We have a user, who has authenticated successfully to the application, they have an authentication cookie. Now, every time they make a request to the server that authentication cookie is sent along to reauthenticate the session. It's not the user doing this though, you are never aware of sending the cookie, it is the browser which does this for you. This is an important distinction because it is the browser that we will be tricking.
What the attacker is aiming to do is to send a malicious request to the server using the users browser. When that request is issued, the cookie will of course be sent along with it. All of this happens against a legitimate website, with a legitimately constructed request it's just that the request is one the user didn't intend.
Let's start off by looking at a real example of how a cross site scripting attack could be added to a legitimate website. In 2012, the Twitter account of Lady Gaga was hacked, and a malicious link added to the twitter feed. Many attacks come from reputable sources such as Twitter and Facebook, sites where attackers can share links. The attacks are based on the user following a link to the attackers website, which mounts the attack.
So here is a nice little enticement. A free Macbook! It looks legit, the source is Lady Gaga so it can't possibly be bad! Right? So the user goes ahead and clicks the link. They are then sent to the attackers website, which will probably be styled to look like an authentic page and use a similar domain name, but one which they control, for example mapple.com Very similar, but totally different.
The attackers page will then get the user to perform an action, typically filling in a form and clicking a button.
Now, on the attackers page the user will be presented with a form and a button to click. When the button is clicked there is a post back to the server and the contents of the form are sent in that post request. In the hackers page however, the form post url is to the online banking transfer of funds address, and the form controls constructed in such a way as to send the correct form data which the banking page needs, and the browser will automatically attach the authentication cookie. As far as the banking server is concerned, it just received a request to transfer funds, from the victims browser, using a valid authentication cookie so it goes ahead and processes the transaction.
So what does the form structure look like?
<form action="http://www.myonlinebank.com/transfer" method="POST" target="hiddenFrame"> <input type="hidden" name="targetAccount" value="6365584" /> <input type="hidden" name="amountToTransfer" value="99.99" /> <input type="submit" value="Win an iPad" onclick="alert('You Won!!!')" /> </form> <iframe name="hiddenFrame" style="display:none;visibility:hidden"></iframe>
In this form, contained on the attackers website, the form is going to post all the values to the online bank transfer address. It is going to pass two parameters the account of the attacker, and the amount to transfer. When the button is clicked the request is sent to the online banking application together with the authentication cookie and the funds transferred. To prevent the user from seeing what is happening, the request is sent to the hidden frame.
This is an overly simplified example, but it serves to show how an attack could be constructed. It relies on the user being pre-authenticated to the banking website, clicking a link from an external source to the attackers website and then completing the action. So this introduces a new attack vector to the mix, that of tricking the user. This is called social engineering, and we'll look at this in the next tutorial.
The attack we just saw is so prevalent and so easy because the attack relies on a very specific, known pattern. The attack merely replicates exactly what the actual application would do, the attacker just controls the values in the POST request.
So how can we mitigate against CSRF attacks? The only real protection against CSRF attacks is through the use of an anti-forgery token. This token is used to ensure that the authentication cookie and the form POST request match up.
The server will add a hidden field to the legitimate form containing a token, that token is also paired with another token added to the authentication cookie. The attacking website has no access to this token and therefore no means to replicate it in the form submit. When the form is submitted, the server first checks to see if the request contains the anti-forgery token, if it does it checks it matches the contents of the authentication cookie. Only if the two match will the transaction be completed.
Anti-forgery tokens add randomness to the request pattern. The attacker does not have access to the token therefore cannot submit the token in a hidden field. The cookie provides verification of the token in the hidden field.
My website and its content are free to use without the clutter of adverts, tracking cookies, marketing messages or anything else like that. If you enjoyed reading this article, or it helped you in some way, all I ask in return is you leave a comment below or share this page with your friends. Thank you.