Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Pro ASP.NET 2.0 In CSharp 2005 (2005) [eng]

.pdf
Скачиваний:
107
Добавлен:
16.08.2013
Размер:
29.8 Mб
Скачать

668 C H A P T E R 1 9 T H E A S P. N E T S E C U R I T Y M O D E L

Understanding Potential Threats

Creating a secure architecture and design requires that you have an in-depth understanding of your application’s environment. You can’t create secure software if you don’t know who has access to your application and where possible points of attack might be. Therefore, the most important factor for creating a secure application architecture and design lies in a good understanding of environmental factors such as users, entry points, and potential possible threats with points of attack.

That’s why threat modeling has become more important in today’s software development processes. Threat modeling is a structured way of analyzing your application’s environment for possible threats, ranking those threats, and then deciding about mitigation techniques based on those threats. With this approach, a decision for using a security technology (such as authentication or SSL encryption) is always based on an actual reason, the threat itself.

But threat modeling is important for another reason. As you probably know, not all potential threats can be mitigated with security technologies such as authentication or authorization. In other words, some of them can’t be solved technically. For example, a bank’s online solution can use SSL for securing traffic on its website. But how do users know they are actually using the bank’s page and not a hacker’s fake website? Well, the only way of course to know this is to look at the certificate used for establishing the SSL channel. But users have to be aware of that, and therefore you have to inform them of this somehow. So, the “mitigation technique” is not a security technology. It just involves making sure all your registered users know how to look at the certificate. (Of course, you can’t force them to do so, but if your information is designed appropriately, you might get most of them to do it.) Threat modeling as an analysis method helps you determine issues such as these, not merely the technical issues.

Threat modeling is a big topic that is beyond the scope of this book; refer to Michael Howard and David LeBlanc’s Writing Secure Code, Second Edition (Microsoft Press, 2002) or Frank Swiderski and Window Snyder’s Threat Modeling (Microsoft Press, 2004).

Secure Coding Guidelines

Of course, a secure architecture and design alone doesn’t make your application completely secure. It’s only one of the most important factors. After you have created a secure architecture and design, you have to write secure code as well. Again, Writing Secure Code, Second Edition (Microsoft Press, 2002) is an excellent source for detailed information for every developer. In terms of web applications, you should always keep the following guidelines in mind when writing code:

Never trust user input: Assume that every user is evil until you have proven the opposite. Therefore, always strongly validate user input. Write your validation code in a way that it verifies input against only allowed values and not invalid values. (There are always more invalid values than you might be aware of at the time of writing the application.)

Never use string concatenation for creating SQL statements: Always use parameterized statements so that your application is not SQL injectable, as discussed in Chapter 7.

Never output data entered by a user directly on your web page before validating and encoding it: The user might enter some HTML code fragments (for example, scripts) that lead to cross-site scripting vulnerabilities. Therefore, always use HttpUtility.HtmlEncode() for escaping special characters such as < or > before outputting them on the page, or use a web control that performs this encoding automatically.

Never store sensitive data, business-critical data, or data that affects internal business rule decisions made by your application in hidden fields on your web page: Hidden fields can be changed easily by just viewing the source of the web page, modifying it, and saving it to a file. Then an attacker simply needs to submit the locally saved, modified web page to the server.

Browser plug-ins are available to make this approach as easy as writing an e-mail with Microsoft Outlook.

C H A P T E R 1 9 T H E A S P. N E T S E C U R I T Y M O D E L

669

Never store sensitive data or business-critical data in view state: View state is just another hidden field on the page, and it can be decoded and viewed easily. If you use the EnableViewStateMAC=true setting for your page, view state will be signed with a message

authentication code that is created based on a machine key of the web server’s machine.config. We recommend using EnableViewStateMAC=true as soon as you include data in your view state that should not be changed by users browsing your web page. See Chapter 6 for more about protecting view state.

Enable SSL when using Basic authentication or ASP.NET forms authentication: Chapter 20 discusses forms authentication. SSL is discussed later in this chapter in the section “Understanding SSL.”

Protect your cookies: Always protect your authentication cookies when using forms authentication, and set timeouts as short as possible and only as long as necessary.

Use SSL: In general, if your web application processes sensitive data, secure your whole website using SSL. Don’t forget to protect even image directories or directories with other files not managed by the application directly through SSL.

Of course, these are just a few general, important issues. To get a complete picture of the situation in terms of your concrete application, you have to create threat models in order to compile a complete list of potential dangers. In addition, invest in ongoing education, because hackers’ techniques and technologies evolve just as other techniques and technologies do.

If you forget about just one of these guidelines, all the other security features are more or less useless. Never forget the following principle: security is only as good as your weakest link.

Understanding Gatekeepers

A good way for increasing the security of your application is to have many components in place that are enforcing security. Gatekeepers are a conceptual pattern that applies a pipelining model to a security infrastructure. This model helps you tighten your security.

The gatekeeper model assumes that a secure application has always more security mechanisms in place than necessary. Each of these mechanisms is implemented as a gatekeeper that is responsible for enforcing some security-related conditions. If one of these gatekeepers fails, the attacker will have to face the next gatekeeper in the pipeline. The more gatekeepers you have in your application, the harder the attacker’s life will be. Actually, this model supports a core principle for creating secure applications: be as secure as possible, and make attackers’ lives as hard as possible.

In Figure 19-1, you can see a pipeline of gatekeepers. At the end of the pipeline, you can see the protected resource (which can be anything, even your custom page code). The protected resource will be accessed or executed only if every gatekeeper grants access. If just one gatekeeper denies access, the request processing is returned to the caller with a security exception.

Implementing a central security component in such a way is generally a good idea. You can also secure your business layer in this way. The ASP.NET application infrastructure leverages this mechanism as well. ASP.NET includes several gatekeepers, each one enforcing a couple of security conditions and therefore protecting your application. In the next sections of this chapter, you will learn which gatekeepers the ASP.NET framework includes and what are the responsibilities of those gatekeepers.

670

C H A P T E R 1 9 T H E A S P. N E T S E C U R I T Y M O D E L

Figure 19-1. A pipeline of gatekeepers

Understanding the Levels of Security

Basically, for mainstream web applications, the fundamental tasks for implementing security (besides the issues you identify during your threat modeling session) are always the same:

Authentication: First, you have to authenticate users. Authentication asks the question, who goes here? It determines who is working with your application on the other end.

Authorization: Second, as soon as you know who is working with your application, your application has to decide which operations the user may execute and which resources the user may access. In other words, authorization asks the question, what is your clearance level?

Confidentiality: While the user is working with the application, you have to ensure that nobody else is able to view sensitive data processed by the user. Therefore, you have to encrypt the channel between the client’s browser and the web server. Furthermore, you possibly have to encrypt data stored on the backend (or in the form of cookies on the client) if even database administrators or other staff of the company where the web application is hosted may not view the data.

Integrity: Finally, you have to make sure data transmitted between the client and the server is not changed by unauthorized actors. Digital signatures provide you with a way to mitigate this type of threat.

ASP.NET includes a basic infrastructure for performing authentication and authorization.

The .NET Framework base class library includes some classes in the System.Security namespace for encrypting and signing data. Furthermore, SSL is a standardized way for ensuring confidentiality and integrity for data transmitted between the client browser and the web server. Now you will take a closer look at each of these concepts.

Authentication

Authentication is the process of discovering a user’s identity and ensuring the authenticity of this identity. The process of authentication is analogous to checking in at a conference registration table. First, you provide some credentials to prove your identity (such as a driver’s license or a passport). Second, once your identity is verified with this information, you are issued a conference badge, or token, that you carry with you when you are at the conference. Anyone you meet at the conference can immediately determine your identity by looking at your badge, which typically

C H A P T E R 1 9 T H E A S P. N E T S E C U R I T Y M O D E L

671

contains basic identity information, such as your first and last name. This whole process is an example of authentication. Once your identity is established, your token identifies you so that everywhere you go within a particular area, your identity is known.

In an ASP.NET application, authentication is implemented through one of four possible authentication systems:

Windows authentication

Forms authentication

Passport authentication

A custom authentication process

In each of these, the user provides credentials when logging in. The user’s identity is tracked in different ways depending on the type of authentication. For example, the Windows operating system uses a 96-bit number called a SID (security identifier) to identify each logged-on user. In ASP.NET forms authentication (which is covered in detail in Chapter 20), the user is given a forms authentication ticket, which is a combination of values that are encrypted and placed in a cookie. All authentication does is allow the application to identify who a user is on each request. This works well for personalization and customization, because you can use the identity information to

render user-specific messages on the web pages, alter the appearance of the website, add custom content based on user preferences, and so on. However, on its own, authentication isn’t enough to restrict the tasks that a user is allowed to perform based on that user’s identity. For that, you need authorization, described in a moment. However, before you learn about authorization, you will take a look at impersonation, which is related to authentication.

Impersonation

Impersonation is the process of executing code in the context (or on behalf) of another user identity. By default, all ASP.NET code is executed using a fixed machine-specific account (typically ASPNET on IIS 5.x or Network Service on IIS 6.0). To execute code using another identity, you can use the built-in impersonation capabilities of ASP.NET. You can use a predefined user account, or you can assume the user’s identity, if the user has already been authenticated using a Windows account.

You might want to use impersonation for two reasons:

To give each web application different permissions: In IIS 5, the default account that’s specified in the machine.config file is used for all web applications on the computer. If you want to give different web applications different permissions, you can use impersonation to designate different Windows accounts for each application. That’s especially important for hosting scenarios where you want to isolate web applications of different customers appropriately (so that, for example, a web application of customer A is not able to access directories or databases from a web application of customer B).

To use existing Windows user permissions: For example, consider an application that retrieves information from various files that already have user-specific or group-specific permissions set. Rather than code the authorization logic in your ASP.NET application, you can use impersonation to assume the identity of the current user. That way, Windows will perform the authorization for you, checking permissions as soon as you attempt to access a file.

These two scenarios are fundamentally different. In the first scenario, impersonation defines a single, specific account. In this case, no matter what user accesses the application, and no matter what type of user-level security you use, the code will run under the account you’ve set. In the second scenario, the users must be authenticated by IIS. The web-page code will then execute under the identity of the appropriate user. You’ll learn more about these options in Chapter 20.

672 C H A P T E R 1 9 T H E A S P. N E T S E C U R I T Y M O D E L

Authorization

Authorization is the process of determining the rights and restrictions assigned to an authenticated user. In the conference analogy, authorization is the process of being granted permission to a particular type of session, such as the keynote speech. At most conferences it is possible to purchase different types of access, such as full access, preconference only, or exhibition hall only. This means if you want to attend the keynote address at Microsoft’s Professional Developer Conference to hear what Bill Gates has to say, you must have the proper permissions (the correct conference pass). As you enter the keynote presentation hall, a member of staff will look at your conference badge. Based on the information on the badge, the staff member will let you pass or will tell you that you cannot enter. This is an example of authorization. Depending on information related to your identity, you are either granted or denied access to the resources you request.

The conference example is a case of role-based authorization—authorization being based on the role or group the user belongs to, not on who the user is. In other words, you are authorized to enter the room for the keynote address based on the role (type of pass), not your specific identity information (first and last name). In many cases, role-based authorization is preferable because it’s much easier to implement. If the staff member needed to consult a list with the name of each allowed guest, the process of authorization would be much more awkward. The same is true in a web application, although the roles are more likely to be managers, administrators, guests, salespeople, clients, and so on.

In a web application, different types of authorization happen at different levels. For example, at the topmost level, your code can examine the user identity and decide whether to continue with a given operation. On a lower level, you can configure ASP.NET to deny access to specific web pages or directories for certain users or roles. At an even lower level, when your code performs various tasks such as connecting to a database, opening a file, writing to an event log, and so on, the Windows operating system checks the permissions of the Windows account that’s executing the code. In most situations, you won’t rely on this bottommost level, because your code will always run under a fixed account. In IIS 5.x, this is the account named ASPNET. In IIS 6.0, this is the fixed Network Service account. (In both cases, you can override the default account, as described in Chapter 18.)

Sound reasons exist for using a fixed account to run ASP.NET code. In almost all applications, the rights allocated to the user don’t match the rights needed by your application, which works on behalf of the user. Generally, your code needs a broader set of permissions to perform incidental tasks, and you won’t want to give these permissions to every user who might access your web application. For example, your code may need to create a log record when a failure occurs, even though the current user isn’t allowed to directly write to the Windows event log, file, or database. Similarly, ASP.NET applications always require rights to the c:\[WinDir]\Microsoft.NET\[Version]\ Temporary ASP.NET Files directory to create and cache a compiled machine-language version of your web pages. Finally, you might want to use an authentication system that has nothing to do with Windows. For example, an e-commerce application might verify user e-mail addresses against a server-side database. In this case, the user’s identity doesn’t correspond to a Windows account.

In a few rare cases, you’ll want to give your code the ability to temporarily assume the identity of the user. This type of approach is much more common when creating ASP.NET applications for local networks where users already have a carefully defined set of Windows privileges. In this case, you need to supplement your security arsenal with impersonation, as described in Chapter 22.

C H A P T E R 1 9 T H E A S P. N E T S E C U R I T Y M O D E L

673

Confidentiality and Integrity

Confidentiality means ensuring that data cannot be viewed by unauthorized users while being transmitted over a network or stored in a data store such as a database. Integrity is all about ensuring that nobody can change the data while it is transmitted over a network or stored in a data store. Both are based on encryption.

Encryption is the process of scrambling data so that it’s unreadable by other users. Encryption in ASP.NET is a completely separate feature from authentication, authorization, and impersonation. You can use it in combination with these features or on its own.

As mentioned previously, you might want to use encryption in a web application for two reasons:

To protect communication (data over the wire): For example, you might want to make sure an eavesdropper on the public Internet can’t read a credit card number that’s used to purchase an item on your e-commerce site. The industry-standard approach to this problem is to use SSL. SSL also implements digital signatures for ensuring integrity. SSL isn’t implemented by ASP.NET. Instead, it’s a feature provided by IIS. Your web-page (or web service) code is identical whether or not SSL is used.

To protect permanent information (data in a database or in a file): For example, you might want to store a user credit card in a database record for future use. Although you could store this data in plain text and assume the web server won’t be compromised, this is never a good idea. Instead, you should use the encryption classes that are provided with .NET to manually encrypt data before you store it.

It’s worth noting that the .NET encryption classes aren’t directly tied to ASP.NET. In fact, you can use them in any type of .NET application. You’ll learn about encryption and digital signatures as well as how to take control of custom encryption in Chapter 25.

Pulling It All Together

So, how do authentication, authorization, and impersonation all work together in a web application? When users first come to your website, they are anonymous. In other words, your application

doesn’t know (and doesn’t care) who they are. Unless you authenticate them, this is the way it stays. By default, anonymous users can access any ASP.NET web page. But when a user requests a

web page that doesn’t permit anonymous access, several steps take place (as shown in Figure 19-2):

1.The request is sent to the web server. Since the user identity is not known at this time, the user is asked to log in (using a custom web page or a browser-based login dialog box). The specific details of the login process depend on the type of authentication you’re using.

2.The user provides their credentials, which are then verified, either by your application (in the case of forms authentication) or automatically by IIS (in the case of Windows authentication).

3.If the user credentials are legitimate, the user is granted access to the web page. If their credentials are not legitimate, then the user is prompted to log in again, or they are redirected to a web page with an “access denied” message.

674 C H A P T E R 1 9 T H E A S P. N E T S E C U R I T Y M O D E L

Figure 19-2. Requesting a web page that requires authentication

When a user requests a secure web page that allows only specific users or users in specific roles, the process is similar, but an extra step takes place (see Figure 19-3):

1.The request is sent to the web server. Since the user identity is not known at this time, the user is asked to log in (using a custom web page or a browser-based login dialog box). The specific details of the login process depend on the type of authentication you’re using.

2.The user provides their credentials, which are verified with the application. This is the authentication stage.

3.The authenticated user’s credentials or roles are compared to the list of allowed users or roles. If the user is in the list, then they are granted access to the resource; otherwise, access is denied.

4.Users who have access denied are either prompted to log in again, or they are redirected to a web page with an “access denied” message.

Figure 19-3. Requesting a web page that requires authentication and authorization

C H A P T E R 1 9 T H E A S P. N E T S E C U R I T Y M O D E L

675

Internet Information Services Security

Before the ASP.NET runtime even gets in touch with an incoming request, IIS verifies the security according to its own configuration. Therefore, before you learn about the details of ASP.NET security, you have to learn about the first gatekeeper in the security pipeline of your web application—IIS.

IIS provides you with a couple of essential security mechanisms that act as gatekeepers before ASP.NET starts with the request processing. Basically, IIS includes the following security mechanisms:

Authentication: IIS supports Basic authentication, Digest authentication, Passport authentication, and Windows authentication as well as certificate authentication through an SSL channel. Any authentication IIS performs results in an authenticated Windows user. Therefore, IIS supports authenticating Windows users only.

Authorization: IIS provides built-in support of IP address restrictions and evaluation of Windows ACLs.

Confidentiality: Encryption can be enforced through SSL.

In the following sections, you will learn about the details of IIS security configuration. The other subsequent security chapters will go into the details of the ASP.NET security infrastructure. You have to keep IIS security always in mind, because it affects how ASP.NET behaves with different security settings applied in web.config.

For example, if your ASP.NET application wants to use Windows authentication, you should configure IIS to use either Windows or Basic (or Digest) authentication. If your ASP.NET web application doesn’t want to use Windows accounts (and therefore use custom or forms authentication), you must configure IIS to allow anonymous access.

IIS Authentication

As previously mentioned, IIS supports several authentication mechanisms. Any other configuration setting security (and therefore authentication) is configured on a per-website basis. You can find the security settings on the Directory Security tab of a virtual directory’s properties. Figure 19-4 shows the authentication options of IIS.

Of course, anonymous access gives everyone access to the web page. It overrides any other authentication setting of IIS because IIS authenticates only if it is necessary (and of course if anonymous authentication is enabled, no additional authentication steps are necessary for saving round-trips). Further, if you have configured anonymous authentication in IIS, you still can use ASP.NET-based security to authenticate users either with ASP.NET-integrated mechanisms such as forms authentication or a custom type of authentication, as you will learn later in this chapter and in subsequent chapters.

Windows authentication configures IIS to validate the credentials of the user against a Windows account configured either on the local machine or within the domain. When working within a domain, domain users don’t need to enter their user name and password if already logged onto a client machine within the network, because the client’s authentication ticket is passed to the server for authentication automatically.

IIS also supports Basic authentication. This is an authentication method developed by the W3C that defines an additional HTTP header for transmitting user names and passwords across the wire. But pay attention: nothing is encrypted. The information will be transmitted Base64 encoded. Therefore, you should only use Basic authentication with SSL. As is the case with Windows authentication, the credentials entered by the user are evaluated against a Windows account. But the way the credentials are transferred over the wire is different. While Basic authentication transmits the information through the HTTP header, Windows authentication uses either NTLM or Kerberos for transmitting the information.

676 C H A P T E R 1 9 T H E A S P. N E T S E C U R I T Y M O D E L

Figure 19-4. IIS authentication options

Digest authentication is similar to Basic authentication. Instead of sending the credentials Base64 encoded across the wire, it hashes the user’s password and transmits the hashed version across the wire. Although this sounds more secure, Digest authentication has never become common. As a result, it’s rarely used outside of controlled environments (such as intranets).

Passport authentication uses Microsoft Passport as its underlying infrastructure. Microsoft Passport implements a central identity management. In that case, the user’s credentials are managed by a separate Passport server. While usually this infrastructure is hosted by Microsoft, you can also host your own Passport infrastructure within your company and use that instead.

Finally, IIS supports one additional authentication method, certificate authentication, that cannot be found in Figure 19-3, as it is configured through SSL.

Note For debugging ASP.NET web applications, Windows authentication needs to be enabled because Windows determines whether you are allowed to debug or not based on your Windows user rights.

IIS Authorization

Figure 19-5 shows how you can configure IP address restrictions with IIS. IP address restrictions provide you with a possibility of restricting access to the web server from machines specified in the list of granted machines. This makes sense if you want only a couple of well-known business partners to be able to access your web server.

C H A P T E R 1 9 T H E A S P. N E T S E C U R I T Y M O D E L

677

Figure 19-5. IP address restrictions in IIS

IIS and Secure Sockets Layer

The SSL technology encrypts communication over HTTP. SSL is supported by a wide range of browsers and ensures that information exchanged between a client and a web server can’t be easily deciphered by an eavesdropper. SSL is important for hiding sensitive information such as credit card numbers and confidential company details, but it’s also keenly important for user authentication. For example, if you create a login page where the user submits a user name and password, you must use SSL to encrypt this information. Otherwise, a malicious user could intercept the user credentials and use them to log onto the system.

IIIS provides SSL out of the box. Because SSL operates underneath HTTP, using SSL does not change the way you deal with HTTP requests. All the encryption and decryption work is taken care of by the SSL capabilities of the web server software (in this case, IIS). The only difference is that the URL for addresses protected by SSL begins with https:// rather than http://. SSL traffic also flows over a different port (typically web servers use port 443 for SSL requests and port 80 for normal requests).

For a server to support SSL connections, it must have an installed X.509 certificate (the name X.509 was chosen to correspond with the X.500 directory standard). To implement SSL, you need to purchase a certificate, install it, and configure IIS appropriately. We’ll cover these steps in the following sections.

Understanding Certificates

Before sending sensitive data, a client must decide whether to trust a website. Certificates were designed to serve this purpose, by making it possible to partially verify a user’s identity. Certificates can be installed on any type of computer, but they are most often found on web servers.