What's the best way to prevent XSS attacks?

To prevent cross-site scripting attacks, software developers must validate user input and encode output. Review characters to filter out, as well as sources and sinks to avoid.

Cross-site scripting vulnerabilities have been exploited by attackers since the early 2000s, and XSS has been on the OWASP Top 10 list of critical security risks for web applications beginning in 2004. However, many developers, system administrators and even some penetration testers still don't take it seriously. In order to become an effective web application hacker or defender, you must understand the basics of how to prevent XSS attacks.

XSS attacks are still problem

Cross-site scripting is a type of web application vulnerability that enables attackers to inject and execute malicious client-side code in the victim's browser within a legitimate web application.

The impact and severity of successful XSS attacks can vary. XSS attacks could result in session hijacking, stolen tokens, stolen session cookies and cross-site request forgery attacks. These attacks can lead to user accounts being compromised.

A successful XSS attack can also enable an attacker to use stolen or forged cookies to impersonate valid users. In cases where the valid user has administrative rights within the application, the attacker can then use those privileges to alter pages or do remote code execution on the server-side of the application.

Types of XSS attacks

There are three types of XSS attacks: stored, reflected and Document Object Model (DOM) based.

  1. A stored XSS attack enables an attacker to embed a malicious script into a vulnerable page, which is then executed when a victim views the page. Stored XSS is considered the most damaging type of XSS attack. For example, when an attacker injects a malicious JavaScript payload directly into a vulnerable web application, the web browser saves the injected JavaScript payload. Then, each time the victim visits that website or web application, the malicious code is executed.
  2. A reflected XSS attack occurs when the malicious payload is embedded into a link and activated only when the user clicks on the link. Here, the malicious payload is not stored but only displayed on the webpage in the form of a URL or POST data.
  3. A DOM-based XSS vulnerability arises when the DOM is used to generate dynamic content containing user input that can be processed without checking. This kind of attack is carried out with JavaScript in the victim's browser

XSS attack prevention

To prevent XSS attacks, developers must validate user input by properly filtering out or escaping special characters and then encoding the output to prevent stored XSS attacks and reflected XSS attacks. The following special characters should always be filtered out or escaped to prevent them from being exploited maliciously:









Developers should validate user input -- sources -- and encode the output -- sinks -- to prevent DOM-based XSS attacks. The input source property is where the DOM reads from, and the source is where the attacker can inject malicious code to exploit the XSS vulnerability. The following source properties should be avoided:

  • URL
  • documentURI
  • location
  • href
  • search
  • hash

Sinks are the points where the DOM executes the malicious characters or code from the input -- the source -- which, in turn, gets outputted to the webpage. These sinks should be avoided to prevent denial-of-service-based XSS attacks:

  • innerHTML
  • outerHTML
  • write

If you'd like to get better at understanding and preventing XSS attacks, Google has built an XSS game website for learning how these attacks work and how to better prevent them. The Mutillidae 2 project from OWASP also offers a learning target for web security professionals to sharpen their XSS attack defenses.

This was last published in August 2019

Dig Deeper on Application attacks (buffer overflows, cross-site scripting)