Cross-Site Scripting (XSS) is a web security vulnerability by which a malicious user is able to inject content into a web page that will impact other website visitors. The injected content could then perform any number of unwarranted acts, including hijacking the user’s session, stealing private information, or performing a denial-of-service attack. An XSS exploit often involves manipulating an online form that presents some piece of the input back to the user, such as a search form. In this post we’ll explore some strategies to assist developers with mitigating XSS vulnerabilities, including input validation, sanitation, and output encoding.
Cross-Site Scripting Vulnerabilities
The classic XSS security exploit involves tricking a webpage to execute malicious Javascript code, which exposes the user’s authentication cookies to another website, all without the user’s knowledge. This allows the owner of the malicious website to then spoof the user’s log in session on the original web site, effectively allowing them to hijack the original user’s session and gain access to their account and information. On an e-commerce site, the attacker could gain access to the user’s address or payment information, and potentially even place fraudulent orders. Another form of a XSS exploit can be used to launch a denial-of-service (DOS) attack against a website. This exploit involves injecting a <meta http-equiv=”refresh”> tag into the page, or Javascript that makes AJAX requests or alters the window.location. By refreshing the page very quickly, or by making large number of web requests, it is possible to overload a website’s server.Mitigation Strategies
The specific techniques for mitigating XSS vary by the server-side framework (PHP, ASP.NET, etc.) in use. However, the overarching concept is very straight-forward: never trust user input. Before working with any value that comes from the client (form fields, the URL query string, cookies, and HTTP headers) the value must be validated to the best of the application’s ability. It is important to remember that validation must take place on the web server. Client-side validation techniques are for a legitimate user’s benefit – to help catch any errors or omissions without the need for a network round-trip. Nothing is preventing an attacker from disabling Javascript, or even crafting an HTTP request without using a web browser at all. Server-side validation can take many forms:- Expecting a numeric identifier? Try converting the value to a number. Check that it is within the expected range (e.g. non-negative, non-zero)
- Is the value expected to be one out of a few possible values, such as with a checkbox list? Verify that the selected value(s) are in fact among of the possible options.
- Need to accept HTML from the user? Sanitize the input by ensuring that any <script> tags and other potentially malicious code is removed.
Mitigating XSS with ASP.NET
We’ll be looking at some specific strategies for mitigating XSS utilizing ASP.NET – both the WebForms and MVC frameworks. These strategies include validation, output encoding, and sanitation.ASP.NET Input Validation
By default, ASP.NET applications throw an HttpRequestValidationException in the event that HTML (or other potentially malicious values) are detected in the user input, which terminates the request. Of course, such a blanket strategy can’t cover every possible case – further validation will be needed to ensure that input matches expectations. Additionally, some applications need to be able to work with HTML, such as Web Content Management Systems (CMS). In these cases, the CMS may disable this validation option entirely – even for other pages in the application. It is important to keep this in mind when implementing custom functionality on a CMS-based website. Besides disabling the request validation option globally, there are several options for temporarily lifting validation for specific needs. WebForms pages have a ValidateRequest attribute that can be set to “false”, and MVC controller actions can be decorated with a [ValidateInput(false)] attribute. Individual MVC view model properties can also be decorated with [AllowHtml] for granular control. By opening only specific pages or components of pages that need to allow HTML the developer can ensure that the remainder of the application continues to benefit from built-in validation. In addition to the built-in validation logic, the application itself should validate specific values to ensure they meet expectations. Let’s look at a brief example of resolving an XSS vulnerability. Consider the following method:The code does several things well:- Ensures the query string values are not null.
- Converts one parameter to a static type - integer (although, it does not do so safely).
- Since the “ContentTypeId” parameter is not safely converted to an integer, the possibility exists for a runtime exception to be thrown, which in turn could show an attacker valuable information such as a stack trace.
- The parameter “ContentId” is not sanitized, and as such this code is vulnerable to an XSS attack.