Secure Code Warrior

Coders Conquer Security: Share & Learn - Cross-Site Scripting

Cross-site scripting (XSS) uses the trust of browsers and ignorance of users to steal data, take over accounts, and deface websites; it's a vulnerability that can get very ugly, very quickly. Let's take a look at how XSS works, what damage can be done, and how to prevent it.

Web browsers might be our gateway to all that great stuff online, but sadly, it's not all good news. The inherent behavior of web browsers can be a catalyst for security vulnerabilities. Browsers began by characteristically trusting the markup it saw and executing it without question. That's all fine and dandy until that functionality is exploited for unsavory purposes... and naturally, attackers eventually found ways to exploit this tendency to further their evil ends.

Cross-site scripting (XSS) uses the trust of browsers and ignorance of users to steal data, take over accounts, and deface websites; it's a vulnerability that can get very ugly, very quickly.

Let's take a look at how XSS works, what damage can be done, and how to prevent it:

How does XSS work?

XSS occurs when untrusted input (often data) is rendered as output on a page but misinterpreted as executable code. An attacker can place malicious executable code (HTML tags, JavaScript, etc.) within an input parameter, which -- when returned back to the browser -- is then executed instead of displayed as data.

As mentioned above, the vulnerability appeared due to the core functioning behavior of browsers, where it is difficult to distinguish data from executable code. The operating model of the web is as follows:

  1. User visits a web page
  2. The page tells the browser what files to load and what to execute
  3. The browser executes what is on the page, no questions asked

This functionality has led to some of the most awesome, interactive experiences we enjoy on the web. The other side of the coin is that it has also led to costly exploits and vulnerabilities.

When attackers add their malicious script to a vulnerable site, it is executed without question. There is no deeper investigation, nor detection measures in place.

There are three types of XSS:

  • Stored XSS
  • Reflected XSS

Stored XSS occurs when an attacker can persistently store the malicious script in a data field of the application (e.g. in a field that stores the user's mobile phone number). This sketchy script is then sent to a user's browser every time that data field is displayed in the application.

This type of attack is often seen on forum sites or commenting engines. An attacker enters the malicious script in a comment, and bam - every user who views that comment unknowingly executes the script.

Reflected XSS occurs when user input is reflected back to the user's browser as-is. An example is a search box that displays, "You searched for ..." to the user while fetching search results.

Now, imagine that the search works by placing the search term in the URL as query parameters. A malicious attacker could send the victim a link with the malicious script embedded in those very same parameters and truthfully, most web users would barely notice it.

The victim clicks the link and is redirected to a phishing site where he/she unwittingly enters their password for the site. Little do they realize, an attacker has just stolen the key to their account.

DOM XSS is a relatively new variety of this vulnerability. It takes advantage of complex templating structures found in many UI frameworks such as Angular and React.

These templates allow for dynamic content and rich UI applications. If used incorrectly, they can be used to execute XSS attacks.

So, there you have it. You've got the scope of XSS in a nutshell. Let's dive deeper into how it can be used destructively.

Why is XSS so dangerous?

XSS can be used to redirect users to malicious sites, steal cookies and hunt for session data. Basically, whatever JavaScript can do, XSS attacks are capable of as well.

Here are three examples of XSS attacks:

  1. Yahoo email users had their session cookies stolen using XSS in 2015.
  2. The Samy worm was distributed via an XSS vulnerability in MySpace. It is still the fastest-spreading malware of all time, affecting one million users in just 20 hours.
  3. eBay allowed malicious scripts to be included in product descriptions. This led to XSS attacks against eBay users.

XSS attacks are deceptively simple and very serious. They can lead to the theft of sessions, user credentials or sensitive data. Reputational damage and decreased revenue are major pitfalls of these attacks. Even just defacing a website can lead to undesirable consequences for a business.

However, XSS can be defeated by a savvy security warrior just like you. The fix is not complicated and the industry has come a long, long way since XSS became a commonly used exploit.

You can defeat XSS.

The key to defeating XSS is understanding the context. Specifically, the context in which your user input will be rendered back to the client and where it will be rendered back. Inside the HTML code, or inside a JavaScript snippet.

If user input doesn't have to be sent back to the browser, so much the better. But if it is, it often should be HTML-encoded. HTML encoding the output will tell the browser to render the content as-is and not to execute it.

Input validation is important as well. However, validation and whitelisting are not foolproof solutions. Encoding goes a few steps further and stops browsers from executing a malicious script. Whatever is not caught with validation and whitelisting strategies, encoding will pick up.

Many frameworks are now encoding HTML output automatically.
Angular, ASP.NET MVC, and React.js are frameworks where default HTML encoding is used. You have to specifically tell these frameworks not to encode by calling a special method.

Most other frameworks, (i.e. Django and Spring) have standard libraries for XSS prevention that you can easily incorporate into your code.

The biggest challenge is teaching yourself to analyze all of the ways that user input can enter a system so you can keep your eyes peeled for it. Query parameters can carry attacks, as can post parameters. Follow the flow of data throughout your application and do not trust any data that comes from outside.

Think like border patrol. Stop every piece of data, inspect it, and don't allow it in if it looks malicious. Then encode when rendering to ensure that any bad stuff that was missed still won't cause problems.

Execute these strategies, and your users will be safe from attack via XSS. Take a look at the OWASP Cheat Sheet for even more tips to keep your data under control.

Thwart XSS and level up your security skills.

XSS resides at number seven on the OWASP Top 10 2017 list of web security risks. It has been around for a while, but it can still appear and cause problems with your application if you're not careful.

Training is so important for developers in building a security-first mindset as they craft code. And, that training is always at its most effective when it simulates real applications, in the languages developers are actively using. With that in mind, why not check out our Learning Resources to learn more about XSS? After that, you can begin the training and practice that leads to your mastery.

Think youre ready to find and fix XSS vulnerabilities right now? Challenge yourself on the Secure Code Warrior platform.