XSS takes advantage of an important aspect of the modern web, which is that most websites are built on the fly when pages load, sometimes by executing code in the browser itself. That can make such attacks tricky to prevent
How XSS works
Anyone can set up a website that contains malicious code. In a cross-site scripting attack, an attacker sets things up so their code gets on their victim’s computer when the victim accesses someone else’s website. That’s where the “cross” in the name comes from. XSS attacks manage to pull this off without any need to gain privileged access to the web server to plant code on it surreptitiously. Instead, the attackers take advantage of how modern webpages work.
If someone asked you for a basic, entry-level explanation of the web, you would probably tell them something like this: a person who wants to create a webpage writes an HTML document, which they upload to a web server; when a user wants to access that page, they point their browser to the server’s address, and the browser downloads the HTML code and interprets it to build a version of the web page for the user.
In an XSS attack, a hacker takes advantage of this interaction between a user and a website to get malicious code to execute on the user’s machine. But how? Consider the following URL:
Put that into your browser address bar and you’ll see the Google search results for “CSO Online.” In fact, the page you’ll see looks exactly as if you had typed “CSO Online” into your browser search bar, or into the Google.com front page. Among other things, you’ll notice that the phrase appears in several places on the page, including the search bar at the top:
XSS attacks are broken down into several categories: reflected attacks, DOM-based attacks, and stored attacks. Here’s how they differ:
What makes a website vulnerable to an XSS attack? Hopefully our discussion so far has made given you a hint. If your web application naively takes in user input, doesn’t check it for potentially malicious executable code, and uses that input to render a web page or perform other operations, it’s vulnerable to this sort of attack.
In malware lingo, a payload is executable code that performs the actions that the attacker wants performed. In an XSS attack, the payload is the script code that the attacker manages to trick the victim’s browser into executing.
XSS protection and prevention
If you’re building or operating a web application or interactive website, there are three main techniques you should be integrating into the design to mitigate against potential cross-site scripting attacks.
- Input sanitization. The obvious answer to preventing malicious script code from being passed in as input and reflected to the user is to simply not accept script code as input in the first place. You should definitely be filtering input with this in mind, but this is easier said than done; cleverly crafted snippets of executable code can be slipped through filters. One way to deal with this is to take an whitelist rather than a blacklist approach—for instance, rather than trying to write a filter that blocks all malicious code from being entered in a web form, write your application so that it only accepts data in specified formats (phone numbers, email addresses, etc.) if that’s what you’re expecting.
- Output escaping. This tackles the problem from the other direction. If your web application sends data entered by the user back to a web page, that data should be filtered to make sure it doesn’t become executable code on that web page. If the user enters HTML tags code as input, your application should use escape characters to ensure that those tags appear as text on the resulting page, rather than being integrated into the page HTML itself.
- The Content Security Policy (CSP) standard. CSP takes the whitelist approach past just input text and into the realm of script execution: your web application should only ever execute the specific code that you’ve told it is safe. Google has some great resources on implementing CSP.
Testing for XSS vulnerabilities is an important aspect of keeping your web application secure. OWASP has resources that get in-depth on how you can test your applications for vulnerability to DOM-based or reflected cross-site scripting attacks. If you’re looking for an XSS cheat sheet, OWASP has you covered there as well with a document full of code for XSS attacks that can be used to bypass certain XSS defensive filters; these will prove invaluable for any penetration testing you might be doing against your own systems.
XSS vs CSRF
You might hear CSRF used in the same context as XSS. This stands for cross-site request forgery, which is an attack that, like XSS, targets a user’s browser. The main difference is that CSRF exploits a user’s authenticated session (maybe they are logged into their bank account), while XSS doesn’t need an authenticated session to be effective.
Let’s say you were logged into Twitter and online banking at the same time, and you clicked on a Twitter link that looked like this:
Depending on how your bank manages session tokens, and what browser you’re using, you might be five grand poorer. XSS is a more dangerous attack vector, but it’s important to defend against both XSS and CSRF. OWASP has a cheat sheet for CSRF defensive security measures as well.
Recent and famous XSS attacks
The so-called Samy worm turned out to be mostly harmless. But others were much more troubling:
And cross-site scripting remains a major threat today. Since 2021, XSS vulnerabilities have been found in the Zimbra email platform, Wordpress, and the Nagios open source IT management platform. And remember, hackers generally don’t use attack techniques in isolation: cross-site scripting is one component in a complex and recently discovered form of attack using wildcard TLS certificates called ALPACA, for instance. You need to make sure your XSS vulnerabilities are closed to stave off big risks.
Copyright © 2022 IDG Communications, Inc.