RSS

Understand Cross-Site Scripting (XSS) by examples - ZTT series

8 minute read


In this article of the Zero Trust Thinking series, we’re going to learn about a critical security vulnerability called Cross-Site Scripting, or XSS for short, with source code (on ASP.NET MVC) and step-by-step instructions to let you execute different types of XSS injection attacks.

The Zero Trust Thinking series is brought to you by ASPSecurityKit, the first true security framework for ASP.NET and ServiceStack built from scratch on the Zero Trust model.

Zero Trust Thinking series

Note

The source of this hands-on article is this comprehensive guide (Protecting Your Users Against Cross-Site Scripting (XSS) Attacks).

What is XSS?

A site, vulnerable to XSS, allows an attacker to inject and execute a piece of JavaScript code, let’s call it an XSS code, on the victim user’s browser, when the victim visits the vulnerable portion of that site.

For a moment, just imagine the consequence of such an attack. If it’s your bank website, the attacker can inject a code that could read sensitive data of your account, such as financial transactions, account balance, and even the login cookie, and send it to the attacker; if the attacker gets your login cookie, he can impersonate you, which gives him full access to perform actions on your account.

Watch it as a video instead

Ways to XSS or types of XSS

Now we know what XSS is, we’d surely like to know how we can protect our applications against it. However, to effectively fortify against an enemy, we need to know its capabilities or the possible ways that this enemy can strike us.

There are broadly three ways to inject an XSS code, which form the basis of classifying XSS into three types. These are known as Stored, Reflected and DOM based XSS. In this article, we’ll demonstrate each of these three types with a sample code available here.

Get ready with the code!

Follow the steps on the readme page of the repo to setup the code on your machine. Briefly, you would need Visual Studio 2019 or higher, clone or download the repo, and then open ZTT.XSS.Attacks solution inside the cloned repository.

After this you also need to create the database with the update-database EF Core command.

update-database

This web app, built on ASP.NET Core MVC, represents a simple classified marketplace where registered users can post, browse and buy classified items or products.

To get ready, press F5 to run the project. Let’s register two users:

  1. Attacker: Use an email like [email protected]; Email verification isn’t required.
  2. Victim: Open a new incognito or private window, and register the other user – [email protected]. Keep both the attacker and victim browser windows open for this demo.

1. Stored XSS

With Stored XSS, the XSS code makes way into the site database and is permanently stored over there – hence the name. Subsequently, it is served as code as part of the HTML response to the victim users by the site.

This method has the widest attack surface as every user of the site who happens to browse the infected data, will end up executing the XSS code.

Follow the below steps to execute this attack:

  1. On the attacker window, go to the products page, and click on ‘Create New’.
  2. An attacker would usually enter a catchy name, to attract maximum number of users, so enter ‘New iPhone for just $199’.
  3. In the description, type ‘Brand new iPhone’, followed by this XSS code:
<script>alert(document.cookie.substr(document.cookie.indexOf('AspNetCore.Identity.Application')));</script>

Note

This XSS code reads your login (ASP.NET Identity) cookie, and simply shows it in an alert box. In the real world, the attacker would simply send this cookie to a remote server that belongs to the attacker, via an AJAX call or something similar, without the victim having any clue.
  1. Now enter the amount $199, and click on the Create button.

    New Product form filled  with infected data

  2. The infected deal has been created successfully and as an attacker, you can see the product in the list.

    Products list with infected iPhone deal being shown

  3. Just to verify that the attack is working, we open the details page, and we can see our login cookie in the alert box.

    Alert box with attacker's ASP.NET Identity cookie

  4. Next, let’s keep this window as is, and let’s switch onto the victim browser window.

  5. So as a legitimate user, you open the products page to hunt for the new deals, and the iPhone deal can’t go unnotice because of its cheap price. As you click on the details to learn more about the deal, the XSS code is executed and your login cookie is in the hands of the attacker. You can confirm that this is the victim’s user cookie, because it’s different from the attacker’s user cookie we’ve already seen earlier.

    Alert box with victim's ASP.NET Identity cookie

  6. If you dismiss the Alert, you can see, as a victim user, you’re only seeing a perfect product description on the page.

    iPhone product details page highlighting description field

  7. In the real-world, the XSS code would have silently sent your login cookie to the attacker’s server.

2. Reflected XSS

With Reflected XSS, the XSS code goes to the server as part of a request and is immediately reflected back by the server in its response.

This type of attack requires the victim user to execute such an infected request, usually by following some malicious link or posting a malicious form.

Coming back to our example, suppose our site has a protection against injecting Stored XSS. The attacker may then look for a reflected XSS vulnerability. He crafts an invalid URL for the vulnerable classified site, and infects it with the same XSS code we’ve seen with Stored XSS.

https://[domain]:[port]/Products1<script>alert(document.cookie.substr(document.cookie.indexOf('AspNetCore.Identity.Application')));</script>

He can then share the URL as a part of an enticing email or as a post on some people forum, with a hope that some users will click it.

Lets look at a simple simulation of user clicking such an email with the xss link.


As you can see above,

  1. The site opens with 404 error and the XSS code has successfully executed, capturing our login cookie.

    404 response page with Alert box showing ASP.NET Identity cookie

  2. Click on the Ok to dismiss the alert dialog. You can see that our URL is being shown as part of the invalid URL message, but without the XSS code because that got interpreted as a proper code by the browser and was executed as such.

    show the 404 page content – highlighting the invalid URL sentence

Though the Reflected XSS injection seems to have a limited attack surface when compared to Stored XSS, because it depends on victim users following a malicious link for example, but in the current age of heavy social media usage, getting people to click on enticing offers in large numbers isn’t difficult by any stretch of imagination.

3. DOM based XSS

With DOM based XSS, the XSS code makes way into the user’s browser execution engine via DOM injection and is never part of the server’s response body unlike Stored/Reflected XSS. The server may or may not see the malicious code.

This type of attack requires the victim user to execute such an infected request, usually by following some malicious link or posting a malicious form.

It is more difficult to identify DOM based XSS as it doesn’t appear in the response.

Coming back to our example, suppose our classified site has a protection against injecting both Stored and Reflected XSS. The attacker may then look for a DOM based XSS vulnerability.

Our Product Details page has a way to accept discount code in the query string, but the discount isn’t applied by the server; instead, the client-side JavaScript code reads it and simply displays it. The actual discount in amount is supposed to be calculated and shown on the checkout page.

Moreover, the classified site keeps the discount feature hidden and only displays its block if the URL has the code. However, this business requirement has led to a DOM based XSS vulnerability that the attacker will exploit.

He crafts a valid product URL for the vulnerable Details page on the site, and infects it with the same XSS code we’ve seen with other two XSS types.

	https://[domain]:[port]/Products/Details/c7aeecbe-d4e9-4a7e-849c-aa9fdf27755d?discountCode=magic42<script>alert(document.cookie.substr(document.cookie.indexOf(%27AspNetCore.Identity.Application%27)));</script>

He can then share the URL as a part of an enticing email or as a post on some people forum, with a hope that some users will click it.

To keep it simple for our example, let’s imagine the victim clicks the infected URL from an email.


As you can see above,

  1. The Product Details page is opened and the XSS code has successfully executed, capturing our login cookie.

    Product details with Alert box showing ASP.NET Identity cookie

  2. Click on the Ok button to dismiss the alert dialog. You can see that the discount code ‘magic42’ appears, but without the XSS code because that got interpreted as a proper code by the browser and was executed as such.

    Product details page with discount code highlighted

Conclusion

To conclude, in this article of the Zero Trust Thinking series, we’ve learnt about what is Cross-Site Scripting, also known as XSS. We went through three different types of XSS and demonstrated each of them with a real-world example.

We’ve also understood the adverse consequences of a successful XSS attack, and we’re ready to learn the techniques and best practices to guard our sites against it.

Our approach will be based on the Zero Trust security model, as we’ve already seen that a vulnerability in any layer of the application can lend itself to XSS exploit. More about it in the upcoming articles !

The Zero Trust Thinking (ZTT) series

ZTT is brought to you by ASPSecurityKit, the first true security framework for ASP.NET and ServiceStack built from scratch on the Zero Trust model.

Leave your email below to receive a notification of new ZTT articles and videos right in your inbox, once every two weeks or so.


Credits

  1. Varun Om contributed with the walkthrough content, concepts and architecture for the sample.
  2. Abhilash contributed with images and sample source code.

Need help?

Looking for an expert team to build a reliable and secure software product? Or, seeking expert security guidance, security review of your source code or penetration testing of your application, or part-time/full-time assistance in implementation of the complete web application and/or its security subsystem?

Just send an email to [email protected] with the details or call us on +918886333058.

Related tags

Zero Trust , ZTT , Cross-Site-Scripting , XSS , Attack-Simulation , Stored-XSS , Reflected-XSS , DOM-XSS