HomeDigital EditionSearch Dotnet Cd
ASP.NET C# Certification Exams The CLI Data Access Editorials Extending .NET Fundamentals Interoperability Interviews Migrate Mobile .NET Mono .NET Interface Object-Oriented Programming Open Source Optimization Product/Book Reviews Security Source Code UML Visual Studio .NET

Security must be established from the moment application coding begins ­ for the simple reason that the cost of fixing a security flaw grows astronomically as the application evolves. A study by IBM's Systems Sciences Institute found that the relative cost of fixing software defects after deployment is nearly 15 times greater than the cost of detecting and eliminating them during development.

In order to secure applications while minimizing costs, vendors are calling on developers to take more responsibility for delivering secure applications that are resistant to attack. However, few developers have the training or tools needed to implement security at the inception of development. While learning to write secure code is a complex process that should be taught in universities, internal training seminars, and industry conferences, understanding the following five common ASP.NET application security flaws and recommended code fixes will give developers a head start on building security directly into applications at their birth.

Never Trust User Input
The cardinal security sin of Web application development is developers' tendency to trust user input. Assuming that users (even malicious ones) are bounded by the browser and will use only the browser to interact with the site leaves the application wide open to attack. Hackers have a rich toolkit of programs that interact and attack sites outside the boundaries of the browser. From the lowest raw/line-mode interface (e.g., telnet), through CGI scanners, Web proxies, and Web application scanners, malicious users have a diverse spectrum of possible attack modes and means.

The only way to counteract hacker attacks is to validate user input. You can perform several, even overlapping, validations. For instance, a program may validate all its input upon reception, to make sure it consists of valid characters, and that no field is too long (potential buffer overflow). Then some routines carry out further validations, making sure that the data is reasonable and valid for the specific purposes for which it will be used. A more fine-grained character set validation may be applied, as well as length restriction enforcement. Following these maxims will help you to properly validate user input:
1.  Always validate all user input in multiple tiers and on a trusted platform.
2.  Validate input to allow nothing other than the functions expected to be input and output.
3.  Set a trusted code base and validate all data before it can enter the trusted environment.
4.  Test each data type before entry (i.e., Web, registry, file system, configuration files).
5.  Define all data formats (i.e., buffer length, integer type).
6.  Define valid user requests and reject all others.
7.  Look for valid, rather than invalid, data.
8.  Never mirror Web input.
9.  Encode or encrypt output.

How to Avoid Five Common ASP.NET Security Flaws
The following five examples will illustrate how to implement these maxims by demonstrating security flaws as they appear in code, the dangers the flaws present, and how to simply rewrite a few lines to greatly reduce the risk of attack.

Parameter Tampering
Using ASP.NET Field Validators
Trusting user input is the number one enemy of secure Web applications. Parameters submitted in HTML forms are a major source of user input; failing to validate these parameters may result in a severe security threat.

The following C# code queries a back-end SQL server (assuming the variables "user" and "password" are taken directly from the user input):

SqlDataAdapter my_query = new SqlDataAdapter(
"SELECT * FROM accounts WHERE acc_user='" + user +
"' AND acc_password='" + password, the_connection);

These few innocent-looking lines of code enable a vicious SQL injection attack. By entering "OR 1=1" in the "user" input field, the attacker can log in to the system as an arbitrary user, or possibly execute shell commands simply by appending the appropriate call right after the query.

'; EXEC master..xp_cmdshell(Oshell command here')--

Danger
The programmer assumed that the user input consists of solely "normal" data ­ real user names, real passwords that do not contain the character O (apostrophe) ­ enabling unexpected characters, such as O to execute SQL attacks. By executing unanticipated SQL queries from the user input, a hacker could call alternate functions or procedures.

Solution
A field validator is a mechanism that enables an ASP.NET developer to enforce restrictions on the field value, for example, specifying that the user input field match a given expression.

In order to block the attack shown above, forbid the apostrophe character either by specifying what is not valid in the field: "[^']*" ­ or better yet, by allowing only alphanumeric characters in the field: "[a-zA-Z0-9]*".

Parameter Tampering Revisited
Avoiding Validation Pitfalls
However, incorporating validators for every user input field will not protect against all attempts to alter parameters. Range validation must also specify the correct data type.

When using the range validator ASP.NET control, keep in mind that the Type attribute must be set according to the type of input field expected, as the Type attribute defaults to "String":

<!-- check for a number 1-9 -->
<asp:RangeValidator ... MinimumValue="1" MaximumValue="9" .../>

Danger
Since no Type is specified, this code will assume "String", meaning that the order is a lexicographical one. Therefore, the validator will ensure only that the string starts with 0­9. Strings such as "0abcd" will be accepted.

Solution
The right way to test for integer range is to specify the type as "Integer":

<!-- check for a number 1-9 -->
<asp:RangeValidator ... MinimumValue="1"
MaximumValue="9" Type="Integer"

Information Leakage
Keeping Hidden Fields Under Wraps
Information about ASP.NET applications can often be found in the __VIEWSTATE hidden field in nearly all HTML pages. Often overlooked because it is Base64 encoded, hackers can easily decode the Base64 data, exposing the __VIEWSTATE data with minimal effort.

Danger
By default, the __VIEWSTATE data consists of:

  • Dynamic data from page controls
  • Data stored explicitly by the developer in the ViewState bag
  • The cryptographic signature of the above data

    Solution
    Enable encryption of the __VIEWSTATE data by setting EnableViewStatMAC="true". Then, set the machineKey validation type to "3DES". This instructs ASP.NET to encrypt the ViewState value using the Triple DES symmetric encryption algorithm: <machineKey validation="3DES" />.

    SQL Injection
    Prevent by Using SQL Parameters
    As described in the section on parameter tampering, a SQL query embeds SQL script in the user input by placing a malicious character (such as an apostrophe) in the input field, causing the SQL server to execute a malicious query.

    Danger
    A malicious query can call for the delivery of information from back-end databases such as a directory of customer credit card numbers.

    Solution
    A more robust solution, rather than allowing only the characters really needed, is the use of SQL parameter APIs (such as those provided by ADO.NET) in order to make the programming infrastructure (rather than the programmer) construct the query.

    Using APIs, the programmer provides a template query (or a stored procedure), and a list of parameter values (embedded into the query), and the result is executed by the SQL Server. The advantage is a guarantee that the parameters will be embedded correctly. For example, apostrophes will be escaped, thus rendering SQL injection attacks useless. At the same time, the apostrophe will not be blocked, which is an upside of this approach.

    So instead of the code in the section on parameter tampering, use:

    SqlDataAdapter my_query = new SqlDataAdapter(
    "SELECT * FROM accounts
    WHERE acc_user= @user AND acc_pass
    word=@pass", the_connection);

    SqlParameter userParam =
    my_query.Select_Command
    .Parameters.Add(
    "@user",SqlDb.VarChar,20);
    userParam.Value=user;

    SqlParameter passwordParam =
    my_query.Select_Command
    .Parameters.Add(
    "@",SqlDb.VarChar,20);
    passwordParam.Value=password;

    Cross-Site Scripting
    Encode Outgoing Data
    Cross-site scripting embeds malicious user input in the response (HTML) page. A simple ASP.NET page such as the following contains a serious security flaw:

    <%@ Page Language="vb" %>

    <asp:Label id="Label1" runat="server">
    INITIAL LABEL VALUE</asp:Label>

    <form method="post" runat="server" ID="Form1">
    Please Provide feedback<br>
    <asp:Textbox ID="feedback" runat="server"/><br>
    <asp:Button id="cmdSubmit" runat="server"
    Text="Submit!" OnClick="do_feedback">
    </asp:Button>
    </form>

    <script runat="server">
    Sub do_feedback(sender As Object, e As System.EventArgs)
    Label1.Text=feedback.Text
    End Sub
    </script>

    Danger
    An attacker can form a malicious request with JavaScript code that will be executed at the client browser when the link is clicked. To see that this is possible, this script can be fed with the following input:

    <script>alert(document.cookie)
    </script>

    Solution
    For a two-tier security architecture, use user input validation and HTML-encode outgoing user data presented in the HTML page to ensure that the data is not interpreted by the browser as anything other than plain text.

    In this case, this can be done by adding a function call to HtmlEncode:

    Label1.Text=Server.HtmlEncode(feedback.Text)

    As a result, the response HTML stream will contain:

    <script>alert(document.cookie)</script>

    As a result, no JavaScript code is executed by the browser, because no HTML "script" tag is present. The < and > symbols are replaced by their HTML-encoded versions, < and > respectively.

    Using Automated Security Testing Tools
    With new applications deployed on average every three months by organizations experiencing changing customer requirements and personnel turnover, the demand placed on developers to develop robust, high-quality software quickly is tremendous. While all developers should be instructed in secure coding techniques, tools that can automatically check code for security flaws can speed the development of secure applications.

    Until now, developers have used only tools that cover specific aspects of functionality testing such as performance and bug/crash spotting. Because manual source code review is inconsistent in nature and presupposes intensive secure coding training, tools concerned with security of the application and its behavior under adverse conditions are also critical to the production of high-quality applications.

    The most effective solution for rapidly improving the quality and security of applications is to provide developers with a tool that automatically tests applications for defects within their existing workflow environment. By using a tool that detects application-specific vulnerabilities during unit testing and offers inline fix recommendations, developers will immediately see the coding errors they have made and learn how to fix the existing vulnerability and avoid future vulnerabilities for ongoing improved security.

    Conclusion
    The dangers of insecure Web applications will only accelerate as Web services explode, sending many more applications outside the firewall. Developers will be under even more pressure to rapidly create new applications under tight deadlines. In order to prepare for the Web services of the future and to ensure high-quality applications today, attention and resources must be devoted to secure coding practices. By taking a proactive approach to security at the birth of applications, companies can construct high-quality, secure applications while reducing costs and limiting risk.

    About The Author
    Amit Klein, director of Security and Research for Sanctum, Inc. is responsible for the security content of Sanctum's products, research of new technologies, and new product directions, as well as performing security audits, conducting security research, and acting as the security knowledge focal point for the corporation. Prior to joining Sanctum, Amit served in the Israeli Defense Force in various R&D positions including leading an algorithmic research team and later a software project development team. info@sys-con.com

    All Rights Reserved
    Copyright ©  2004 SYS-CON Media, Inc.

      E-mail: info@sys-con.com