Security in IIS

[Previous] [Next]

I'd like to conclude this chapter with a discussion of IIS security and how it fits in with the other security-related topics I've talked about. Whether you're building Web-based applications that use ASP pages as a gateway to one or more COM+ applications, Web-based applications with HTML-based user interfaces, or Web-based applications that use HTTP but not HTML, your clients will go through IIS to get to your Visual Basic components. This should be sufficient motivation for you to learn how IIS security integrates with COM+ security.

Figure 11-13 shows life inside a typical Web application built with ASP pages and Visual Basic components. The first thing to notice is that INETINFO.EXE is the client's entry point into the middle tier. INETINFO.EXE is therefore the process that must authenticate the client. This means that you must rely on one of the authentication modes supported by IIS.

click to view at full size.

Figure 11-13. Clients that send HTTP requests to IIS are authenticated by INETINFO.EXE. IIS uses impersonation to run each client request under the identity of a specific user account.

The second thing to notice is that IIS must run each HTTP request under the identity of a specific security principal. INTEINFO.EXE runs under the identity of the system, so if IIS were to process client requests using its process token, each request would run under the system's identity and would have virtually no restrictions. Obviously, this isn't a good solution. Instead, IIS uses impersonation so that client requests can run under the identity of more restricted user accounts.

I described the threading architecture of IIS and ASP in Chapter 9. As you'll recall, when a client requests a simple .HTM page, IIS processes the request on an MTA thread. However, when a client requests an .ASP page, IIS hands the request to ASP.DLL, which switches the request to an STA thread in order to run the page. Even though the threading architecture is complicated, impersonation works correctly in IIS even when the request is processed by an STA thread from the ASP thread pool. This means that client requests always run under the identity of a user account and never under the identity of the system.

Well, almost always. IIS does a reliable but not foolproof job of switching client requests to a user-specific token. There's a small risk of an attack in which a bad guy switches the thread that's processing his request back to the system token. As you can imagine, you really don't want the bad guy running his malicious code under the identity of the system. This essentially removes any restrictions on what he can do.

In Chapter 9, I also described how IIS uses WAM components to run IIS applications in isolation. One motivation for running an IIS application in isolation is to improve fault tolerance. A second motivation is to eliminate the risk of a bad guy performing the kind of attack I just described.

A WAM component for an isolated IIS Application is configured to run in special COM+ server application. IIS automatically creates one of these COM+ server applications behind the scenes whenever it's necessary. When IIS creates one of these special COM+ server applications, it configures the application's identity using a special user account called IWAM_Machine, where Machine is the NETBIOS name of the local computer. This account is a local user account that's far more restricted than the system account. Even if the bad guy switches his request to the process token, he still can't run under the system's identity. As you can see, running an IIS application in isolation can be a valuable safety precaution. For this reason, many companies prefer to run their IIS applications outside of INETINFO.EXE by setting the Application Protection setting to Medium (Pooled) or High (Isolated).

By now, you know that IIS always runs client requests by impersonating various user accounts. But which user account does IIS use for a request? It depends on which authentication mode IIS is using. Before I dive into the topic of the modes that IIS uses to authenticates clients, I'd like to take a step back and talk about some important issues related to authentication using HTTP.

HTTP Security Standards

HTTP has become a widely accepted protocol because it allows you to reach clients running a variety of different operating systems and browsers, and it gives your application the potential to reach any user on the Internet. However, these benefits usually come with a few uncertainties.

When you use HTTP, you can't always assume that the client's identity can be authenticated with a user account in a Windows 2000 domain. In fact, you can't always assume that the client is running Windows. What's more, you might have to assume that the client computer and the Web server have to communicate through a firewall. What this boils down to is that an authentication mechanism such as Kerberos or NTLM won't suffice over the Internet.

Let me quickly review how Windows authentication works between a user and a remote server computer running within a private network. As you know, a path of trust must exist between the user's authority and the server computer. If the user and the server computer belong to the same domain or belong to domains with a trust relationship, the server computer can authenticate the user's calls using Kerberos or NTLM. Kerberos also provides the additional benefit of authenticating the identity of the server to the user.

Network authentication with Kerberos or NTLM requires a domain controller. The domain controller runs a protocol that helps the client and the server discover a common session key. This "shared secret" makes possible the establishment of a secure channel. Messages are encrypted using the session key on the sending side, and they're decrypted using the same session key on the receiving side. This process is often referred to as symmetric-key encryption.

Distributing a shared secret between any two computers on the Internet simply isn't feasible. It would essentially require every authority to have a bidirectional trust relationship with every other authority.

Fortunately, HTTP has matured to the point where a good deal of standardization has taken place in the areas of security and authentication. Secure Sockets Layer (SSL) has been adopted as the most common authentication protocol used with HTTP. SSL conducts authentication in a cross-platform fashion and it can be used to authenticate users from different organizations even if they don't belong to a common authority. SSL authentication is more accommodating than Kerberos or NTLM, however, it's still based on the concept of trust.

In the SSL authentication scheme, one party doesn't have to divulge its secret to another. Encryption is based on two keys instead of one. One key is used to encrypt messages, and a second key is used to decrypt them. An entity can thus distribute a public key while keeping the other key private. This scheme is known as asymmetric-key encryption.

Here's how asymmetric-key encryption works at a very high level. Let's say that I give you my public key. I can encrypt a message with my private key and send it to you. You can then decrypt my message using my public key. If you trust the fact that I'm the only one with a private key capable of encrypting the message, you can be sure that I sent the message. Likewise, you can use my public key to encrypt your messages before you send them to me. Once again, if you trust that I'm the only one with the private key for decrypting the message, you can be sure that your messages won't be read by anyone else.

There are a few things to note about asymmetric-key encryption. The example I just gave of authentication doesn't involve mutual authentication. You know about me, but I know nothing about you. If I needed to authenticate you so I could be sure that it was really you on the other end, you'd have to give me a public key as well. However, it should be clear from the example that mutual authentication isn't required in order to establish a secure channel. As long as one party exchanges its public key with another, the two can communicate in a secure fashion.

You should also keep in mind that asymmetric-key encryption is computationally expensive compared to symmetric-key encryption—somewhere in the neighborhood of 1000 times more expensive. This means that using public/private key pairs has a significant runtime cost. One other point I should mention is that SSL authentication doesn't rely strictly on asymmetric-key encryption. SSL is also capable of passing a secret session key using asymmetric-key encryption in order to set up a faster channel based on symmetric-key encryption. As you can see, SSL attempts to speed things up when it can.

Certificates

As you've seen, public/private key pairs allow you to create a secure channel without the need for shared secrets or a domain controller. However, the distribution of public keys raises another security concern. For example, what if a bad guy passes you a public key and tricks you into thinking that it's my public key? If you're fooled into encrypting messages with his public key, you'll be sending messages that he can read. To prevent this security hole, the distribution of public keys usually involves certificates and a central authority that must be trusted by all public key recipients.

A certificate (also known as a digital certificate) is a document that attests to the association between a public key and an entity such as a human or a company. A certificate attests that the public key held by the certificate actually belongs to the entity named in the certificate. The common Internet standard for certificates is defined by the International Telecommunications Union (ITU) in ITU-T Recommendation X.509. An X.509 certificate consists of the following fields:

  • Version
  • Serial number
  • Signature algorithm ID
  • Issuer name
  • Validity period
  • Subject (user) name
  • Subject public key information
  • Issuer unique identifier
  • Subject unique identifier
  • Issuer signature

A certificate must be signed with the issuer's private key. Without this key, the certificate would have no value. The issuer's signature can be verified using the issuer's public key. If an entity trusts the issuer, the entity can also be confident that the public key contained in the certificate belongs to the subject named in the certificate.

Certificates are issued by a certificate authority (CA). A CA is a trusted service or entity that vouches for the identities of those to whom it issues certificates. More specifically, a CA vouches for the authenticity of the public key held in the certificate. However, in order for this entire scheme to work, a path of trust must exist. You have to trust a CA in order to trust the digital certificate it issues.

Many third-party companies, such as VeriSign, act as CAs. When you want to obtain a certificate from a third-party CA, you have to prove your identity. After all, if the CA is going to vouch for you, it wants to be sure that you're really you. When you send a certificate request to a CA, you must also send a public key for which you have a matching private key. The CA creates the certificate by packaging your name and your public key together with its signature and then sends the certificate to you.

You should note that a certificate is useless unless the certificate recipient has the public key of its issuer. So how do you obtain the CA's public key in a reliable and secure fashion? The public keys of CAs such as VeriSign are well known and are installed with browsers such as Netscape Communicator and Microsoft Internet Explorer. When two parties both have the public key of a CA, a path of trust exists between them.

CAs can certify subordinate CAs, which can then issue their own certificates. It is therefore possible to create a hierarchy of CAs with parent-child relationships. The top-level CA must be trusted without a certificate from any other CA, and its public key must be independently known. CA hierarchies make it possible to create paths of trust between nonaffiliated entities. Microsoft has a product named Microsoft Certificate Server (MCS) that allows a company to issues its own certificates.

SSL and HTTPS

Microsoft supports a suite of four related protocols for dealing with certificate-based security: Secure Sockets Layer (SSL) 2 and 3, Transport Layer Security (TLS) 1, and Private Communication Technology (PCT) 1.

Microsoft created PCT to compete with SSL 2. However, over the last few years SSL 3 has become the de facto authentication protocol to use with HTTP. PCT is now considered outmoded and should be avoided. TLS 1 is essentially a newer version of SSL 3, so I'll use the term SSL for either SSL or TLS.

SCHANNEL (Secure Channel) is Microsoft's implementation of all four protocols. SCHANNEL is an SSP that plugs into the Windows security architecture just as NTLM and Kerberos do. SCHANNEL allows applications such as IIS and Internet Explorer to use SSL when they conduct authentication based on asymmetric-key encryption.

SSL is used in two ways. The more common approach is to use SSL with a server certificate. This allows clients to authenticate the Web server. The server has no idea who the client is, but a server certificate is all that's needed to establish a secure channel. The Web server can exchange messages with an unauthenticated client without the risk of the bad guy deciphering what the messages mean.

The second approach is to use client certificates with a server certificate. The obvious benefit to using client certificates is that it allows the Web server to authenticate its clients. Each client can be mapped to a user account, which makes it possible to rely on standard authorization techniques such as restricting access through role-based security. However, this scheme can be hard to set up because each client needs its own certificate. Once again, MCS can help if you want to pursue the option of distributing client certificates.

Client certificates can be mapped to user accounts in a Windows 2000 domain. When mapping certificates to user account, you have two options. You can map each certificate to its own user account, or you can map many certificates to a common user account. For example, you can map every certificate for each user in the Sales department to a single user account. The documentation that ships with IIS and MCS is a good place to start when you want information on creating and distributing certificates to your clients.

Once you have a certificate on the Web server (and optionally a certificate on the client) you can use Secure HTTP (HTTPS). HTTPS is nothing more than HTTP over SSL. HTTPS differs from HTTP in that it always uses encrypted communication using a secret session key. Also, HTTPS uses port 443 by default, whereas HTTP uses port 80 by default. When the client first establishes a connection to IIS using HTTPS, public keys are exchanged in certificates using a negotiation protocol known as SSL authentication.

Once you have a server certificate, clients can communicate using either HTTP or HTTPS. However, you can also configure an entire IIS Web site or a virtual directory to require HTTPS. If you have heavy security requirements, you can use HTTPS for every request. However, keep in mind that HTTPS is slower than HTTP because it uses asymmetric-key encryption to set up a secret session key. If some parts of your site are less sensitive than others, you might consider using a mixture of HTTP and HTTPS.

IIS Authentication Modes

Now that we've covered the basics of how certificates and SSL work, let's look at the five IIS authentication modes. These are listed in Table 11-5 in the order in which IIS attempts to use them at runtime.

The first choice of IIS is the fastest mode, Anonymous Access, which avoids authentication altogether. In this mode, the Web server doesn't know or care about the identity of the client. However, IIS must still use impersonation so that the request doesn't run under the identity of the system account. By default, IIS uses an account named IUSR_Machine, which is created when IIS is installed. IUSR_Machine is only the default anonymous user account; you can assign a different user account to the anonymous user account using the Internet Services Manager.

Since IIS always tries to process a client request without authenticating the client, if you want IIS to authenticate client requests so that they run under the identity of the user's account, you must do something to prevent anonymous access.

Table 11-5 IIS Authentication Modes

Authentication Mode Description What It Impersonates On By Default?
Anonymous Access Doesn't authenticate client IUSR_MACHINE Yes
Certificate-based Authentication Authenticates using SSL and client certificate User accounts Yes
Integrated Windows Authentication Authenticates using Kerberos or NTLM User accounts Yes
Digest Authentication Authenticates using password passed in encrypted form and a Windows 2000 domain controller User accounts No
Basic Authentication Authenticates using password passed as clear text User accounts No

There are two common ways to prevent IIS from running a request using anonymous access. The first approach involves disabling anonymous access. Using the Internet Services Manager, you can disable anonymous access for an entire site, a virtual directory, or individual files. The second way to force IIS to authenticate clients is to reconfigure the permissions for .HTM and .ASP files so that the IUSR_Machine account doesn't have the proper access permissions to read them. You can configure permissions for individual .ASP files or for entire virtual directories as long as they're on an NTFS partition. If IIS fails when attempting to access a file using the IUSR_MACHINE account, it then attempts to authenticate the client using one of the other modes.

The second choice of IIS is Certificate-based Authentication. This approach has by far the greatest administrative setup cost, but it's the preferred technique for authenticating clients and running their requests under the identity of established user accounts. Note that information about the client certificate is available programmatically. In fact, it's available through both the ASP object model and through interfaces in the COM+ Services Type Library.

Integrated Windows Authentication mode relies on Kerberos or NTLM. The client and the Web server negotiate which protocol to use and a secure channel is set up in the manner described earlier. The limitation of this mode is that it requires Windows and Internet Explorer. It also uses ports that are restricted by most firewall software. While this approach doesn't scale well on the Internet, it works great when client computers and the Web server run within a private Windows network and trust a common authority.

Digest Authentication mode is new in IIS 5. It's disabled by default, so you have to turn it on in order to use it. When a user initially connects to the site, the user is prompted for a user name and password. Digest authentication is like NTLM in that it uses a challenge-response protocol and doesn't transmit the password over the Internet as clear text. However, it has a few significant problems that render it unusable in most situations. The most notable problem is that you must run the Web server on a domain controller. This opens you up to some pretty bad attacks. If the bad guy compromises your domain controller, he compromises everything in the domain. The other problem with digest authentication is that user accounts must be reconfigured in the accounts database to store their passwords as encrypted clear text.

Basic Authentication mode is also disabled by default. As with Digest Authentication mode, the user is prompted for a user name and password. The browser transmits the user name and password in the HTTP authentication header using a Base64/UUEncoded encoding scheme. This encoding scheme was not designed to protect messages, so you should assume that the password is actually being sent over the Internet as clear text. Therefore, you should use Basic Authentication mode only with HTTPS. If you don't use HTTPS, this mode results in some pretty bad exposure.

The strength of basic authentication is that it's a longtime HTTP standard and is supported by most browsers. It works through firewalls and proxy servers, and it doesn't require much effort to set up (especially compared to certificate-based authentication).

You should note one other interesting thing about using basic authentication with IIS and ASP. The password is available to ASP scripts and Visual Basic components using the AUTH_PASSWORD variable in the ServerVariables collection. You can't disable this option, so you have to put a fair amount of trust in the people who are writing scripts and components. For example, a sneaky developer could write user name and password pairs out to a log file and use this information to mount an attack.

So which of the five authentication modes should you choose for your application? It depends. Each has its strengths and weaknesses. Certificate-based Authentication and Basic Authentication are the most popular modes for authenticating clients over the Internet.

You might get the impression that anonymous access is only for situations in which you don't care who the client is, but this isn't always the case. In some situations, you'll want to authenticate your clients but it won't make sense to maintain a Windows user account for each one. This is often the case when an application is designed to accommodate thousands or tens of thousands of users. If you want your application to scale to such heights, one option is to use a Microsoft product named Site Server, which has built-in support for tracking user profiles in a custom database. Another option is to hand-roll a custom security model.

For example, if you use anonymous access with HTTPS, you can create a secure channel. A client can safely transmit a user name and password across the Internet, and your application can supply a logon routine to perform custom authentication by running a lookup in an application-specific database to verify the user name and password. At this point, you'll probably need to generate some type of custom session key, which you send back and forth using HTTP cookies. A custom security framework such as this requires a substantial amount of code, but it provides greater flexibility and scalability.

Using IIS Authentication with Role-Based Security

Once you authenticate the client, you've only halfway home. To secure your application, you must also assign the proper access permissions to your .ASP files and/or your configured components. If your .ASP files (and other related files) are stored on an NTFS partition, you can configure them to grant or deny read access permissions or read/execute access permissions to users, groups, and aliases. It's relatively easy to configure access permissions on individual files and directories using Windows Explorer.

However, when you configure access permissions at the file and directory level, you can't take advantage of role-based security. As you'll recall, role-based security is valuable because it allows you to preconfigure authorization in a COM+ application and then deploy it in many production environments. Don't forget that the programmatic side of role-based security provides the benefits of conditional authorization checks and customized auditing.

There are three ways that you can configure a COM+ application that will be used by ASP page clients: You can configure it as a library application, a local server application, or a remote server application. Let's look at the strengths and weaknesses of each of these deployment schemes.

If you use a library application, your objects load onto the same STA thread as the ASP page that creates them. However, COM+ inserts a lightweight interceptor proxy between the ASP page and the object. This allows COM+ to run its declarative authorization checks each time a call is made from the ASP page to the object. You should observe that these authorization checks are run using a logon session and a token created in conformance with one of the IIS authentication modes. One of the advantages of using a library application is that it provides the best performance.

If you use a local server application, your objects load into a private and local instance of DLLHOST.EXE. Once again, COM+ inserts an interception layer between the ASP page and the object in order to conduct role-based authorization checks. Running authorization checks in DLLHOST.EXE requires the creation of another token. However, both processes are on the same computer, so there's no need to create a second logon session.

Take another look at Figure 11-13. The request on top is passed from INETINFO.EXE to DLLHOST.EXE. It's important to see that impersonation allows the user's identity to propagate from one server process to another. For example, if IIS authenticates the client as Bob, the ASP page in INETINFO.EXE runs under Bob's identity. When the call is made to DLLHOST.EXE, authorization checks can be conducted using Bob's token as well. This works smoothly because of a new feature in Windows 2000 called dynamic cloaking. (This doesn't work as well in Windows NT and IIS 4).

I've told you about using components from library applications and local server applications. Now I'll describe the third option and try to talk you out if using it. If you attempt to use a remote server application, you're likely to be in for heartache and frustration. Conducting role-based authorization checks on a computer that's one hop away from the Web server requires propagating a logon session across the network. This can be challenging or even impossible.

The problem is that most authentication modes used by IIS create a logon session without network credentials. In other words, the logon session doesn't include a password or some other proof of its identity. Without network credentials, the Web server can't propagate a logon session to another machine. In these cases, delegation doesn't work.

There are many ways to configure the authentication mode that IIS uses, and most of them don't result in a logon session with network credentials. However, with some effort you can make delegation work with basic authentication, certificate-based authentication or Kerberos.

However, you should consider avoiding delegation because it goes against the practice of authenticating and authorizing as close to the client as possible. Delegation is expensive because it requires propagating the client's identity from the Web server downstream to another server. This degrades performance. Whenever possible, try to perform authentication and authorization on the Web server itself.

Further Reading

Security is a daunting topic. I hate to admit it, but this chapter is just the tip of the iceberg. There's so much more to learn in areas such as domain administration, certificate distribution, and cryptography. What's more, you should keep up on which IIS attacks are most common so you can stay a few steps ahead of the bad guys. I have to apologize because I've left you with lots of homework.

If you want to master the administrative side of IIS and MCS, you should read the documentation that ships with these products. The Windows 2000 Resource Kit is also a valuable resource. It details how to get around in Active Directory and has good coverage of IIS.

If you really want to understand the guts of the Windows security model— especially if you're writing security-related code in C++—Keith Brown's Programming Windows Security is required reading. Even if you don't like to read C++ code examples, the book is valuable because it clearly explains the core concepts of Windows security.

Summary

The chapter started with a discussion of the core concepts of Windows security. Everything is based on principals. Authorities are services that allow one principal to authenticate another. Logon sessions and tokens are data structures created at runtime to cache authorization information about principals. Each process gets a process token that associates it with a principal and establishes its identity. A DACL is a configurable list of access permissions that makes it possible to run authorization checks against a principal's token at runtime.

Network authentication is performed by plug-in modules known as SSPs. Kerberos and NTLM are SSPs that are used to provide authentication services for computers communicating within a private network. The authentication level determines how actively the authentication service does its job. You should authenticate and authorize as close to the client as possible, which means that you should avoid COM+ application designs that involve impersonation or delegation.

The COM+ security model is based on roles. Roles decouple access permissions from SIDs, which makes it easier to deploy a single application in multiple production environments. You can preconfigure declarative role-based authorization checks, and you can also write code to conduct conditional authorization checks and audit user activity.

If you're creating a Web-based application, you must learn how IIS integrates with COM security. IIS uses impersonation to avoid running client requests under the identity of the system. The user account that IIS impersonates is determined by the IIS authentication mode. Using certificate-based authentication and basic authentication are two common ways to map Internet users to Windows user accounts. It's not uncommon to run requests under the anonymous Internet user account (which is IUSR_MACHINE by default).

Once a client is authenticated, the access permissions you've configured determine what the client can do. If you want to use role-based security, you should use configured components installed in a library application or a local server application. You should try your best to avoid the use a remote server applications. Conducting authorization checks on an application server a hop away from the Web server is expensive because it requires impersonation and possibly delegation. You should always prefer conducting authorization checks on the Web server itself.



Programming Distributed Applications with COM+ and Microsoft Visual Basic 6.0
Programming Distributed Applications with Com and Microsoft Visual Basic 6.0 (Programming/Visual Basic)
ISBN: 1572319615
EAN: 2147483647
Year: 2000
Pages: 70
Authors: Ted Pattison

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net