5 Tips for Preventing Cross-Site Scripting (XSS) Vulnerabilities in ASP.NET Web Applications

Jakob
6 min readFeb 4, 2019

--

This article will briefly discuss a notorious vulnerability known as cross-site scripting (XSS) and provide 5 tips to help you prevent it in your ASP.NET Web Application.

A cross-site scripting vulnerability allows an attacker to inject malicious scripts into websites. The consequences of this attack can be devastating since it can allow an attacker can do things such as steal sensitive data and spread malware. There are three types of cross-site scripting attacks which I will mention briefly.

Stored XSS

A stored XSS attack happens when the cross-site scripting payload has been stored somewhere such as in a database or local storage. The payload can then be triggered when someone retrieves it from storage.

Reflected XSS

A reflected XSS occurs when the cross-site scripting payload is served as a part of a request. This kind of cross-site scripting attack can be present in search results and user inputs where data is reflected back on the website.

DOM-based XSS

This type of cross-site scripting attack occurs when the payload is triggered by modifying the HTML DOM.

Cross-site scripting is the seventh most dangerous vulnerability according to the OWASP Top 10 most critical web application security risk list. This is a very common attack. Positive Technologies found that cross-site scripting was used in 29.1% of web attacks they examined in Q1, 2017. This can be seen in more detail in the image below.

(Source: https://www.ptsecurity.com/ww-en/analytics/web-application-attack-statistics-q1-2017/)

Now let’s take a look 5 helpful ways to prevent this vulnerability.

1. Use a cross-site scripting sanitizing library such as AntiXSS and use it correctly.

This library has many methods to help prevent cross-site scripting attacks by white-listing certain characters and encode everything else. Some people might think they can use a cross-site scripting encoder and then put the data anywhere into HTML after encoding it. This however couldn’t be further from the truth. It’s important to use relevant cross-site scripting filter methods based on where the untrusted data will be put and how it’s put there. For instance, before inserting untrusted data into HTML attributes, the method AntiXSS.HtmlAttributeEncode should be used, which is specifically designed to prevent an attacker from escaping an HTML attribute. Methods such as AntiXSS.HTMLEncode should be used before adding untrusted data inside HTML elements. However, if you would use the HTMLEncode method for untrusted data and insert it into a URL, then it might leave security holes in your web application since the HTMLEncode method is not designed to prevent cross-site scripting attacks for URLs.

This library is available under the namespace System.Web.Security.AntiXSS after ASP.NET version 4.5. However, prior to version 4.5 you will have to download it as a NuGet package. Then you can go ahead and add the code below to your configuration file (with a relevant targetFramework).

<system.web>
<httpRuntime targetFramework=”4.5" enableVersionHeader=”false” encoderType=”Microsoft.Security.Application.AntiXssEncoder, AntiXssLibrary” maxRequestLength=”4096" />

2. Be careful when mixing Razor variables and JavaScript.

The Razor syntax is based on the ASP.NET framework and is a way to embed server code into web pages. This allows developers to also add razor variables directly into JavaScript code. This should be done cautiously as it can introduce security loops if not done right.

For instance, let’s say we have a JavaScript function that receives a parameter called parameter1. Using the razor syntax, parameter1 is written as @parameter1 and is directly inserted into quotes as a function parameter in this example.

Function functionName(“@parameter1”){

}

If an attacker would insert a backslash ( \ ) into the parameter, then the quote ( “ ) would be escaped which would allow an attacker to write malicious JavaScript into the program. This is possible because backslash is treated as an escape character in JavaScript, so any character or symbol coming after a backslash will be treated as a string, not code. Many cross-site scripting sanitizers won’t treat backslash as a malicious character and it will therefore not be encoded so they would not prevent this attack(unless they are designed for JavaScript encoding).

It’s not uncommon to see developers insert razor variables straight into JavaScript functions and variables like this. In some cases it’s safe, especially after dangerous characters have been escaped, but that depends on the context. A safer alternative to the example above would be to insert the data into an HTML element attribute after it has been properly encoded using a cross-site scripting sanitizer designed for HTML attributes, such as the AntiXSSEncoder.HtmlAttributeEncode method. After the data has been safely inserted into an HTML element attribute, we can retrieve it from the element attribute using JavaScript. The example below shows how this can be achieved.

<input type=”hidden” id=”getData” data-untrustedinput=”@parameter1" />
<script>
let data = document.getElementById(“getData”);
let parameter1Safe = data.dataset.untrustedinput;
//we have now successfully retrieved the data
</script>

Another way would be to use a cross-site scripting library methods that are designed to encode input before being inserted into JavaScript.

3. Use validation

Validating data can be an effective prevention for cross-site scripting. For instance, a regular expression allowing only numbers would successfully filter out malicious scripts. However, do not make a habit of relying solely on validation as there are often cases where validation does not prevent all possible types cross-site scripting attacks.

You can click here to see more guidance on how to use validations in ASP.NET

4. Use appropriate HTTP Headers

HTTP headers are a part of requests and responses used for data communication on the internet. They can instruct the browser to treat data in a certain way and include instructions that can help with increasing the website’s security.

The HTTP header X-XSS-Protection will instruct the browser to enable a cross-site scripting filter which can prevent certain cross-site scripting attacks. Either one of the following values are recommended for the header:

X-XSS-Protection: 1;orX-XSS-Protection: 1; mode=block;

By giving the header a value of 1, the page will be sanitized if a cross-site scripting attack is detected. By adding a “mode=block;” value to the header, the page will be stopped from rendering if a cross-site scripting attack is detected.

To add this HTTP header to your ASP.NET application, simply add the code below into your web.config file, inside <system.webServer>.

<httpprotocol>
<customheaders>
<add name=”X-XSS-Protection” value=”1; mode=block” />
</customheaders>
</httpprotocol>

The Content-Security-Policy HTTP header can also help with preventing cross-site scripting attacks by disabling the use of inline scrips. Inline scripts are scripts that are added directly to the HTML markup, in contrast to referencing a script from your HTML code. Attackers often use inline scripts when they are executing cross-site scripting attacks. For instance, the inline script shown in the code below will display an alert box on the screen with the text, “you have been hacked”. This is a demonstration of how an inline script can be used to execute code in a website by an attacker.

<body>
<script>alert(“you have been hacked”)</script>
</body>

The Content-Security-Policy header can do much more than only disabling inline scripts. The header can control what domains and sub-domains can send requests to our website and much more. I will introduce an example of this header that can disable inline scripts and only allow scripts to be loaded from the originating server here below

<httpprotocol>
<customheaders>
<add name=”Content-Security-Policy” value=”script-src ‘self’” />
</customheaders>
</httpprotocol>

You can read more about this header here.

5. Insert data safely into your HTML

It’s important to manipulate the HTML DOM safely and use safe methods in order to prevent DOM-based XSS and other XSS attacks. It would be possible to write a separate blog post or even a whole dissertation on this part alone. There are multiple methods that are available to use when dynamically inserting content into HTML markup and some of them are more prone to cross-site scripting attacks than others.

For instance, when we want to add text to an HTML element, then we should use a method that will guarantee that anything we put into the element will be treated as a text and not HTML code. The first property below will treat all input as text content while the second property is capable of receiving text content and HTML elements, which makes it prone to cross-site scripting attacks.

document.getElementById(“id”).textContent = “user data”;document.getElementById(“id”).innerHTML = “user data”;

I hope you took something of value from this article and I wish you all the best in defending your web applications against malicious users.

Happy coding.

--

--

Jakob

Jakob is a full stack developer. MSc in Cyber Security and BSc in Computer Science.