Contextual output encoding/escaping of string input There are several escaping schemes that can be used depending on where the untrusted string needs to be placed within an HTML document including HTML entity encoding, JavaScript escaping, CSS escaping, and
URL (or percent) encoding. Most web applications that do not need to accept rich data can use escaping to largely eliminate the risk of XSS attacks in a fairly straightforward manner. Performing HTML entity encoding only on the
five XML significant characters is not always sufficient to prevent many forms of XSS attacks, security encoding libraries are usually easier to use.
Safely validating untrusted HTML input Many operators of particular web applications (e.g. forums and webmail) allow users to utilize HTML markup. When accepting HTML input from users (say, <b>very</b> large), output encoding (such as <b>very</b> large) will not suffice since the user input needs to be rendered as HTML by the browser (so it shows as
very large, instead of <b>very</b> large). Stopping an XSS attack when accepting HTML input from users is much more complex in this situation. Often, untrusted HTML input must be run through an
HTML sanitization engine to ensure that it does not contain potentially malicious JavaScript code. For example, if a user enters Hello world alert("XSS") then the application processing the markup may allow the span> but escape the script when the input is displayed: Hello world <script>alert("XSS")</script> Many validations rely on parsing out (blacklisting) specific "at risk" HTML tags such as the
iframe>, link>, and <script> tag, or by only allowing certain tags and removing or escaping others. There are several issues with this approach, for example sometimes seemingly harmless tags can be left out which when utilized correctly can still result in an XSS Another popular method is to strip user input of " and ' however this can also be bypassed as the payload can be concealed with
obfuscation.
Cookie security 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, then 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 as the victim, or the victim is changing his or her
mobile IP.
Disabling scripts While
Web 2.0 and
Ajax developers require the use of JavaScript, some web applications are written to allow operation without the need for any client-side scripts. This allows users, if they choose, to disable scripting in their browsers before using the application. In this way, even potentially malicious client-side scripts could be inserted unescaped on a page, and users would not be susceptible to XSS attacks. Some browsers or browser plugins can be configured to disable client-side scripts on a per-domain basis. This approach is of limited value if scripting is allowed by default, 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 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.
Emerging defensive technologies Trusted types changes
Web APIs to check that values have been
trademarked as trusted. As long as programs only trademark trustworthy values, an attacker who controls a JavaScript
string value cannot cause XSS. Trusted types are designed to be
auditable by
blue teams. Another defense approach is to use automated tools that will remove XSS malicious code in web pages, these tools use
static analysis and/or pattern matching methods to identify malicious codes potentially and secure them using methods like escaping.
SameSite cookie parameter When a cookie is set with the SameSite=Strict parameter, it is stripped from all cross-origin requests. When set with SameSite=Lax, it is stripped from all non-"safe" cross-origin requests (that is, requests other than GET, OPTIONS, and TRACE which have read-only semantics). The feature is implemented in
Google Chrome since version 63 and
Firefox since version 60. == Notable incidents ==