With digital being the new normal, an attack on your organization’s web app, means a damaging attack on your brand, reputation and customer base – one that can be difficult to recover from. In this series on Web-based Application Security, we analyze critical vulnerabilities in web-based application security with practical ways to secure your organization (Read Part 1: Open Redirection Vulnerability and Part 2: Cross-Site Forgery). Let’s do a deep dive into Cross Site Scripting.

Understanding the Cross-Site Scripting (XSS) Vulnerability

OWASP describes Cross-Site Scripting, as follows, “Cross-Site Scripting attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user.

Year after year, XSS is notorious for being the most common vulnerability detected. Even though it is easy to prevent an XSS attack, as it hinges on sanitizing user input – owing to the prevalence of soliciting user input in web apps – it takes one slip to miss a check. Also, unlike other vulnerabilities, is is easy for hackers to exploit. For example, CSRF requires a user to have an authenticated session, XSS does not need an authenticated session to work – it just needs a website to accept untrusted user input. Attackers can then execute malicious scripts in the victim’s browser that range from benign, such as Samy’s worm that got him a million mySpace friends and a “samy is my hero!” popup, to positively dangerous such as defacing your home page, redirecting users to malware sites, hijacking user sessions or browsers, etc.

XSS has been exploited in so many ways, that it now comes in various flavors:

Reflected/Non-Persistent/Type II XSS Attacks

This is one of the most basic types of XSS attacks. Here the victim is tricked into clicking a link in a phishing email or browsing a malicious website. The injected script is reflected off the web server – in an error message or search result – and it goes to the vulnerable web site, which reflects the attack back to the victim’s browser. The browser then runs the injected script because it came from a “trusted” server. Good news is that typically, built-in XSS filters in Chrome or Internet Explorer detect these attacks.

Stored/Persistent/Type I XSS Attacks

These attacks are more complex, and their consequences more severe than reflected attacks. In this type of attack, the injected script is stored on the target servers in a database or on the target website in a comment, message, etc. When a user loads the website, the malicious script is run to achieve its (un)intended goal. What makes this attack more evil, is that it can turn into a “worm” on more popular websites – every time the user visits the page, the script runs and worsens the harm.


Typically, XSS attacks target the server side, but with DOM-based attacks, the script is fully on the client side and manipulates the DOM (Document Object Model) instead of the HTML code. The attack payload modifies the DOM environment in the victim’s browser, causing the client-side code to be interpreted based on the hacker’s intent.

In Action: XSS Attack

You visit your favorite news website mynews.com. It has an XSS vulnerability that allows a script to be injected when commenting on an article.

Evil Hacker adds a comment:

Now when anyone visits the popular Sports article on mynews.com, on page load, the script will send the victim’s authorization cookie to Evil Hacker’s malwaresite. Whereupon Evil Hacker can use the cookie to hijack the victim’s session by impersonation. This is an example of a Stored/Persistent/Type 1 XSS attack.

A high-level diagram of cross-site scripting.

Preventing the XSS Vulnerability

Here is a list of best practices to secure your organization’s website from XSS attacks:

Trust No One

The first all-encompassing, no-exception rule – do not permit any untrusted inputs – unless it is in the specific sections details below. In particular, do not accept and run JavaScript code from an untrusted source.

Encoding or Escape untrusted input

ONLY allow untrusted data when it is explicitly validated by using the following functions:

  • HTML escape before inserting untrusted data into HTML element content.
  • Attribute escape before inserting untrusted data into HTML common attributes.
  • JavaScript escape before inserting untrusted data into JavaScript data values.
  • CSS escape and strictly validate before inserting untrusted data into HTML style property values.
  • URL escape before inserting untrusted data into HTML URL parameter values.

Utilize Libraries and Sanitization Engines for better HTML Hygiene

For apps that utilize markup, libraries are available that can parse and clean HTML formatted text. Create an HTML sanitization engine that validates untrusted HTML input.

For more details on preventing XSS attacks, check out OWASP’s XSS Prevention Model.