Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Hack Proof Your ASP.NET Application From Cross Site Scripting (XSS)

4.73/5 (43 votes)
8 Jul 2013CPOL6 min read 203.3K   2.9K  
This article describes what XSS is and how to prevent XSS attacks.

Introduction

This is part 2 of my series Secure your ASP.NET Applications. In this article, I will describe what exactly Cross Site Scripting (XSS) is and how a hacker exploits it and how we can prevent XSS attacks.

Background

Part 1 of this series is available here which is about how to secure your ASP.NET applications from SQL injection attacks.

Cross Site Scripting (XSS)

Cross-Site Scripting is a kind of security exploit in which the attacker inserts malicious code of his choice (mostly script) into a web page or a database without the user's knowledge. XSS in itself is a threat which is brought by the internet security weaknesses of client-side scripting languages, with HTML and JavaScript (others being VBScript, ActiveX, HTML, or Flash) as the prime culprits for this exploit.

We can categorize XSS as follows:

  1. Reflected (when malicious code goes from the user's browser to the server and comes back from server)
  2. Persistent (when code remains stored somewhere, example - code stored in a database and executed on the client browser over and over, which makes it more dangerous).
  3. DOM based XSS attack (both reflected and persistent can fall in this category, attacker can manipulate DOM elements and can use DOM data).
What can these attacks do:
  1. Create and access DOM elements
  2. Send information to attacker site
  3. Hijack cookies, click events, credentials

How is it exploited

Following are the ways an attacker tries XSS on a web application:

  1. It can be done from server side code (example: ASP.NET code)
  2. It can be done from client side code (JavaScript/jQuery code)
  3. Attacker can inject script into user's experience

1. Reflected Cross Site Scripting Attack

In this kind of attack, the attacker generally tries to send script or HTML input to the server and lets it come back to the browser and run. They achieve it using a querystring. Although all latest browsers apply XSS filters, HTML elements can be inserted using this attack. Also to test, you can enable XSS filters in browsers; for IE - Tools > Internet option > Security tab > Custom level > Enable XSS filter. Let's see how to do it so things will be more clear:

ReflectedXSS1

In the above example I simply pass the HTML in the query string which gets reflected in the web page. This is just to show the attacker can use proper scripts with intention to get your credentials.

ReflectedXSS2

In the above example we are passing an HTML element and script in our label which gets assigned as it is and becomes a legal script, and the element for a page gets reflected in our page and shows the effects. This is just a basic example of how an attacker tries Reflected XSS, scripts, and their use can be too harmful.

2. Persisted Cross Site Scripting Attack

In persisted attack, the user injects a script to the database and every time the user visits that page he faces the consequences of that script. Example:

pesistedXSS

Script injected in the Comments section:

XML
hiii this is text
<link rel="stylesheet" 
  href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
//these scripts are innocent (Just opening the pop up),
//that's the developer cause who developed vulnerable web applications .
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
 <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
 
  <script>
  $(function() {
    $( "#dialog" ).dialog();
  });
  </script>
 
<div id="dialog" title="Session Out please login again">
 <input  type="Text" placeholder="login"/><br/>
  <input  type="Text" placeholder="login"/><br/>
  <button>

3. DOM based Cross Site Scripting

Both persistent and reflected can fall in this category, but some other variances of attacks make it different. Some developers do think JSON is safe and some use jQuery unsafe methods. How they use it:

C#
//Encoded String using  Microsoft.Security.Application.Encoder.JavaScriptEncode
var json = jQuery.parseJSON('{"name":"sarvesh", 
  "girlfriendname":"\x3cscript\x3ealert\x28\x27hehaha\x27\x29\x3c\x2fscript\x3e"}');
var createelement = document.createElement('div');
document.body.appendChild(createelement);
//we should not use this html , we can use text instead of this
$(createelement).html(json.girlfriendname);
//it will show the alert 

Image 4

As attacker is not inserting a direct script, he is inserting an encoded string which contains a script. These are new ways an attacker finds to exploit XSS. Or we can use a direct encoded string, I just use JSON to show this; this is also not a safe way.

C#
var jencoded = "\x3cscript\x3ealert\x28\x27hehaha\x27\x29\x3c\x2fscript\x3e";
//this will give the same result

Another way of attack comes under this category, i.e., using HTML elements and JavaScript code without a script tag. The developer tries to find the script tag or <> these characters and replace them to avoid XSS but that is not a full proof way. The following example shows that.

Sometimes we need to show a dynamic alert:

XML
<img onmouseover=alert(user input) /> 

The user can give input in a SQL Injection manner like this:

XML
<img onmouseover=alert(1) onmouseout=alert(document.cookie) > 

Now he can see the cookies you are saving, and that might be user credentials or any important data.

How to prevent XSS

  1. Your code output should be HTML encoded but make sure while storing data, it should not be encoded. Encoding and storing can lead to double encoding.
  2. XML
    < => &lt; => &amp;lt; => &amp;&amp;lt;  

    So for encoding we can use AntiXss sanitizier's GetSafeHtml() and GetSafeHtmlFragment(). To download AntiXss, go to MS Visual Studio's Tools > Library Package Manager > Package Manager Console > Install-Package AntiXss.

    Sanitizer.GetSafeHtmlFragment(YourString) 

    Sanitized

    It's better to use these methods if we really don't encode data.

  3. Specify page encoding in web.config because the attacker can change the encoding to UTF-7 which has a different standard to write the lines and can make it tough to filter out the script code in the page.
  4. XML
    <configuration>
       <system .web="">
          <globalization culture="en-US" fileencoding="utf-8" 
            requestencoding="utf-8" responseencoding="utf-8" uiculture="de-DE">
       </globalization></system>
    </configuration>
  5. Apply content security policies to allow the script of your own host, or to allow the script of any host like Google and Microsoft. We can add a header to stop scripting from the attacker site or any third party site.
  6. Although it is not full proof because IE does not support this, but we can still use this as an additional thing to stop XSS. Add the following code to allow scripts just from your host.

    C#
    Response.AddHeader("X-WebKit-CSP", "default-src 'self'");
    // experimental header introduced into Google Chrome
    // and other WebKit based browsers (Safari) in 2011
    
    Response.AddHeader("X-Content-Security-Policy", "default-src 'self'");
    //experimental header introduced in Gecko 2 based browsers
    // (Firefox 4 to Firefox 22, Thunderbird 3.3, SeaMonkey 2.1).
  7. Do not use filter approach to find the script tag and replace that, there are many cheat-sheets available on the internet for XSS. A simple example that an attacker can use: onload=alert('anything').
  8. Data validation: you can't trust the user input, just make sure the data is exactly what your application expects.
  9. Don't set the ValidateRequest attribute to false. When it is true it might throw an error; to prevent this error make sure your data is properly encoded before sending it to the server.
  10. Be concerned where DOM elements are being created and modified. Use functions such as setAttribute and document.createElement('div') rather than document.writein and $('div').html().
  11. Force the user to update IE 6 which is very much vulnerable to XSS. IE6update.com is a better solution for that.
  12. Audit every place where data is assigned. Know your control behavior as a label can't post the values and text-box can. So better encode text-boxes first. You can use a third party control to check the vulnerability; for Firefox use XSS-ME and for Chrome can use DOM-SNITCH.
  13. Update yourself on regular basis ,check new ways of the same attack. The attacker invents new ways to do the same attack in their spare time. OWASP has a very good cheat sheet and defense for XSS. OWASP has regular updates about these attacks.
  14. Know ASP.NET encoding ways and use proper config statements to make changes.

Antixss

All the above mentioned methods are useful to prevent XSS attacks.

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)