catch the security flaw #5 (flaw and its countermeasure)

In my last post, I showed input validation code that uses RegularExpressionValidators improperly. Thanks to Mathew Grabau and Marius Cristian CONSTANTIN for pointing out that the Page’s IsValid property has not been checked before using the input. As a result, effectively, the code performs only client side validation, which can easily be bypassed. As a matter of fact, there are three more vulnerabilities in the code, that, together lead to a bigger vulnerability.

1. “validateRequest” is set to false.

    1: <%@ Page Language="C#" ValidateRequest="false" 
    2: AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>   

2. User supplied input is, without encoding, rendered back to the browser.

    1: protected void btnSubmit_Click(object sender, EventArgs e)   
    2: {            
    3:     Response.Write("Welcome " + Request["txtName"]);  
    4: }   

3. The Request object has been used ambiguously.

    1: Response.Write("Welcome " + Request["txtName"]);

What I mean by ambiguously is, that, a specific collection like Request.Forms or Request.QueryString has not been used to get the input parameter. If, Request[“txtName”] is used directly, the Web server searches the collections in the following order:

QueryString
Form
Cookies
ClientCertificate
ServerVariables

If “txtName” exists in more than one collection, the Request object returns the first instance that the object encounters [1]. As a result, if “txtName” is entered in the query string as well, it will be picked up from there and not from the form variable.

Therefore, an attacker can lure a victim into clicking a link like

https://server_name/firstwebsite/Default2.aspx?txtname=%3cscript%3ealert('xss')%3b%3c%2fscript%3e

If the victim clicks on this link, enters any name in the text box and clicks the submit button, script payload in the query string will execute in the victim’s browser, leading to cross-site scripting.

cth5

A much more secure way of writing the same code would be:-

    1: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
    2:      <html xmlns="https://www.w3.org/1999/xhtml" >
    3:      <body>
    4:         <form id="form1" runat="server">
    5:          <asp:TextBox ID="txtName" runat="server"></asp:TextBox>
    6:         <asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick="btnSubmit_Click" />
    7:         <asp:RegularExpressionValidator ID="regexpName" runat="server"     
    8:                                         ErrorMessage="This expression does not validate." 
    9:                                         ControlToValidate="txtName"     
   10:                                         ValidationExpression="^[a-zA-Z'.\s]{1,40}$" />
   11:         </form></body></html>
    1: public partial class Default2 : System.Web.UI.Page
    2: {
    3:     protected void Page_Load(object sender, EventArgs e)
    4:     {
    5:     }
    6:     protected void btnSubmit_Click(object sender, EventArgs e)
    7:     {
    8:         if (Page.IsValid)
    9:         {
   10:             Response.Write("Welcome " +
   11:                 HttpUtility.HtmlEncode(txtName.Text));
   12:         }
   13:     }
   14: }    

References:-
[1] Request Object
https://msdn.microsoft.com/en-us/library/ms524948.aspx