Cross-site scripting (XSS) is a type of computer security vulnerability typically found in web applications that enables malicious attackers to inject client-side script into web pages viewed by other users. An exploited cross-site scripting vulnerability can be used by attackers to bypass access controls such as the same origin policy. Cross-site scripting carried out on websites were roughly 80% of all security vulnerabilities documented by Symantec as of 2007. Their impact may range from a petty nuisance to a significant security risk, depending on the sensitivity of the data handled by the vulnerable site, and the nature of any security mitigations implemented by the site’s owner.
Cross-site scripting holes are web application vulnerabilities that allow attackers to bypass client-side security mechanisms normally imposed on web content by modern browsers. By finding ways of injecting malicious scripts into web pages, an attacker can gain elevated access privileges to sensitive page content, session cookies, and a variety of other information maintained by the browser on behalf of the user. Cross-site scripting attacks are therefore a special case of code injection.
XSS vulnerabilities have been reported and exploited since the 1990s. Some prominent sites that have been affected in the past are the social networking sites Twitter, Facebook, MySpace, and Orkut. In recent years, cross-site scripting flaws surpassed buffer overflows to become the most common publicly-reported security vulnerability, with some researchers claiming that as many as 68% of websites are likely open to XSS attacks.
Contextual Output Encoding/Escaping of String Input
It is worth noting that although it is widely recommended, simply performing HTML entity encoding on the five XML significant characters is not always sufficient to prevent many forms of XSS. Encoding can be tricky, and the use of a security encoding library is highly recommended.
Safely Validating Untrusted HTML Input
Many operators of particular web applications (e.g. forums and webmail) wish to allow users to utilize some of the features HTML provides, such as a limited subset of HTML markup. When accepting HTML input from users, output encoding will not suffice since the user input needs to be rendered as HTML by the browser. Stopping XSS when accepting HTML input from users is much more complex in this situation. Untrusted HTML input must be run through an HTML policy engine to ensure that is does not contain XSS. Tools such as OWASP AntiSamy and http://htmlpurifier.org/ accomplish this task.
Besides content filtering, other imperfect methods for cross-site scripting mitigation are also commonly used. One example is the use of additional security controls when handling cookie-based user authentication. Many web applications rely on session cookies for authentication between individual HTTP requests, and because client-side scripts generally have access to these cookies, simple XSS exploits can steal these cookies. To mitigate this particular threat (though not the XSS problem in general), many web applications tie session cookies to the IP address of the user who originally logged in, and only permit that IP to use that cookie. This is effective in most situations (if an attacker is only after the cookie), but obviously breaks down in situations where an attacker is behind the same NATed IP address or web proxy—or simply opts to tamper with the site or steal data through the injected script, instead of attempting to hijack the cookie for future use.
Another mitigation present in Internet Explorer (since version 6), Firefox (since version 184.108.40.206), Safari (since version 4) and Google Chrome, is a HttpOnly flag which allows a web server to set a cookie that is unavailable to client-side scripts. While beneficial, the feature does not fully prevent cookie theft nor can it prevent attacks within the browser.
Some browsers or browser plugins can be configured to disable client-side scripts on a per-domain basis. If scripting is allowed by default, then this approach is of limited value, since it blocks bad sites only after the user knows that they are bad, which is too late. Functionality that blocks all scripting and external inclusions by default and then allows the user to enable it on a per-domain basis is more effective. This has been possible for a long time in Internet Explorer (since version 4) by setting up its so called “Security Zones”, and in Opera (since version 9) using its “Site Specific Preferences”. A solution for Firefox and other Gecko-based browsers is the open source NoScript add-on which, in addition to the ability to enable scripts on a per-domain basis, provides some anti-XSS protection even when scripts are enabled.
The most significant problem with blocking all scripts on all websites by default is substantial reduction in functionality and responsiveness (client-side scripting can be much faster than server-side scripting because it does not need to connect to a remote server and the page or frame does not need to be reloaded). Another problem with script blocking is that many users do not understand it, and do not know how to properly secure their browsers. Yet another drawback is that many sites do not work without client-side scripting, forcing users to disable protection for that site and opening their systems to vulnerabilities. The Firefox NoScript extension enables users to allow scripts selectively from a given page while disallowing others on the same page. For example, scripts from example.com could be allowed, while scripts from advertisingagency.com that are attempting to run on the same page could be disallowed.