This blog post I want to talk about preventing the hacker from using XSS attack in ASP.NET applications.
The first defense is using ValidateRequest. By default Microsoft sets the ValidateRequest to true.
<%@ Page Title="" Language="C#" ValidateRequest="true" MasterPageFile="~/Demo.Master" AutoEventWireup="true" CodeBehind="Demo.aspx.cs" Inherits="XSS_Demo.Demo" %>
That is a good thing but it can cause of problems later on; the reason is it gives the programmer a false sense of security. Writing secure code is about intent. When we rely on default settings to control the behavior of how web pages validate input we rely on other people to make our code is secure and we are no longer coding with intent. Second issue is we are no longer relying on a proven security principle of “Defense-in-Depth”. We understand that with any security mechanism it can and will be broken. The security mechanism may not have a current vulnerability known at the present time but over time the cyber criminal’s have proven they can find one or a work-around. So we always want a backup security mechanism. Our goal is simple and proven. When one security defense mechanism fails we have another. Making the effort for the cyber criminal increasing difficulty so he goes elsewhere.
Another reason why we don’t want to rely on ValidateRequest is web applications have a trend to become more complex with consecutive deployments into production with more and more complex user interaction. Down the road someone is going to need the user to be able to input the following characters “</>into a user control. As soon as that happens we get the error message “A potentially dangerous Request.Form value was detected from the client”. To resolve this error we need to set ValidateRequest to false and now our application is open to XSS attacks. Now we have a decision, how are we going to provide the security against XSS attack vector? In my opinion when we bolt on security to an application already in production we have already lost some of the potential to make our application secure. I understand with an ever-changing production environment, business requirements changing, etc, some decisions will affect the architecture of an application in production. However that is not the case here.
As a defense-in-depth mechanism we need to sanitize all data from our users. All data from users should be considered to be untrusted data. It should not be dependent on if the application is external or internal facing to our organization. If you don not have initial control/creation of the data it is untrusted.
Our next defense-in-depth mechanism that we should have in place from the beginning of the application is to verify the data is correctly formatted using a regular expression. We have two choices here; we can validate against bad input characters or validate for expected input. The best choice is to validate for expected input.
The other choice leaves us open to the cyber criminal’s expertise in obfuscating his attack to our regex filter. The following is just a sample of how the cyber criminal can obfuscate his attack.
<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">
<DIV STYLE="width: expression(alert('XSS'));">
<HTML><BODY><?xml:namespace prefix="t" ns="urn:schemas-microsoft-com:time"><?import namespace="t" implementation="#default#time2"><t:set attributeName="innerHTML" to="XSS<SCRIPT DEFER>alert("XSS")</SCRIPT>"></BODY></HTML>
<SCRIPT>document.write("<SCRI");</SCRIPT>PT <A HREF="http://220.127.116.11/">XSS</A>
<A HREF="htt p://6	6.000146.0x7.147/">XSS</A>
// "\%3C|<") // catches first <
// "\%3E|>") // catches first >
// "((\%2F)|\/)") // catches forward slash inside closing tag
static Regex regExample = new Regex(@"((\%3C)|<)((\%2F)|\/)*[a-z0-9\%]+((\%3E)|>)");
The reader can try for him self to see if the above regex expression catches the above XSS script injections.To see a more extensive list on ways to obfuscating XSS attacks please see http://ha.ckers.org/xss.html or OWASP XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
AntiXSS/Web Protection Library:
We have one more option in our arsenal to help make our application secure that we should be using from the beginning. That is encoding. We can use HtmlEncode. HtmlEncode part of standard .NET framework that uses a blacklist approach to encoding, filtering out known bad characters, like <> and “ characters. We can give our self’s extra protection and greater flexibility by using Microsoft AntiXSS library; which has been rename “Web Protection Library WPL”. Web Protection Library has a lot of encoding functions that will help you prevent XSS attacks in ASP.NET applications. AntiXSS library uses a whitelist of known good characters. AntiXSS also has protection in place spanning characters sets in over different languages. Due to this approach, AntiXSS is inherently safer against new XSS attacks. Furthermore to my first point in this blog by using Microsoft Web Protection Library you are now coding with intent on writing secure code.
Resources Web Protection Library: