**Cross-Site Scripting** (abbreviated as XSS) is a class of security vulnerability whereby an attacker manages to use a website to deliver a potentially malicious JavaScript payload to an end user. XSS vulnerabilities are *very* common in web applications. They're a special case of code injection attack; except where SQL injection, local/remote file inclusion, and OS command injection target the server, XSS exclusively targets the users of a website. There are two main varieties of XSS vulnerabilities we need to consider when planning our defenses: * **Stored XSS** occurs when data you submit to a website is persisted (on disk or in RAM) across requests, usually with the goal of executing when a privileged user access a particular web page. * **Reflective XSS** occurs when a particular page can be used to execute arbitrary code, but it does not persist the attack code across multiple requests. Since an attacker needs to send a user to a specially crafted URL for the code to run, reflective XSS usually requires some social engineering to pull off. Cross-Site Scripting vulnerabilities can be used by an attacker to accomplish a long list of potential nefarious goals, including: * Steal your [session identifier](https://paragonie.com/blog/2015/04/fast-track-safe-and-secure-php-sessions) so they can impersonate you and access the web application. * Redirect you to a phishing page that gathers sensitive information. * Install malware on your computer (usually requires a 0day vulnerability for your browser and OS). * Perform tasks on your behalf (i.e. create a new administrator account with the attacker's credentials). Cross-Site Scripting represents an asymmetric in the security landscape. They're incredibly easy for attackers to exploit, but XSS mitigation can become a rabbit hole of complexity depending on your project's requirements. # Brief XSS Mitigation Guide 1. If your framework has a templating engine that offers automatic contextual filtering, use that. Make sure you use the appropriate context flags (e.g. `url`, `html_attr`, `html`). **Context matters to XSS prevention.** 2. `echo htmlentities($string, ENT_QUOTES | ENT_HTML5, 'UTF-8');` is a safe and effective way to stop all XSS attacks on a UTF-8 encoded web page, but doesn't allow any HTML. 3. If your requirements allow you to use e.g. Markdown instead of HTML, then [don't use HTML](#avoid-html). 4. If you need to allow some HTML and aren't using a templating engine (see #1), use [HTML Purifier](http://htmlpurifier.org). 5. For user-provided URLs, you additionally want to only allow `http:` and `https:` schemes; never `javascript:`. Furthermore, URL encode any user input. The rest of this document explains cross-site scripting vulnerabilities and their mitigation strategies in detail. ## What Does a XSS Vulnerability Look Like? XSS vulnerabilities can occur in any place where information which can be altered by any user is included in the output of a webpage without being properly escaped. ### Example 1
This is a potential **stored XSS** infection point (assuming the `profile` field was pulled straight from the database without escaping). If the malicious user is able to include a snippet that looks like this, they can exploit any authenticated user that visits their profile and steal their cookies for future impersonation efforts: ### Example 2