How misunderstood is it?
In a large number of situations, cross-site scripting is compared to SQL-injection due to similarities in their practice of injecting malicious code into legitimate and trusted code. However, this is misguiding and demeaning to both attack categories. They are two quite independent beasts that work in very different contexts and arise from different motivations.
Unlike SQL-injection, cross-site scripting doesn’t inject malicious instructions into database-access processes at the hands of a malicious user, but rather work by manipulating an innocent end-user into executing code that will be seen by the server as legitimate user activities.
While the prevention of SQL-injection can be (arguably) easily achieved to a satisfying degree as consequence of techniques like intermediate query frameworks and ORM (especially in the .NET world), cross-site scripting (or XSS in street-talk) is not usually considered a threat due to the lack of understanding of its severity and state of reliable resolutions.
Even the name “cross-site scripting” itself leads people into assuming a limited range of attack vectors. While this name made sense with the scenarios in which it was discovered, it has long surpassed the security of same-origin policy, with the examples of stored XSS and second-order XSS.
Introduction to Cross-site scripting
- Persistent XSS (or stored XSS) stores strings containing the malicious code inside the web application’s database to be later inadvertently executed (on viewing) by a victim. These can be posts or comments in a forum, a user-to-user message or a HTML-customized page of a social profile.
- Reflected XSS (or non-persistent XSS) embeds such malicious strings inside a request sent by the user (under manipulation) to the application, for example, as an AJAX GET request.
With XSS, the harvest of user credentials —or more commonly user sessions leading to exactly that— becomes trivial. Hijacking the victim’s cookies containing the session ID can be as simple as calling document.cookie and sending it as a simple GET request to the attacker’s server.
Attacks where unsuspecting users are manipulated into clicking seemingly innocent links inside social networking sites (including but not limited to Facebook), simply viewing a certain social forum post or falling for a dynamically created page that is disguised as a privacy or security reminder are quite common.
Such phishing attacks have the potential to be extremely difficult to separate from legitimate content and are not identifiable through simple vigilance as in the case of traditional phishing attacks where a user is persuaded into visiting a fake login screen in an attacker-controlled domain.
Secretively registering a keyboard event-listener through `addEventListener(..)` is just a matter of coming up with a clever pattern for breaking through the encoding or sandboxing of any client-side framework. The astounding and fearful nature of being able to track all keystrokes of a user in any web application requires no further explanation.
The potential scope of an attack
As in many vulnerabilities, the exploitation of a well-planned XSS would usually be simply a stepping stone in a much larger scheme. Since firewalls, encryption or user diligence is completely irrelevant to XSS, and since the hijacking of a session of a customer or administrator of a web application is a game-over scenario for the security of the system, such a vulnerability can be much more devastating than most other attacks.
Simplest and most common forms of attempts to prevent cross-site scripting is encoding and validation. Encoding is used for escaping the user input and helping the browser interprets such strings only as data and not code. Validation is used for filtering user input in cases it’s required to be executed, by helping the browser strip or block malicious instructions.
Such careful handling of user input must to be done differently depending on the context, in other words where in a page user input is inserted. This can be performed either at the reception of input or prior to the insertion of that input into a webpage.
Sanitisation or handling of input can be done on the side of the user-agent (browser) or on the side of the back-end, depending on the circumstance. The same input may be required to be inserted or processed at different places and under different contexts.
Such security measures need to be taken without limiting the user-experience and functionality.
Blacklisting and whitelisting are two methods used for validating, i.e. sanitizing or rejecting input. Both have competing advantages as well as drawbacks. But generally, blacklisting, which is a method of preventing known patterns is deemed inferior to whitelisting, which only allows extremely selective input patterns.
Still, secure input handling alone may not be a long-term solution in many cases, as oversight in a single place can render security in all other places worthless.
Content Security Policy
As a firm and reliable solution for such situations, CSP introduces policies for the browser to prevent ground for such vulnerabilities.
While parameters of CSP are well customizable, three main categories can be identified:
– No untrusted sources – Content can be loaded only from a set of clearly-defined external sources.
Admitting the possibility of a problem is key to finding a resolution for it. With familiarity and foresight, most unfortunate circumstances can be expected and avoided. Otherwise every speck of effort in securing a product can be washed-away due to simple oversight.