Security is one of the most important subjects when creating some business (not necessary a web business or even computer related).
think about investing lot of time developing your business, and then seeing it all ripped apart, just because a sensitive information was reviled to some unwanted individuals, or even worse, gone global to the public.
Of course, security in not only related to stealing data, messing with the business reputation can be devastating just as much as the mentioned above.
When developing Web applications, security is highly important due to the reason that the application is running in the most hostile environment, I mean, everybody can access it, meaning that everyone is a potential threat to the system.
Cross Site Scripting (AKA XSS) is one of the known and ancient methods to exploit security holes on the web.
The idea of the method is injecting client side script code to a web application, which will perform an additional task at the client side.
It may seem to some as a harmless thing, but actually, it can trigger much dangerous attacks such as session hijacking, one-click attacks and Phishing.
Well, this post actually not about how to conduct an XSS attack, but how to avoid being an XSS victim.
So, what do you have to do in order to prevent XSS? - INPUT VALIDATION.
Let's take a look what does the .Net framework has to offer on this matter
- ValidateRequest – page directive
- Built-in .Net validation controls (such as "required field validator", "Range Validator", and so…)
- Server Side validation.
ValidateRequest directive – Enabled by default, supposed to "protect" All the input to the page from XSS.
It looks for "<" and ">" tags, probably by some regulars expressions, the problem with this option is that it limits ALL inputs, even the intended ones (such as XML, HTML tags and so…).
Built-in .Net validation controls – The framework provides probably all the input validation that you will need when writing it.
Starting from required fields, numerics values, Regular expressions, and even write your own custom validation.
The problem with it, that it gives the developer a feeling that once the validation is made, it can't be tempered by the client, which IS NOT TRUE.
Note that the common use of these tools is on the client side, which makes the whole validation process irrelevant.
Ask yourself as a developer if you setting the "EnableClientScript" property on the validation control when you use it? – The common answer will be yes, because it improves performance by saving round trips to the server.
But if the question would be, have you did some extra coding to ensure server side validation to occur? – Unfortunately, the common answer will be NO.
Note to yourself – This is no' 1 reason for XSS vulnerabilities in ASP.NET applications.
Server Side validation – This is where your coding skills starts to kick in.
This is where you need to stop, and start thinking about security for your application.
A rooky developer will probably go straight to developing a page , neglecting the security aspect, while the more experienced developer will design a total solution, considering many aspects of the application, security would be one of the top issues (if not the first).
Lets see some examples :
Lets create this asp.net page :
<%@ Page language="c#" validateRequest=false Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="SecurityExample.WebForm1" enableViewStateMac="True"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm1</title>
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
<meta content="C#" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<asp:textbox id="TextBox1" style="Z-INDEX: 101; LEFT: 96px; POSITION: absolute; TOP: 48px" runat="server"
MaxLength="5" Width="160px"></asp:textbox>
<asp:regularexpressionvalidator id="RegularExpressionValidator1" style="Z-INDEX: 102; LEFT: 320px; POSITION: absolute; TOP: 56px"
runat="server" Width="144px" ValidationExpression="\d{5}" ControlToValidate="TextBox1" Height="40px" ErrorMessage="Numbers with 5 digits only"></asp:regularexpressionvalidator>
<asp:button id="Button1" style="Z-INDEX: 103; LEFT: 128px; POSITION: absolute; TOP: 144px" runat="server"
Width="112px" Text="send data"></asp:button>
<asp:label id="lblOutput" style="Z-INDEX: 104; LEFT: 112px; POSITION: absolute; TOP: 192px"
runat="server" Width="136px" Height="16px" EnableViewState="False"></asp:label></form>
</body>
</HTML>
lets add some PageLoad code behind :
private void Page_Load(object sender, System.EventArgs e)
{
// Check if the current run is postback
if (IsPostBack)
{
lblOutput.Text = "this is a postback<br>";
// Activate the page validation
Page.Validate();
// Check if the page is valid
if (Page.IsValid)
{
lblOutput.Text += "Page is Valid!";
}
else
{
lblOutput.Text += "Page NOT valid";
}
}
else
lblOutput.Text = "this is NOT a postback<br>";
}
Lets look at the code in the page_load method:
Q : I'm calling here to the page validation manually, Why ?
A : The complete process is combined with the following operations :
- Client side validation
- Postback to the server
- Page Initialization
- Page_Load method invoked
- Desired action invokes the attached method to it (button_click)
- when the associated control of the action has a causesValidation property set to true, the action invokes the Page.Validate()
method which check the validation of the page, and sets the Page.IsValid property to true or false if the validation succeeded or not respectively
- Logic associated with the action of the control is being executed
Suppose the user has managed to cconduct some validation tempering on the client side (this is really not a hard task to acomplish),
and posted the data manually as a postback.
The server gets the posted data and addresses it as a postback from the page, and it begins to proccess the data, invokes the Page_Load (with absolute no indication if the data is valid or not), executes the Page_load method completly invokes the given operation(say button_click) and executes it completely.
This way if we wont comit Page.Validate() and then check the Page.IsValid method , we are risking here with an XSS vulnurability.
Q : So, what is the best way to conduct a server validation ?
A : First, create those validators as you always do.
Then apply this code on your page (or your master page) :
Page.Validate();
if(!Page.IsValid)
throw new Exception("Security Exception occured");
you can do some other handling besides throwing an exception, like logging, tracing, a nice message to the user and so on.
Note that this actions will protect you at the Presentation layer but not further ( at the DAL - sql injection , or the Session layer - Session hijacking and more....)
Here are 10 base guidelines to prevent being an XSS victim :
- Never write to page unfiltered data.(or encoded)
- Never write to the page straight from the user input.
- Before handling input, Validate that it is really what you are expecting for.
- Don't expose exceptions to the client.
- Don't expose Any internal information about the application to the client.
- Never rely on client side validations.
- Know the existing threats and vulnerabilities.
- Don't use built-in features if you're not completely understand what they are doing.
- Try to think "out of the box" in security related issues
- Handle security issue by design, not by mistake.