Real World XSS Vulnerabilities in ASP.NET Code
RV here again...
From couple of weeks we have been seeing some XSS vulnerabilities in asp.net code. Today I wanted to show you guys some real world examples ranging from property assignments, data binding and JavaScript building. For each example, I will offer both the vulnerability and mitigation which is very useful in self reviews. Before I say anything further, I want to caution you by saying that the following code examples must never be used in any application.
Example #1
In this case, we are simply using the user input directly in a label. The following is the vulnerable code.
1: string strUsername = txtUsername.Text;
2: string strPassword = txtPassword.Text;
3: if (AuthenticationClass.Authenticate(strUsername, strPassword))
4: {
5: //Set auth cookie and redirect, always use FormsAuthentication.SetAuthCookie
6: }
7: else
8: lblMessage.Text = string.Format("{0} is not found, click here to register!",
9: strUsername);
Line 8, the username is directly being used to output the message. The following code fixes the vulnerability.
1: lblMessage.Text = string.Format("{0} is not found, click here to register!",
2: AntiXss.HtmlEncode(strUsername))
Example #2
In this case, we are data binding data from a database.
1: //Probably the most common code that is vulnerable to XSS
2: //This is persistent XSS vuln, a very dangerous as one
3: //user attacks and many users will get exploited.
4:
5: <asp:Repeater ID="repFeedback" runat="server" >
6: <ItemTemplate>
7: <p><asp:Label runat="server" ID="CommentsLabel" Text='<%# Eval("Comments") %>'/>
8: <br /> - <i><asp:Label runat="server" ID="NameLabel" Text='<%# Eval("Name") %>'/>
9: (<asp:Label runat="server" ID="EmailLabel" Text='<%# Eval("Email") %>'/>)</i></p>
10: </ItemTemplate>
11: </asp:Repeater>
Line 7-9 are vulnerable to XSS. Fortunately there is a very simple way to fix, which is shown below.
1: <asp:Repeater ID="repFeedback" runat="server" >
2: <ItemTemplate>
3: <p><asp:Label runat="server" ID="CommentsLabel"
4: Text='<%# AntiXss.HtmlEncode(DataBinder.Eval(Container.DataItem, Eval("Comments"))) %>'/>
5: <br /> - <i><asp:Label runat="server" ID="NameLabel"
6: Text='<%# AntiXss.HtmlEncode(DataBinder.Eval(Container.DataItem, Eval("Name"))) %>'/>
7: (<asp:Label runat="server" ID="EmailLabel"
8: Text='<%# AntiXss.HtmlEncode(DataBinder.Eval(Container.DataItem, Eval("Email"))) %>'/>)
9: </i></p>
10: </ItemTemplate>
11: </asp:Repeater>
Also, please note that DataBinder.Eval and Eval are slow as they use reflection to parse the expression. A better option is to use the Container.DataItem directly as it is a DataRowView object.
1: <%#Microsoft.Security.Application.AntiXss.HtmlEncode
2: ((((System.Data.DataRowView)Container.DataItem)["Comments"]).ToString()) %>
Example #3
In this case, we are using a ASP.NET value in the JavaScript.
1: <script language="javascript">
2: function showMessage()
3: {
4: var message='<%=this.strMessage%>';
5: var div = document.getElementById('messageLabel');
6: div.innerHTML=message;
7: }
8: </script>
Line 4 has the vulnerability. Anytime you use .NET variables or data directly into java script, that is a perfect recipe for a disaster. In fact, this vulnerability is so dangerous that neither ASP.NET Request Validation nor Server.HtmlEncode cannot protect you. Only AntiXss has native java script encoding.
1: var message=<%=AntiXss.JavaScriptEncode(this.strMessage)%>;
Please note that AntiXss.JavaScriptEncode automatically surrounds the input with single quotes to make it a valid string.
We have seen three most common examples but there are many other vulnerable ways. The following is the small list of properties which could return untrusted input. By no means these values should be trusted, they should be validated and encoded during output.
Class name and property |
Request.Params |
Request.QueryString |
Request.Form |
Request.Headers |
Request.ServerVariables |
Request.Cookies |
TextBox.Text |
HiddenField.Value |
Please note that there are other ways in which you can get user input and could result in a XSS attack. The best strategy is to identify user inputs and encode them before sending back to the browser.
Comments
- Anonymous
September 09, 2008
PingBack from http://www.easycoded.com/real-world-xss-vulnerabilities-in-aspnet-code/ - Anonymous
September 10, 2008
Another good post on real world XSS vulnerabilities in ASP.NET code is now posted on our team blog site. - Anonymous
September 10, 2008
Besides the 8 you mentioned, here is a portion of the list I'm building for the OWASP Code Review Project.ItemUrlRawUrlUrlReferrerFilesInputStreamBinaryReadHttpMethodBrowserUserAgentAcceptTypesUserLanguagesrecordSet - Anonymous
September 15, 2008
Example#3 code may be vulnerable to a kind of DOM Based XSS, even if you use AntiXss.JavaScriptEncode().I think6: div.innerHTML=message;should be6: div.innerText=message; - Anonymous
November 06, 2008
The comment has been removed - Anonymous
January 02, 2009
Guest post by Ben Livshits of Microsoft Research here.... In the last several years we have seen a proliferation