Thursday, March 19, 2009

Building Secure ASP.NET Pages and Controls

Threats and Countermeasures
Most Web application attacks require that malicious input is passed within HTTP requests. The general goal is either to coerce the application into performing unauthorized operations or to disrupt its normal operation. This is why thorough input validation is an essential countermeasure to many attacks and should be made a top priority when you develop ASP.NET Web pages and controls. Top threats include:
Code injection
Session hijacking
Identity spoofing
Parameter manipulation
Network eavesdropping
Information disclosure
Figure 10.1 highlights the most common threats to Web applications.
Figure 10.1
Common threats to ASP.NET Web pages and controls
Code Injection
Code injection occurs when an attacker causes arbitrary code to run using your application's security context. The risk increases if your application runs using a privileged account.
Attacks
There are various types of code injection attacks. These include:
Cross-site scripting. Malicious script is sent to a Web application as input. It is echoed back to a user's browser, where it is executed.
Buffer overflows. The type safe verification of managed code reduces the risk significantly, but your application is still vulnerable, especially where it calls unmanaged code. Buffer overflows can allow an attacker to execute arbitrary code inside your Web application process, using its security context.
SQL injection. This attack targets vulnerable data access code. The attacker sends SQL input that alters the intended query or executes completely new queries in the database. Forms authentication logon pages are common targets because the username and password are used to query the user store.
Vulnerabilities
Vulnerabilities that can lead to successful code injection attacks include:
Weak or missing input validation or reliance on client-side input validation
Including unvalidated input in HTML output
Dynamically constructing SQL statements that do not use typed parameters
Use of over-privileged process accounts and database logins
Countermeasures
The following countermeasures can be used to prevent code injection:
Validate input so that an attacker cannot inject script code or cause buffer overflows.
Encode all output that includes input. This prevents potentially malicious script tags from being interpreted as code by the client's browser.
Use stored procedures that accept parameters to prevent malicious SQL input from being treated as executable statements by the database.
Use least privileged process and impersonation accounts. This mitigates risk and reduces the damage that can be done if an attacker manages to execute code using the application's security context.
Session Hijacking
Session hijacking occurs when the attacker captures an authentication token and takes control of another user's session. Authentication tokens are often stored in cookies or in URLs. If the attacker captures the authentication token, he can transmit it to the application along with a request. The application associates the request with the legitimate user's session, which allows the attacker to gain access to the restricted areas of the application that require authenticated access. The attacker then assumes the identity and privileges of the legitimate user.
Vulnerabilities
Common vulnerabilities that make your Web pages and controls susceptible to session hijacking include:
Unprotected session identifiers in URLs
Mixing personalization cookies with authentication cookies
Authentication cookies passed over unencrypted links
Attacks
Session hijacking attacks include:
Cookie replay. The attacker captures the authentication cookie either by using network monitoring software or by some other means, for example, by exploiting an XSS scripting vulnerability.
Query string manipulation. A malicious user changes the session identifier that is clearly visible in the URL query string.
Countermeasures
You can employ the following countermeasures to prevent session hijacking:
Separate personalization and authentication cookies.
Only transmit authentication cookies over HTTPS connections.
Do not pass session identifiers that represent authenticated users in query strings.
Re-authenticate the user before critical operations, such as order placement, money transfers, and so on, are performed.
Identity Spoofing
Identity spoofing occurs when a malicious user assumes the identity of a legitimate user so that he can access the application.
Vulnerabilities
Common vulnerabilities that make your Web pages and controls susceptible to an identity spoofing attack include:
Authentication credentials that are passed over unencrypted links
Authentication cookies that are passed over unencrypted links
Weak passwords and policies
Weak credential storage in the user store
Attacks
Identity spoofing attacks include:
Cookie replay. The attacker steals the authentication cookie either by using network monitoring software or by using an XSS attack. The attacker then sends the cookie to the application to gain spoofed access.
Brute force password attacks. The attacker repeatedly tries username and password combinations.
Dictionary attacks. In this automated form of a brute force password attack, every word in a dictionary is tried as a password.
Countermeasures
You can employ the following countermeasures to prevent identity spoofing:
Only transmit authentication credentials and cookies over HTTPS connections.
Enforce strong passwords. Regular expressions can be used to ensure that user-supplied passwords meet suitable complexity requirements.
Store password verifiers in the database. Store non-reversible password hashes combined with a random salt value to mitigate the risk of dictionary attacks.
For more information about storing password hashes and other secrets in the database, see Chapter 14, "Building Secure Data Access."
Parameter Manipulation
Parameters are the items of data that are passed from the client to the server over the network. They include form fields, query strings, view state, cookies, and HTTP headers. If sensitive data or data that is used to make security decisions on the server are passed using unprotected parameters, your application is potentially vulnerable to information disclosure or unauthorized access.
Vulnerabilities
Vulnerabilities that can lead to parameter manipulation include:
Using hidden form fields or query strings that contain sensitive data
Passing cookies that contain security-sensitive data over unencrypted connections
Attacks
Parameter manipulation attacks include:
Cookie replay attacks. The attacker captures and alters a cookie and then replays it to the application. This can easily lead to identity spoofing and elevation or privileges if the cookie contains data that is used for authentication or authorization on the server.
Manipulation of hidden form fields. These fields contain data used for security decisions on the server.
Manipulation of query string parameters.
Countermeasures
You can employ the following countermeasures to prevent parameter manipulation:
Do not rely on client-side state management options. Avoid using any of the client-side state management options such as view state, cookies, query strings or hidden form fields to store sensitive data.
Store sensitive data on the server. Use a session token to associate the user's session with sensitive data items that are maintained on the server.
Use a message authentication code (MAC) to protect the session token. Pair this with authentication, authorization, and business logic on the server to ensure that the token is not being replayed.
Network Eavesdropping
Network eavesdropping involves using network monitoring software to trace packets of data sent between browser and Web server. This can lead to the disclosure of application-specific confidential data, the retrieval of logon credentials, or the capture of authentication cookies.
Vulnerabilities
Vulnerabilities that can lead to successful network eavesdropping include:
Lack of encryption when sending sensitive data
Sending authentication cookies over unencrypted channels
Attacks
Network eavesdropping attacks are performed by using packet sniffing tools that are placed on the network to capture traffic.
Countermeasures
To counter network eavesdropping, use Secure Sockets Layer (SSL) to provide an encrypted communication channel between browser and Web server. It is imperative that SSL is used whenever credentials, authentication tickets, or sensitive application data are sent over the network.
Information Disclosure
Information disclosure occurs when an attacker probes your Web pages looking for ways to cause exception conditions. This can be a fruitful exercise for the attacker because exception details, which often are returned as HTML and displayed in the browser, can divulge extremely useful information, such as stack traces that contain database connection strings, database names, database schema information, SQL statements, and operating system and platform versions.
Vulnerabilities
Vulnerabilities that lead to information disclosure include:
Weak exception handling
Letting raw exception details propagate to the client
Attacks
There are many attacks that can result in information disclosure. These include:
Buffer overflows.
Sending deliberately malformed input.
Countermeasures
To prevent information disclosure:
Use structured exception handling.
Return generic error pages to the client.
Use default redirect pages that contain generic and harmless error messages.
Design Considerations
Before you develop Web pages and controls, there are a number of important issues that you should consider at design time. The following are the key considerations:
Use server-side input validation.
Partition your Web site.
Consider the identity that is used for resource access.
Protect credentials and authentication tickets.
Fail securely.
Consider authorization granularity.
Place Web controls and user controls in separate assemblies.
Place resource access code in a separate assembly.
Use Server-Side Input Validation
At design time, identify all the various sources of user input that your Web pages and controls process. This includes form fields, query strings, and cookies received from the Web user, as well as data from back-end data sources. The Web user clearly lives outside your application's trust boundary, so all of the input from that source must be validated at the server. Unless you can absolutely trust the data retrieved from back-end data sources, that data should also be validated and sanitized before it is sent to the client. Make sure your solution does not rely on client-side validation because this is easily bypassed.
Partition Your Web Site
Your Web site design should clearly differentiate between publicly accessible areas and restricted areas that require authenticated access. Use separate subdirectories beneath your application's virtual root directory to maintain restricted pages, such as checkout functionality in a classic e-commerce Web site that requires authenticated access and transmits sensitive data such as credit card numbers. Separate subdirectories allow you to apply additional security (for example, by requiring SSL) without incurring SSL performance overhead across the entire site. It also allows you to mitigate the risk of session hijacking by restricting the transmission of authentication cookies to HTTPS connections. Figure 10.2 shows a typical partitioning.
Figure 10.2
A Web site partitioned into public and secure areas
Note that in Figure 10.2, the restricted subfolder is configured in Internet Information Services (IIS) to require SSL access. The first element in Web.config allows all users to access the public area, while the second element prevents unauthenticated users from accessing the contents of the secured subfolder and forces a login.
For more information about restricting authentication cookies so that they are passed only over HTTPS connections and about how to navigate between restricted and non-restricted pages, see "Use Absolute URLs for Navigation" in the "Authentication" section of this chapter.
Consider the Identity That Is Used for Resource Access
By default, ASP.NET applications do not impersonate, and the least privileged ASP.NET process account is used to run ASP.NET Web applications and for resource access. The default is the recommended configuration. There are several situations in which you may want to use a different Windows security context for resource access. These include:
Hosting multiple applications on the same server
You can use IIS to configure each application to use a separate anonymous Internet user account and then enable impersonation. Each application then has a distinct identity for resource access. For more information about this approach, see Chapter 20, "Hosting Multiple ASP.NET Applications."
Note If your applications run on Windows Server 2003 with IIS 6.0, you can use application pools and configure each application to run in its own worker process that provides process-level isolation. By default, all applications run in a default application pool. With application pools, you can configure each process to run using a separate identity and, as a result, you do not need to use impersonation. For more information, see "How To: Improve Security When Hosting Multiple Applications in ASP.NET 2.0."
Accessing a remote resource with specific authentication requirements
If you need to access a specific remote resource (for example, a file share) and have been given a particular Windows account to use, you can use configure this account as the anonymous Web user account for your application. Then you can use programmatic impersonation prior to accessing the specific remote resource. For more information, see "Impersonation" later in this chapter.
Protect Credentials and Authentication Tickets
Your design should factor in how to protect credentials and authentication tickets. Credentials need to be secured if they are passed across the network and while they are in persistent stores such as configuration files. Authentication tickets must be secured over the network because they are vulnerable to hijacking. Encryption provides a solution. SSL or IPSec can be used to protect credentials and tickets over the network and DPAPI provides a good solution for encrypting credentials in configuration files.
Fail Securely
If your application fails with an unrecoverable exception condition, make sure that it fails securely and does not leave the system wide open. Make sure the exception details that are valuable to a malicious user are not allowed to propagate to the client and that generic error pages are returned instead. Plan to handle errors using structured exception handling, rather than relying on method error codes.
Consider Authorization Granularity
Consider the authorization granularity that you use in the authenticated parts of your site. If you have configured a directory to require authentication, should all users have equal access to the pages in that directory? If necessary, you can apply different authorization rules for separate pages based on the identity, or more commonly, the role membership of the caller, by using multiple elements within separate elements.
For example, two pages in the same directory can have different and elements in Web.config.
Place Web Controls and User Controls in Separate Assemblies
When Web controls and user controls are put in their own assemblies, you can configure security for each assembly independently by using code access security policy. This provides additional flexibility for the administrator and it means that you are not forced to grant extended permissions to all controls just to satisfy the requirements of a single control.
Place Resource Access Code in a Separate Assembly
Use separate assemblies and call them from your page classes rather than embedding resource access code in your page class event handlers. This provides greater flexibility for code access security policy and is particularly important for building partial-trust Web applications. For more information, see Chapter 9, "Using Code Access Security with ASP.NET."
Input Validation
If you make unfounded assumptions about the type, length, format, or range of input, your application is unlikely to be robust. Input validation can become a security issue if an attacker discovers that you have made unfounded assumptions. The attacker can then supply carefully crafted input that compromises your application. The misplaced trust of user input is one of the most common and devastating vulnerabilities in Web applications.
Constrain, Then Sanitize
Start by constraining input and check for known good data by validating for type, length, format, and range. Sometimes you also need to sanitize input and make potentially malicious input safe. For example, if your application supports free-format input fields, such as comment fields, you might want to permit certain "safe" HTML elements, such as and , and strip out any other HTML elements. The following table summarizes the options that are available for constraining and sanitizing data:
Table 10.1 Options for Constraining and Sanitizing Data
Requirement
Options
Type checks
.NET Framework type system. Parse string data, convert to a strong type, and then handle FormatExceptions.
Regular expressions. Use ASP.NET RegularExpressionValidator control or Regex class.
Length checks
Regular expressions
String.Length property
Format checks
Regular expressions for pattern matching
.NET Framework type system
Range checks
ASP.NET RangeValidator control (supports currency, date, integer, double, and string data)
Typed data comparisons
Regular Expressions
You can use regular expressions to restrict the range of valid characters, to strip unwanted characters, and to perform length and format checks. You can constrain input format by defining patterns that the input must match. ASP.NET provides the RegularExpressionValidator control and the Regex class is available from the System.Text.RegularExpressions namespace.
If you use the validator controls, validation succeeds if the control is empty. For mandatory fields, use a RequiredFieldValidator. Also, the regular expression validation implementation is slightly different on the client and server. On the client, the regular expression syntax of Microsoft JScript® development software is used. On the server, System.Text.RegularExpressions.Regex syntax is used. Since JScript regular expression syntax is a subset of System.Text.RegularExpressions.Regex syntax, it is recommended that JScript regular expression syntax be used to yield the same results on both the client and the server.
For more information about the full range of ASP.NET validator controls, refer to the .NET Framework documentation.
RegularExpressionValidator Control
To validate Web form field input, you can use the RegularExpressionValidator control. Drag the control onto a Web form and set its ValidationExpression, ControlToValidate, and ErrorMessage properties.
You can set the validation expression using the properties window in Microsoft Visual Studio .NET or you can set the property dynamically in the Page_Load event handler. The latter approach allows you to group together all of the regular expressions for all controls on the page.
Regex Class
If you use regular HTML controls with no runat="server" property (which rules out using the RegularExpressionValidator control), or you need to validate input from other sources such as query strings or cookies, you can use the Regex class either in your page class or in a validation helper method, possibly in a separate assembly. Some examples are shown later in this section.

No comments:

Post a Comment