Example Authentication and Authorization Scenarios

[Previous] [Next]

Let's look at some common identity flow scenarios and the authentication and authorization implications of each.

The Complete Delegation Scenario

This first example is new with Windows 2000: the user accesses the Web server, which authenticates the user using Integrated Windows or Basic authentication. Authorization is performed when the user accesses Web pages or other objects (such as writing to files) or invokes components by virtue of access control list (ACL) checks on the files.

The Web server accesses remote COM+ applications configured to delegate the calling users. COM+ authorization includes checks of launch permissions and method roles, and code-based access checks through the use of the IsCallerInRole method. For more on these checks, see Chapter 7, "COM+ Security Overview."

Finally, the COM+ application impersonates the user and then calls SQL Server by using OLE DB. SQL Server is configured to use Windows security, rather than standard security, and the database connections from COM+ to SQL Server have the Trusted_Connection connection option set—that is, each connection uses the calling client's identity rather than the COM+ launch account identity. This assumes that the COM+ component is impersonating the original caller. If a COM+ component does not impersonate the user, the request to SQL Server has the identity of the process used to launch the COM+ application.

For example, the following OLE DB connection string will connect to a computer named DBServer, open the ExAir database in SQL Server, and use the calling user's identity:

 Provider=SQLoledb;Server=DBServer; catalog=ExAir;Trusted_Connection=Yes 

This is in contrast to a connection like the following one, which uses an embedded username and password:

 Provider=SQLoledb;Server=DBServer; catalog=ExAir;uid=DBUser;pwd=!611M 

If you specify a username and password for a trusted connection, the username and password are ignored.

NOTE
Go on, admit it—how many of your Web pages make connections to a SQL Server database using the following connection string?

Provider=SQLoledb;Server=DBServer;catalog=ExAir;uid=sa;pwd=

We see a lot of these in ASP pages, where a Web developer uses the SQL Server system administrator account (that is, sa) to access SQL Server data and leaves the password blank. This is a very bad thing; do not do this. Do not use sa to connect to a SQL Server, because sa is an administrative account with special privileges in SQL Server. It is not a generic data access account.

While we're on the subject, never leave the sa password blank. Give it a strong password. Refer to Appendix B, "Strong Passwords," for details on what makes a password strong.

The Web application might or might not include specific authorization at the Web server other than ACL checks performed by the Web server itself. However, at the very least, we need to flow identity from the Web server to COM+ objects and SQL Server and determine whether we're going to perform extra authentication and authorization steps along the way.

There's one important note about all this. When any access is made from one computer to another, Windows 2000 attempts to authenticate the connection first. For example, when an ASP page in IIS launches the COM+ component on a remote server, Windows 2000 attempts to authenticate the user before access to the remote server is granted. If access is granted, the COM+ application starts up and then attempts to query SQL Server on another computer. Windows 2000 will authenticate this new connection before access to SQL Server is granted.

Here are the steps taken, assuming no authentication or authorization failures occur:

  1. The client accesses the Web server, which is configured to use Integrated Windows or Basic authentication.
  2. The Web server authenticates the client.
  3. The Web server loads the ASP page.
  4. The ASP page invokes a COM+ application on a remote computer.
  5. A new authenticated connection is attempted between the Web server and the COM+ server. In doing so, the server hosting the COM+ application authenticates the initial user.
  6. COM+ checks whether the user can launch the COM+ application and then checks (as the calls are made) whether the user can make method calls.
  7. A method in the COM+ application impersonates the original caller.
  8. The same COM+ method call sends a query to SQL Server over a trusted connection. The computer hosting SQL Server verifies that the user can access this computer.
  9. SQL Server then checks whether the user has access permission to the database and then to each table accessed or stored procedure used.

As you can see, this process is a little involved, but it is, by far, the most secure scenario. At no point can an attacker get around any system, because each part of the application performs its own authentication and authorization and all use the same user account database, Active Directory in Windows 2000, and the same authentication mechanism, Kerberos.

Notice that both Integrated Windows authentication and Basic authentication are listed as possible authentication modes capable of supporting this scenario. Integrated Windows authentication as a choice is easy to explain: it natively uses Kerberos, and Kerberos supports delegation. But why Basic authentication? Basic authentication is a special case because when IIS calls LogonUser to authenticate and log the user account on to the system, the call primes the Kerberos Security Support Provider (SSP) with the user's credentials in case Kerberos is required later. Hence, the scenario works with Basic authentication and any browser that supports Basic authentication, even if the user is accessing the Web server from across the Internet. Of course, we hope you're using SSL/TLS to protect the username and password!

Figure 8-5 shows where authentication and authorization are performed in the complete delegation scenario. We'll explain the setup and configuration of this scenario in Chapter 10.

click to view at full size.

Figure 8-5. Where authentication and authorization checks occur in a full delegation scenario using Kerberos.

A caveat regarding the complete delegation scenario

From a security perspective, the complete delegation scenario is an excellent approach: there's one set of user accounts at any point in the system, and you can deny access to a user or group. However, you should keep in mind that in this scenario database connection pooling is defeated when authenticated connections are used between the COM+ applications and SQL Server.

Database connection pooling enables an application to use any unused connection from a pool of connections that do not need to be reestablished for each use. Once a connection has been created and placed in a pool, an application can reuse that connection without performing the complete connection process. The main benefit of connection pooling is improved performance. Connection pooling is defeated when authenticated connections are used because it requires that all connections in the pool have the same identity associated with them. This is so that any user at any point can pick up any established connection. And, by definition, an established connection has already been authenticated. We'll elaborate on this issue in Chapter 10.

IIS, COM+, and SQL Server as Gatekeepers

In this scenario, IIS performs authentication and possibly authorization and passes the user's identity as an application-level variable to COM+ or SQL Server. At each step, COM+ or SQL Server can perform application-level authentication or authorization. By "application-level," we mean performed in user-written code rather than provided by an element of the operating system, such as ACLs in Windows 2000.

For example, a Web application might gather the user's identity by using Basic authentication and then authenticate the user against Windows 2000. Windows 2000 checks that the username and password are correct, as well as other logon rights, such as whether the user is allowed to log on at the current time. At this stage, we're using the operating system security services—Windows 2000, not an application, determines that the username and password are valid.

Assuming the authentication step succeeds, the ASP Request.ServerVariables("AUTH_USER") variable contains the name of the user and Request.ServerVariables("AUTH_PASSWORD") contains the user's password. This works for Basic authentication only because Basic is the one authentication scheme that passes the password in the clear to the Web server.

WARNING
Make sure to use SSL/TLS if you're using Basic authentication. Usernames and passwords are subject to disclosure otherwise.

The user credential data is then passed to COM+ business objects, which in turn pass the username and possibly the password on to SQL Server. Using application logic rather than operating system security, the COM+ applications and SQL Server can make authorization decisions. You're assuming that Windows 2000 and IIS have performed valid authentication steps that lead IIS to fill in the AUTH_USER and AUTH_PASSWORD server variables. Figure 8-6 shows the flow of user identity from the Web server to COM+ and SQL Server.

click to view at full size.

Figure 8-6. User identity flows from the Web server to COM+ and SQL Server as arguments to method calls and SQL queries.

Sample banking ASP code in IIS looks like this:

 <% Option Explicit %> <% Dim strTellerName, strTellerPassword, strAccount, Dim strType, lAmount, iRet strTellerName = Request.ServerVariables("AUTH_USER") strTellerPassword = Request.ServerVariables("AUTH_PASSWORD") strAccount = Request.Form("Account") strType = Request.Form("Type") lAmount = Request.Form("Amount") ' Create the business object. ' Note there is no need to use Server.CreateObject in IIS 5; ' CreateObject will suffice. Dim oBusinessObject Set oBusinessObject = CreateObject("Bank.Funds") oBusinessObject.Withdraw strTellerName, _ strTellerPassword, _ strAccount, _ strType, _ lAmount %> 

In this example, the ASP code gets the username and password from IIS and various account data from a posted form; invokes a COM+ business banking object written in Microsoft Visual Basic on a remote server (by using a COM+ application proxy); and then passes the user's credentials, the bank client's account number and account type, and a value to withdraw from the account. The Visual Basic code, which in turn calls a SQL Server stored procedure, might look something like this:

 Sub Withdraw(ByVal strTellerName As String, _ ByVal strTellerPassword As String, _ ByVal strAccount As String, _ ByVal strType As String, _ ByVal lAmount As Long) Dim oRS As New ADODB.Recordset Dim strSQL As String Dim strConnect As String strConnect = "Provider=SQLoledb; " & _ "Server=FINANCES; " & _ "Initial Catalog=bank; " & _ "UID=bankid; pwd=" ' Build up call to spWithdraw stored procedure. strSQL = "{call spWithdraw('" & strTellerName & "', " & _ "'" & strTellerPassword & "', " & _ "'" & strAccount & "', " & _ "'" & strType & "', " & _ Str(lAmount) & ") }" oRS.Open strSQL, strConnect Set oRS = Nothing 

Note how we are no longer using a trusted connection between the COM+ application and SQL Server. Instead, the Visual Basic COM+ application uses a predetermined account named bankid that has no password to make the connection. The following code then calls a SQL Server stored procedure, which performs the real work and makes the decision about whether the teller can make the withdrawal for the client:

 CREATE PROCEDURE spWithdraw(@tname char(64), @tpassword char(20), @acc char(10), @acctype char(10), @amount money ) AS if (select count(*) from tellers where tellername = @tname and tellerpassword = @tpassword and limit >= @amount) >= 1 begin update accounts set balance = balance - @amount where account = @acc and accounttype = @acctype and balance >= @amount end 

From an implementation perspective, this common authentication and authorization example is organized as shown in Figure 8-7.

The SQL UPDATE will occur only if all of the following are true:

  • The teller is authorized to withdraw from the account.
  • The account and suffix exist.
  • The client has the funds.

In other words, the SQL UPDATE performs application-level authorization.

click to view at full size.

Figure 8-7. The Web server authenticates the user and passes the user's credentials as arguments to various middle-tier and back-end services.

The downside to this scenario is simple: it's insecure! It's easy to call the stored procedure, directly pass in the name of a teller, and bypass the authentication step performed by IIS, as described earlier in this chapter.

NOTE
One of the reasons for the scenario's insecurity is an attacker's ability to try thousands of passwords by creating a simple application that calls the stored procedure directly and changes the password for each new request. Because SQL Server does not know that the second argument to the stored procedure is a password, it cannot perform bad-password lockout as Windows 2000 does. Such an attack will fail if Windows 2000 accounts are used throughout the application.

This scenario is secure enough for systems in which the data is noncritical or the COM+ and SQL Server servers are adequately protected from attack should the attacker bypass the security steps performed by the Web server. However, be sure to avoid a mistake that's commonly made when creating this security solution: adding a SQL Server username and password in the ASP code or COM+ component code.

For example, an ASP page with a line of code like the following one is dangerous:

 <% oDB.Open "{call spGetPlaneMaintenanceRecords}", _ "Provider=SQLoledb; " & _ "server=DBServer;initial catalog=ExAirMaintenance; " & _ "uid=EngineeringAccount;pwd=$##D0n+Te11;network=dbmssocn", _ 0, 1 %> 

Here are the problems this code creates:

  • Providing a username and password to SQL Server works only with SQL Server's legacy authentication scheme, standard security. However, Microsoft recommends that SQL Server use integrated security (Windows NT Security) rather than standard security.
  • The application will no longer work if the password is changed in SQL Server.
  • The application will not work if the username or password is not correct in the ASP or Visual Basic code.
  • If a nonauthorized user gains access to the ASP or Visual Basic source code, that user also gains access to the "secret" SQL Server username and password. The most common cause of this type of vulnerability is incorrect ACLs on the ASP files.

NOTE
Another common cause of ASP source code disclosure is the inclusion of sample software on the Web site's production servers. For example, IIS 4 included sample code to view other ASP source code as part of a complex demonstration. Clearly, this should not be included on a production Web site.

Adding authorization to IIS

Notice that SQL Server performs all authorization in this example by calling a stored procedure that determines access. However, sometimes you'll want to add a greater degree of authorization to the application. Of a number of ways to do this, the most common is to use Windows 2000 ACLs on files used by IIS.

For example, while writing this book, the authors set up a Web site for document reviewers to use to access the latest versions of manuscripts. Access to all other parts of the Web site was open, but access to the manuscripts was restricted to a list of trusted people. To achieve this, we used two ACLs. All normal files had the following ACL:

  • Everyone (Read)
  • Administrators (Full Control)
  • SYSTEM (Full Control)

The ACL for the manuscripts was as follows:

  • Reviewers (Read)
  • Administrators (Full Control)
  • SYSTEM (Full Control)

Reviewers is a local group containing the list of user accounts trusted to review the manuscripts.

ACLs on Files

It's generally considered good practice to use groups rather than individual user accounts when setting ACLs. Use local groups when you need to add a number of users to an ACL on a resource. To do this, perform the following steps:

  1. Create a local group by using the Local User and Groups Microsoft Management Console (MMC) tool.
  2. Add users to the local group.
  3. Give the local group the appropriate access to the resource in question.

It's easier to maintain local groups rather than individual accounts. Imagine having 1000 resources, each with an ACL like the following:

  • Everyone (Read)
  • Squirt (Full Control)
  • Major (Full Control)
  • Cheryl (Full Control)
  • Administrators (Full Control)

A year or so later, it's decided that Frodo also has full control of all resources. You now need to go to all 1000 resources and change the ACLs. A painful task indeed. Instead, it would be better to have an ACL like the following one on the resources in question:

  • Everyone (Read)
  • Trusted People (Full Control)
  • Administrators (Full Control)

Trusted People is a local group containing the Cheryl, Major, and Squirt accounts. Add Frodo to the Trusted People local group, and you don't need to change any ACLs on any resources.

Finally, don't set ACLs on files. Set them on directories and use ACL inheritance—it's easier to manage!

Alternate Web authentication schemes

You'll notice that the sample banking ASP code shown earlier uses the Request.ServerVariables("AUTH_USER") variable. This will work with the following authentication schemes only:

  • Basic authentication
  • Integrated Windows authentication (NTLM or Kerberos)
  • Digest authentication
  • Certificate mapping

The variable is an empty string if you use Anonymous authentication.

All these mechanisms, described in detail in Chapter 5, "Internet Information Services Security Overview," use real Windows 2000 accounts. Sometimes, however, you might want to use alternate authentication schemes, such as cookie-based or forms-based authentication. These methods usually use a database, such as SQL Server, to perform a lookup of the username and password; if the username and password are valid, access is granted.

Forms-based authentication

Forms-based authentication requires the user to visit a login page and enter credentials, such as a username or identification number and a secret (such as a password) known to the Web site and the user. Usually, this step is performed over an SSL/TLS connection so that the information is encrypted and kept confidential. The credentials are then used as a lookup in the SQL database. For example, the following statement returns zero if a user whose identity is Mike and password is *7Y!2kJ is not found in the user table:

 select count(*) from user where id='Mike' and pwd='*7Y!2kJ' 

Once the user has been authenticated, the server creates a special session key unique to that session; it then adds the session key to the query string used by the browser on all subsequent requests so that the user does not need to be reauthenticated.

Take Care When Processing Strong Passwords with SQL

Be careful when processing usernames and passwords. Well-chosen passwords will likely include either quotation marks or single quotes. (Refer to Appendix B for more information on well-chosen passwords.) However, processing such passwords by using SQL in, say, Visual Basic or ASP code might cause an error. For example, say that the password is 1Auckland' and you use the following to build the SQL string:

 strSQL = "select count(*) from accounts " & _ "where id = '" & strUser & "' " & _ "pwd = '" & strPassword & "'" 

The following string results:

 select count(*) from accounts where id='mike' and pwd='1Auckland'' 

The two single quotes at the end of the string make this is an invalid SQL statement that will fail when SQL Server is asked to process it.

To avoid this problem, use the Replace function in the Visual Basic or ASP code to replace all instances of a single quote with two single quotes, thereby creating a valid SQL statement. Another method is to pass the data to a SQL Server stored procedure and use the SQL REPLACE function to perform the same task.

Session keys

The session key is often derived from the following items: username, password, random number, and timestamp. The random number is maintained by the server and is usually renewed on a regular basis or at each new session.

NOTE
Do not be tempted to use random number functions built into programming languages or programming language libraries, such as Rndin Visual Basic, randin C/C++, and Math.randomin Microsoft JScript. Most of these use mathematical formulae to derive their numbers. Although seemingly random, the values are predictable because they are derived using mathematical functions. This book's companion CD includes a COM+ object called CryptUtil.Randomthat generates better random numbers by using the Microsoft CryptoAPI (CAPI) tools.

The timestamp reduces the useful lifetime of the key. This means that the key is useless if someone manages to discover the key a few days or, possibly, hours after the session has finished.

To derive a session key, use the following algorithm

 R ":" T ":" HEX(HASH(R ":" T ":" U ":" P)) 

where

  • R is a random number, often called a nonce.
  • ":" is the colon character.
  • T is a timestamp.
  • HASH is a hash function, such as MD5 or SHA-1.
  • U is the user's identification or name.
  • P is the password.
  • HEX is a function that converts a binary data stream to a stream made of hexadecimal numbers (0-9 and A-F inclusive). You could also use base64 encoding, which converts a binary data stream to a stream made up of alphanumeric and punctuation characters. The Multipurpose Internet Mail Extensions (MIME) specification, RFC 1341, defines base64 encoding as a way to encode binary information for transmission in e-mail. Note that base64 encoding is not the same as UNIX uuencode encoding.

What Are Hash Functions?

Hash functions, also called digest functions, are cryptographic algorithms that produce a different output, called a message digest, for each unique data. Identical data has the same message digest, but if even one of the bits of a document changes the message digest changes. Message digests are usually 128 bits or 160 bits in length, depending on the algorithm used. For example MD5, created by RSA Data Security, Inc., creates a 128-bit digest, and SHA-1, developed by the National Institute of Standards and Technology (NIST) and the National Security Agency (NSA), creates a 160-bit digest.

Not only is it impossible to determine the original data by knowing just the digest, it is also infeasible to determine data that will match any given hash. A good analogy is your thumbprint. Your thumbprint uniquely identifies you, but it does not reveal anything about you.

NOTE
Once you've determined the session key to send back to the client, there's no need to use SSL/TLS. SSL/TLS need only be used when the user enters a username and password or when other sensitive data that should be encrypted is sent from the client to the server or vice versa. The reason is that the session key does not include the user's password.

The random number R must be expressed as cleartext as well as used in the hash if the server is to maintain no state for the user's connection; otherwise, the server won't know how to rederive the hash if it no longer has the nonce. Because the nonce is exposed as cleartext, it's often called a salt. Its main purpose is to make sure that two people with the same name and password who log on at the same time don't get the same hash. Because the random number changes for each connection, the hash changes also.

NOTE
Another use for salts is to prevent dictionary attacks, in which an attacker who has generated and stored hashes for every word in the dictionary manages to access your database file and rapidly compare password hashes rather than calculating hashes on the fly, which is a much slower process. If you add 80 bits of random salt, the attacker needs to pregenerate and store hashes for every word in the dictionary for each value of the random salt. For a 90,000 word dictionary, this is 90,000 hashes versus 90,000 x 2 ^ 80 hashes, or 108,803,323,765,317,000,000,000,000,000 hashes. Using a small amount of salt renders a dictionary attack infeasible.

The main purpose of T is to add a useful lifetime to the session key. For example, you might determine that a session is valid for no more than thirty minutes and, after that, a user must reauthenticate. Because the timestamp is in cleartext, the server can check it, and because the timestamp added to the hash, it's difficult to forge. It's usually better to add the timestamp as some form of numeric value rather than as a string representation of the date and time—that way you are not affected by any regional date formats. For example, you could use the following code to get the value of a date and time if you are using VBScript in an ASP page:

 <% Dim dTimeStamp dTimeStamp = CDbl(Now) %> 

This will encode the current date and time as a double-precision floating-point number. For example, 24-Nov-1999 6:03:46 PM becomes 36488.7526157407, and the latter number is then included in the session key. You can check that the session key has not expired with the following ASP code:

 <% ' Maximum session time is 30 minutes (30 x 60 seconds). Dim MAX_SESSION_TIME MAX_SESSION_TIME = 30 * 60 If DateDiff("s", dTimeStamp, Now) > MAX_SESSION_TIME Then ' Session is too old. ' Redirect to login page. Response.Redirect("login.asp") Else ' Normal processing. End If %> 

The same code fragments in JScript look like this:

 <% var dt = new Date(); var dTimeStamp = dt.valueOf(); %> 

The timestamp in this case is not a double; rather, it's expressed in milliseconds elapsed since January 1, 1970 UTC. For example, 15-Apr-2000, 8:13:38 PM Pacific Daylight Time becomes 955854818666. The following JScript code will verify that the time is within the valid range:

 <% // Maximum session time is 30 minutes. // (30 x 60000 milliseconds). var MAX_SESSION_TIME = 30 * 60 * 1000; var dtNow = new Date(); var dNow = dtNow.valueOf(); if (dNow _ dTimeStamp > MAX_SESSION_TIME) { // Redirect to logon page. } else { // All ok. } 

Note that it is assumed that dTimeStamp contains the timestamp held in the session key and is parsed out of the query string elsewhere in the server-side ASP code.

So, what does one of these session keys look like? Here's an example of what one might look like using the Visual Basic code defined above:

 01E28172AAB99182:36488.7526157407:49EC8175911A9FE709EAB6EA 

You can get the query string by using Request.QueryString inside your ASP code and parse out the session key by using a regular expression. In Visual Basic, use the following syntax:

 Dim strQueryString, regExp set regExp = New RegExp strQueryString = Request.QueryString regExp.Pattern = ":(.*):" Set colMatches = regExp.Execute(strQueryString) dTimeStamp = colMatches.item(0) 

The same expression in JScript looks like this:

 var regExp = /:(.*):/; var strQueryString = Request.QueryString; regExp.exec(strQueryString); var dTimeStamp = RegExp.$1; 

Now back to the session itself. The first series of hexadecimal numbers before the first colon is a 128-bit random number. The number before the second colon is the timestamp and the final series of hex digits is the hex-encoded 160-bit result of the SHA-1 hash of the random number, timestamp, username, and password. For an attacker to reconstruct a valid hash, she must know

  • The random number maintained by the server
  • The timestamp
  • The username
  • The user's password

This is certainly not a perfect authentication scheme—and it's in no way as good as the authentication schemes in Windows 2000—but it might be good enough for noncritical environments, such as those providing access to subscriptions or real-time stock updates. The scheme's weakness stems from it being subject to replay. In other words, an attacker sniffing the connection between your computer and the server might learn the session key and use it to access the data without needing the password because the session key is used to gain access.

To minimize this risk, reduce the useful lifetime of the session key in your ASP code. For example, if the key is valid for only 15 minutes, an attacker can use the key for at most 15 minutes, after which time he must know the password to get a new session key. However, remember that the key is valid for only 15 minutes for the rightful user also, so try to balance usability and security.

Don't Use IP Addresses for Authentication Purposes

Why don't we use the IP address of the client in the hash too? That way no one could use the session key unless they also had the client's IP address. The session key algorithm would look like this:

 R ":" T ":" HEX(HASH(R ":" T ":" U ":" P ":" IP)) 

So why wouldn't this work? The Web server knows the IP address the connection is coming from; it's available in the Request.ServerVariables ("REMOTE_ADDR") variable. Think about it for a moment, and then read on!

The client IP address can be transient; it can change between requests. Imagine that your client is located behind a bank of proxy servers. She connects to your site and logs in, and you build a session key that includes the client's IP address. Right? Well, no! The IP address is the IP address of the proxy server. The next connection from the client might not come through the first proxy server; it might come through another proxy server that has a different IP address, and therefore the hash will no longer be valid.

Because forms-based authentication does not use real Windows 2000 accounts, there's no way to flow real operating system identity from the Web server to COM+ and SQL Server. Instead, the data must be sent as arguments to COM+ methods or properties and SQL statements. This can pose a risk if the connections between the computers are open to network sniffing or other forms of interception.

NOTE
Microsoft Commerce Server 2000 and Microsoft Site Server Membership and Personalization use forms-based authentication and map the user's identity to one or more groups by using low-level Windows 2000 security functions. They perform this by adding groups to a preset proxy user account token. Group membership information is held in the Membership Lightweight Directory Access Protocol (LDAP) Directory.

Making Basic authentication look like forms-based authentication

You can also use Basic authentication and leverage Windows 2000 user accounts without the Basic authentication dialog box appearing! You can do this in two ways: by using the XMLHTTP object or by using some little-known URL syntax.

The first method involves the Extensible Markup Language (XML) support built into Microsoft Internet Explorer 5.0 and later. This will not work with any other browser. Your code can prompt the user to enter the username (strUser) and password (strPwd) and then pass the information to the client-side JScript code shown below in Internet Explorer.

 <script> var xmlHTTP = new ActiveXObject("Microsoft.XMLHTTP"); xmlHTTP.open("get","http://www.exair.com/logon", & _ false, strUser,strPwd); xmlHTTP.send("xmlDoc"); document.write (xmlHTTP.responseText); </script> 

When the user's browser attempts to access http://www.exair.com/logon, which is configured to require Basic authentication, the XML object model attempts to handle the authentication phases for the user without Internet Explorer having to display the logon dialog box. Plus, so long as the Basic authentication realm does not change, Internet Explorer will continue to send the correct credentials to the Web server at www.exair.com and there'll be no need to use the XML again. You can find out more about this technology by searching for XMLHttpRequest at http://msdn.microsoft.com/xml.

The second method involves a little-known, but valid, URL format:

 http://username:password@webserver 

This is defined in RFC 1738, "Uniform Resource Locators (URL)," at ftp://ftp.isi.edu/in-notes/rfc1738.txt. The most relevant text, from "3.1. Common Internet Scheme Syntax," reads like so:

While the syntax for the rest of the URL may vary depending on the particular scheme selected, URL schemes that involve the direct use of an IP-based protocol to a specified host on the Internet use a common syntax for the scheme-specific data:

 //<user>:<password>@<host>:<port>/<url-path> 

Some or all of the parts "<user>:<password>@", ":<password>", ":<port>", and "/<url-path>" may be excluded. The scheme specific data start with a double slash "//" to indicate that it complies with the common Internet scheme syntax. The different components obey the following rules:

User An optional username. Some schemes (e.g., ftp) allow the specification of a username.
Password An optional password. If present, it follows the username separated from it by a colon.

The username (and password, if present) is followed by a commercial at-sign "@". Within the user and password field, any ":", "@", or "/" must be encoded.

Note that an empty username or password is different than no username or password; there is no way to specify a password without specifying a username. E.g., <URL:ftp://@host.com/> has an empty username and no password, <URL:ftp://host.com/> has no username, while <URL:ftp://foo:@host.com/> has a username of "foo" and an empty password.

For example, Cheryl's browser might gather her credentials and then use them to build up the following URL by using client-side JScript:

 https://cheryl:password@www.exair.com/logon 

There are limitations on what characters can be used in the URL. For example, DOMAIN\Account syntax will fail because the \ character is invalid. You can alleviate this issue by encoding the \ character as %2F in the URL. (2F is the hexadecimal value of the \ ASCII character.) If Cheryl wanted to include her domain information in the above syntax, she would have to enter

 https://EXAIR%2Fcheryl:password@www.exair.com/logon 

NOTE
Note the use of httpsrather than httpat the start of the URL. Because a valid username and password is provided in the URL, it will be in cleartext as it is sent to the server. Hence, a secure SSL/TLS session must be used to prevent attackers from determining the username and password.

This URL format does not display the username and password in the Web browser's URL field when accessing Web sites. Please also note that this method has been tested in Internet Explorer 5 and Netscape Navigator 4.7, but that there's no guarantee it will work in any other browser.

Cookie-based authentication

Cookie-based authentication is similar in principle to forms-based authentication, but the session key is sent as a cookie rather than in a query string. The biggest barrier to using cookies is the fact that some users disable cookie usage in their browsers, thereby ruling out this form of authentication for those users. Cookie-based authentication is most often used for low-security sites, such as those providing online subscriptions. For example, Dow Jones Interactive (http://www.djinteractive.com) uses this authentication, as do many newspaper Web sites.

The server will check whether you have the appropriate cookie set when you access the Web site for the first time. If the cookie is not there, is invalid, or has expired, you'll be directed to enter a username and password on a form. Assuming the username and password are correct, the server-side ASP code will build a new cookie that's stored on the client computer.

ASP can read cookies by using the Request.Cookies collection and can create or modify a cookie by using the Response.Cookies collection. You can make a cookie expire at a specified date by using the Expires property. For example, Response.Cookies("Subscription").Expires = "September 3, 2001" will make the cookie related to subscription expire on September 3, 2001; at that time the client will need to pay some more money to continue the subscription. However, this is not a secure mechanism because the expiration date can easily be changed in the cookie. If you want to enforce secure cookie expiration, you should build a field into the cookie that contains a hash of the date and some other data known only to the server.

As with forms-based authentication, identity flows at the application level and not as operating system identity.

Don't Rely on the HTTP Referer Header

The HTTP Referer—yes, the word is misspelled, but the name has stuck!—header is sent by a browser indicating which Web page linked to your page. Some misguided Web sites use this header as a means of authentication.

For example, the authors have seen commercial software that includes a page named post.cgi that takes user input from a form, newad.html, but only if the post came from newad.html. The CGI script, post.cgi, queries the Referer header—if it equals newad.html, the data must have come from newad.html and nothing else, right? No.

The header in question is just that, an HTTP header and nothing more, and it can easily be faked. The following simple Perl script shows how to get around this simple authentication scheme:

 #!/usr/bin/perl # Perl 'headers' use HTTP::Request::Common qw(POST GET); use HTTP::Headers; use LWP::UserAgent; # URL to send fake post $url = 'http://webserver/photoads/cgi-bin/post.cgi'; # build up a new post with 16,000 letter 'A's as the comment $ua = LWP::UserAgent->new(); $req = POST $url,[ Name => 'Mikey', Comments => 'A' x 16000]; # fill in the referer header $req->header(Referer => 'photoads/newad.html'); # send the request to the application $res = $ua->request($req); 

In short, do not use the Referer header for anything but analysis; it's too easy to spoof to be used for authentication means.

Cryptography required in ASP to perform custom authentication

Custom authentication mechanisms using forms and cookies require cryptography. While all Windows platforms have built-in support for cryptographic functions through the CryptoAPI, little of this is directly available to ASP programmers. CAPI supports key storage and retrieval, encryption, decryption, hashing, certificates, and more.

You can use CAPI from ASP by writing a C++ COM+ component—you could use Visual Basic, but CAPI is very low-level and C++ is a better language for that task—or you can use a prebuilt component such as AspEncrypt from Persits Software.

The following example ASP code uses AspEncrypt and could be used to perform the session key derivation described earlier:

 <% ' Create the Persits COM+ crypto component. Set oCM = Server.CreateObject("Persits.CryptoManager") Set oContext = oCM.OpenContext("WebAppContainer", True) ' Create SHA Hash object. Set hHash = oContext.CreateHash ' Constants used when creating random numbers. Const FORMAT_HEX = 0 Const FORMAT_BASE64 = 1 Const FORMAT_ASCII = 2 ' Initialize random number variable. Dim oRnd, iRnd Set oRnd = Server.CreateObject("CryptUtil.Random") iRnd = oRnd.GenRandom(32,FORMAT_ASCII) Set oRnd = Nothing dTimeStamp = CDbl(Now) strUserName = strUserName ' Taken from form post. strPwd = strPwd ' Taken from form post. ' Build up the text to be hashed. strHashValue = iRnd & ":" & _ dTimeStamp & ":" & _ strUserName & ":" & _ strPwd ' Derive the hash and get the hex result. hHash.Reset hHash.AddText strHashValue strHashValue = hHash.Value.Hex ' Build up the session key including the ' cleartext and the hash. strKey = iRnd & ":" & _ dTimeStamp & ":" & _ strHashValue %> 

Note the use of the CryptUtil.Random component—this is a C++ COM+ component written by one of the authors and included with the source code on the companion CD. More information about AspEncrypt can be found at http://www.persits.com.

Microsoft Passport

If all of this cryptography makes you a bit dizzy and you realize that you're really in the business of selling goods and services rather than building security infrastructure, you might want to consider using Microsoft Passport. Microsoft Passport is a single-sign-in technology for multiple Web sites. Once a Passport user has logged on to Passport, he can access any other Passport-enabled Web site without being prompted to enter credentials.

Importantly, you can access certain information about the user without prompting the user for it—this does not include credit card information, in which case the user will be asked if it's satisfactory for the data to be accessed. For example, assume you need to know the user's location to customize the user's experience of your site. If the user has already logged on to Passport, either through the Microsoft Passport site at www.passport.com or another Passport-enabled site, and then accesses your site, she will not be prompted to enter her Passport information again and you will gain access to her information without having her fill out another annoying form! The information is available to you as a service of Passport.

At the time of this writing, there were over 55 million Passport users worldwide and in excess of 200 Web sites. You can get more information about Microsoft Passport at http://www.passport.com.



Designing Secure Web-Based Applications for Microsoft Windows 2000 with CDROM
Designing Secure Web-Based Applications for Microsoft Windows 2000 with CDROM
ISBN: N/A
EAN: N/A
Year: 1999
Pages: 138

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