In the previous three chapters of this series, we discussed ways for developers to put their hacker hats on and program defensively to prevent security bugs from cropping up in their software. We described the nature of SQL injection, OS command injection and buffer overflow attacks. We did not, however, touch upon the No. 1 issue that plagues web application developers: cross-site scripting (XSS).

Indeed, XSS ranks quite high in the CWE/SANS Top 25 Most Dangerous Software Errors list:

Rank Name
1 Improper Neutralization of Special Elements used in an SQL Command (‘SQL Injection’)
2 Improper Neutralization of Special Elements used in an OS Command (‘OS Command Injection’)
3 Buffer Copy without Checking Size of Input (‘Classic Buffer Overflow’)
4 Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’)
Scroll to view full table

XSS is easy to test for. In fact, it is probably one of the most common vulnerability types found in software. However, XSS can be really hard to fix. When maintaining a large web application that was written 10 years ago using servlet technology, there may be thousands of places where XSS lays dormant. Newer technologies using rich, client-side user interfaces (UIs) are not spared, either.

To top it all off, most developers are using web technologies nowadays, even in mobile apps, so XSS is a big headache for everyone.

Notorious Examples of Cross-Site Scripting

XSS made history with the Samy worm, the fastest spreading virus of all time. The worm was a relatively harmless and very original type of virus that self-replicated by altering the profile pages of MySpace users and sending friend requests to its creator, now-famous hacker Samy Kamkar, who ended up in hot water with authorities after the incident. Twitter was also targeted by a similar XSS worm that embedded malicious links on the website StalkDaily.

Besides infections on social networking sites, XSS has been used for financial gain, most notably in attacks against e-commerce giant eBay. Cybercriminals injected malicious scripts into several listings for cheap iPhones. The scripts sent users to a spoofed login page that harvested their credentials.

What Is the Programming Flaw?

XSS occurs when a webpage renders user input as HTML or JavaScript code. Below are some examples of code that renders the user input.

Figure 1 shows several locations within the HTML markup of a server-generated page:

Figure 2 shows input rendered as is within the JavaScript code of a server-generated page:

Figure 3 shows XSS being rendered by client-side code:

The attack vectors come in many flavors. In the reflected XSS scenario, the attack is conducted via links that contain the malicious code. Victims click on the link, which is from a host they trust, and then interact with the altered website. Common attacks include fake login pages that send credentials somewhere else.

Figure 4 shows how reflected XSS works:

The stored flavor of XSS is even more dangerous because victims come across it unwittingly simply by using a vulnerable web application. The aforementioned XSS worms are examples of stored XSS.

Preventing XSS

There is no silver bullet to prevent XSS. In fact, fixing XSS sometimes feels like playing whack-a-mole. The video below exemplifies the challenges associated with preventing this pesky bug:

Let’s dive into a few best practices that web developers should always keep in mind.

Output Encoding

Output encoding works very well for pages generated on the sever side and is quite effective in neutralizing most XSS payloads. The most common method is HTML encoding, while URL encoding can help neutralize the injection of markup in links and redirects.

Figure 5 shows how HTML encoding neutralizes XSS:

JavaScript Escaping

Escaping can prevent injection within JavaScript context by escaping single quotes.

For example: x=”-alert (1)-” becomes x=’\’-alert (1)-\”

A flavor of HTML encoding that also encodes single quotes with ‘ can also be used. This provides a more consistent approach to preventing the issue.

Safe DOM Elements

XSS in modern, rich client UIs is often made possible by unsafe handling of the document object model (DOM).

Using the innerHTML attribute, for example, allows the user input to be rendered as HTML and XSS with JavaScript events. The safe alternative is to use contentText or innerText in some versions of Internet Explorer (IE).

Use Eval and Dynamic Function Calls With Care

Pages with large JavaScript libraries may be using the eval function, which accepts a JavaScript expression as argument. Needless to say, what goes into that expression should be carefully scrutinized. The same goes for situations in which the code or page generates function names dynamically.

Enforcing the Charset

There are XSS attacks that use a different encoding, such as UTF7, for example. If the charset of the page is not enforced, the browser will default to auto detect and those payloads will execute. For example: Content-type: text/html; charset=UTF8.

Input Validation

Whitelisting can reduce the attack surface, although in some cases single quotes and tags must be allowed. If you want to allow someone named O’Brien to update his or her user profile, for example, you need to allow single quotes.

If possible, most input should be whitelisted to alphanumeric to prevent XSS and many other attacks, and special characters should only be allowed on an exception basis. This will reduce the attack surface and minimize the potential for bugs.

Blacklisting is a very bad idea because it may prevent some tools or testers from finding the issue. Others may be able to beat the rule by trying a previously unknown method. The OWASP XSS Evasion Cheat Sheet lists the staggering number of XSS attack variations.


Besides preventing the issue, there are ways to minimize it by using secure headers that most modern browsers support:

  • X-XSS-Protection: 1; mode=block enforces the browser XSS filter for some browsers; and
  • Content-Security-Policy: script-src ‘self’ prevents the loading of external scripts, which makes XSS exploitation difficult.

There are many more useful settings of the content security policy, including options to log violations that can indicate that an attacker is leveraging a possibly unknown XSS on the site.

XSS Is Here to Stay

XSS is a pesky, ubiquitous and very dangerous type of programming flaw. Developers should always keep XSS in mind when building today’s flashy web applications. The web has become the choice for implementing attractive, platform-independent applications, and it is here to stay. Unfortunately, so is the threat of XSS.

Access Your Complimentary Trial

More from Application Security

Securing Your SAP Environments: Going Beyond Access Control

Many large businesses run SAP to manage their business operations and their customer relations. Security has become an increasingly critical priority due to the ongoing digitalization of society and the new opportunities that attackers exploit to achieve a system breach. Recent attacks related to corrupt data, stealing personal information and escalating privileges for remote code execution all highlight the new and varied entry points threat actors have taken advantage of. Attackers with the appropriate skills could be able to exploit…

Does Follina Mean It’s Time to Abandon Microsoft Office?

As a freelance writer, I spend most of my day working in Microsoft Word. Then, I send drafts to clients and companies across the globe. So, news of the newly discovered Microsoft Office vulnerability made me concerned about the possibility of accidentally spreading malware to my clients. I take extra precautions to ensure that I’m not introducing risk to my clients. Still, using Microsoft Office was something I did many times a day without a second thought. I brought up…

3 Reasons Why Technology Integration Matters

As John Donne once wrote, “No man is an island entire of itself.” With digitalization bridging any distance, the same logic could be applied to tech. Threat actors have vast underground forums for sharing their intelligence, while security professionals remain tight-lipped in a lot of data breach cases. Much like the way a vaccine can help stop the spread of infectious diseases, sharing threat intelligence and defense strategies can help to establish a more secure future for everyone.  So what…

Why Your Success Depends on Your IAM Capability

It’s truly universal: if you require your workforce, customers, patients, citizens, constituents, students, teachers… anyone, to register before digitally accessing information or buying goods or services, you are enabling that interaction with identity and access management (IAM). Many IAM vendors talk about how IAM solutions can be an enabler for productivity, about the return on investment (ROI) that can be achieved after successfully rolling out an identity strategy. They all talk about reduction in friction, improving users' perception of the…