3.7 Verifying Site Security
This section discusses strategies for verifying the security of a Web system, providing step-by-step procedures for testing the areas discussed previously.
Authentication
Security verification of the Web system's authentication mechanism concentrates on the packet-level security of the login data: user ID and password. This evaluation is accomplished by using a packet sniffer tool, such as the Windows NT/2000 Network Monitor. The strategy presented here will help determine whether the user ID and password information is being transmitted in a secure fashion to the server across the Internet.
Acquire the ports used to access the site by both HTTP and HTTPS (SSL) connections. Typically, port 80 is used for HTTP, and port 443 is used for HTTPS. This example will use these two ports.
Connect to the site and navigate to the basic authentication dialog or the custom authentication form.
Start the network monitoring tool. At this point, it may be useful to filter out some of the network traffic to minimize the amount of captured messages. With the Windows NT/2000 Network Monitor, this is accomplished by selecting Filter...from the Capture menu, then double-clicking the SAP/ETYPE list entry. Click the Disable All button, select the IP ETYPE protocol entry from the list, and click Enable.
Switch back to the browser and enter the user ID and password of a valid test user in the basic authentication dialog box or the custom authentication form. Do not submit the data yet; simply enter the data into the fields.
Switch to the network monitor tool and start capturing network packets. With the NT/2000 Network Monitor, this is accomplished by selecting Start from the Capture menu or by pressing F10.
Switch back to the browser and click the OK button on the login dialog, or submit the custom form and wait for the next page to load.
Stop the capture in the network monitoring tool once the next page is received.
View the captured data by selecting Display Captured Data from the Capture menu or by pressing F12.
First, locate the initial entry from the client to the server, which is the entry that should contain the user ID and password. This entry should resemble the following:
Source: Name or address of the machine running the browser Destination: Name or address of the Web server host Protocol: HTTP, HTTPS or TCP Dest. Port: 80 (HTTP) or 443 (HTTPS)
If this entry is HTTP on port 80, the data in the packet should contain either the Authorization entry for Basic Authentication or the POST command with the form variables containing the user ID and password for the custom authentication form. If the data in the packet contains this information in plaintext, readable form, a security flaw exists.
If this entry is HTTPS or TCP on port 443, the packet data should be encrypted and therefore unreadable. Either of these packets should be followed by responses from the server to the client over HTTP, HTTPS, or TCP.
Authorization
Two separate kinds of tests are required to evaluate the correctness of the Web server authorization process. One test focuses on page/script accessibility and the other on data accessibility.
Page/Script Accessibility
For this test, first obtain a list of the pages and server-side components, including paths and required parameters, that are available to the Web system's various user roles. This list will vary, depending on the type of site that is being tested. If the engineering techniques presented in Chapter 2 were followed, this list will closely resemble the list of «interface» use cases. For TBS, a subset of the list of scripts looks like this:
Script Parameters Role /asp/BrowseByCategory.asp None All (including anonymous users no login required) /asp/ViewPreviousOrder.asp id=<order ID> TBS Registered Users
In addition, obtain a valid user account for each role. Once these two items have been obtained, test for page/script accessibility by attempting to access each script in the list by directly accessing the script. Do not log in to the site. For example, to test the I-Browse Catalog by Keyword functionality of the TBS case study, the following URL would be entered into the address box of the browser:
http://Homer/asp/BrowseByCategory.asp
This script is available to all users, so it should execute properly. If the script requires a parameter, you may need to obtain some additional information for the parameter. For example, the View Previous Order functionality requires an OrderID, so a valid ID would need to be obtained from the database. The URL for ViewPreviousOrder.asp would look like this:
http://Homer/asp/ViewPreviousOrder.asp?id=938193.
This script should fail to execute, as we have not logged in yet. If it does execute, a security flaw exists.
Data Accessibility
Even though the user is limited to the appropriate scripts, it may be necessary to restrict the data the user can view. For example, in the TBS case study, the user should not be able to view orders for other customers. For this part of the test process, you will need to obtain multiple valid users who have the same level of access but are allowed to view different data. You will also need the list of scripts and their parameters from the preceding part of the test strategy. You can safely remove from the list any scripts that do not retrieve data associated with a specific user, such as BrowseByCategory.asp, which retrieves the same data regardless of the user.
Log in with one of the user accounts and access one of the listed scripts. Make note of the data provided to the script used for retrieving the user's information. For example, the ViewPreviousOrder.asp script will require an OrderID to use as a basis for retrieving the order status.
Log in with one of the other user accounts, one that has the same level of access as in step 1, and attempt to access the script with the data used by the first user (OrderID). This should generate an error message denying access. If it is possible to log in with a different user account and to view the data belonging to the user from step 1, a security flaw may exist, as the system is displaying a user's private data to another user.
Content Attacks
To properly test most of the system security scenarios presented here, the Web system component must return a predictable error page if a problem is discovered with an input field. For example, if it detects that an input is too long or contains special characters, a component should display or redirect the browser to a predictable error page, such as "input error detected." This will be the indicator for the test to determine whether the script has effectively managed the input error. If the script does not detect a problem with an input field but still encounters an error, the Web server's standard internal error page should be returned. This will allow input-field error checking to be differentiated from other kinds of component errors.
Some of the strategies presented here may require manual editing of HTML pages. In other words, the page is saved to the local disk from the browser and then edited with a text editor and re-sent to the Web server.
System Command Execution
Testing for vulnerabilities in components that use system commands is somewhat dependent on the languages being used and the operating system on which the server is running. It is recommended, however, the Web system restrict all user input to support only acceptable characters, regardless of the back-end technology and operating system being used. This area of testing requires the Web server component to actively check for metacharacters in all its inputs. "Actively checking" means that the component examines all input data fed to it when the component is invoked. When it detects one of these characters, the component must return a predetermined error page, which will be the basis of the success or failure of the test.
The text on the error page can also assist in automated testing, as the testing script will know that the test has passed when it sees the expected error page. For example, consider an error page stating "Error: Invalid characters detected." An automated testing tool could be scripted to look for this page as the basis for a successful test, as the component properly detected the bad characters and returned the error page.
To further assist in the testing process, the component should check all its inputs up frontmeaning as early as possibleif possible. This will reduce the number of test cases, as some components may require a combination of good and bad inputs to produce the test case if the good inputs are needed to get to the point of checking for the bad inputs.
Obtain a list of Web server components, derived from the «interface» use cases, and their inputs. Each input should have a list of acceptable input characters associated with it. The list will look something like the following:
Valid input Component Parameters characters /asp/BrowseByCategory.asp None N/A /asp/ViewPreviousOrder.asp id=<order ID> [0-9]
This list should also include hidden form fields.
Verify that the components will return a predetermined error page when an invalid input character is detected. The predetermined error page can be captured by an automated testing tool, if desired; the successful capture of the error page represents the success indicator for the test.
For each input to the component, supply a single input character from the set of escape sequences or metacharacters that may cause unexpected behavior. On a UNIX system, the standard list of shell metacharacters is as follows (Kamthan 1999):
&;´'\"|*?~<>^()[]{}$ \n and \r
Most form field values should not allow the user to specify file path operations, so also check the following character sequence:
/..
Test each field individually; that is, do not attempt to populate all the fields with a bad character and send them in at the same time. Test one at a time so you can isolate any fields that may not be properly filtered.
Note that option and hidden inputs cannot be directly modified through the form page. This problem can be solved in several ways.
Save the page to disk and directly edit the value property of the input field.
If using an automated testing tool, directly modify the script to read the value from a file.
Supply the desired input values on the URL line. Note that all values must be entered in the URL for this method to function properly. Also verify that this is possible in the target Web system.
Server-Side File Access
Using the list of Web server components obtained in the previous section, examine the list of inputs for fully formed file names, including paths, or file name fragments. You may need to talk with the component's developer in order to determine the exact usage of some of the inputs.
Component inputs that can consist of fully formed file names present a possible security problem. The recommended action here is to have the component modified in order to eliminate this type of usage. However, if the server configuration is secured so as to protect against a user's accessing a dangerous file, this security mechanism can be tested by supplying an alternative file name in place of the one in the form before it is submitted. This type of test can be performed by using an automated tool or by saving the page to disk and manually editing the field value. Some coordination with system administrators may be necessary to find appropriate file names with which to test.
If the input is a file name fragment, it should be tested as outlined in the previous section. Particular attention needs to be paid to the ../ sequence of characters.
Buffer Overflows
Much like testing component inputs for dangerous metacharacters, testing buffer overflows requires that the component actively check the lengths of all inputs. Component inputs are either HTML form fields or name/value pairs. A name/value pair is a field name and a value, separated by = on the URL line and is formatted as a name/value pair. A sample set of input might look something like name=Norma, orderID=12345.
When an input string that exceeds the maximum length is detected, the component should return a predetermined error page. The successful display of the error page represents a successful test result. The security test procedure is concerned with verifying that an overflow condition cannot be created, by supplying long inputs to the component. The error message produced is simply a way to confirm that the component has properly detected the invalid input and then aborted the activity.
The list of Web system components should be augmented with the maximum length of each input that the component will accept. If the engineering techniques described in Chapter 2 are used, these lengths should be documented in the «interface» use case descriptions. If the input length exceeds this value, the component must return the predetermined error page. If the error page is not returned, a security flaw exists.
For each input to the component, supply an input string that exceeds the maximum size by one character. This should return the predetermined error page. Also try the test with an input string that is exactly equal to the maximum size of the field and watch the behavior of the component with this input. Boundary conditions often cause problems when dealing with buffers and string operations. Any printable character is acceptable as input, as long as it is within the valid set of characters that the component is willing to process. A long string of A characters will usually suffice.
Typically this type of test must be performed either by saving the HTML page to disk and manually editing the value attribute of an input field or by using an automated testing tool to send in the data. As with metacharacter testing, make sure that each field is tested one at a time so any problematic fields can be isolated.
Database Security
Most of the database test strategies are difficult to carry out in an automated fashion, as the access methods and data involved are quite variable. Therefore, testing in this section assumes that the proper vendor-supplied database tools to connect to and to query the database are available.
Data Encryption
This test strategy is aimed at verifying that data in the database is being stored in an encrypted form. Test steps include submitting sensitive data and then executing a query for the data in the database. These types of activities require a working knowledge of the database access tools pertinent to the particular database being used. Knowledge of the system's database schema is also necessary.
Enter values for each form field that requests sensitive information, such as first/last names, telephone numbers, addresses, and credit card numbers. Note the exact values entered and submit the form. It may be necessary to navigate through several forms to ensure that the information has been stored in the Web system's database. For example, it may be necessary to navigate through all the forms necessary to complete a payment transaction.
Once the form has completed processing, open the database query tool and query the appropriate table and columns for the fields entered in the previous step. If the data is successfully queried, it is stored in an unencrypted form and should be regarded as a possible security risk.
Temporary and Log Files
The following strategy investigates the use of temporary and log files by Web system components. The goal is to locate components that expose private data by storing it on the server's file system in an unencrypted form.
Obtain a high-privilege user account on the server, such as one of the Web servers or another back-end server, that processes sensitive data. This account must have a very high privilege, such as the root account on a UNIX system or the administrator account on a Windows NT/2000 system.
Also obtain a list of the Web system pages that invoke the processing of sensitive user data, including the submission of payment information or the management of account data. Note that access to some of these operations may not be possible through the Web server, such as after-hours batch processing.
For each operation in the list, from the previous step, enter a set of sensitive data and invoke the operation.
For each piece of sensitive information entered in the previous script, search the server's file system for all files containing this data. On UNIX, this can be accomplished by using the find command, as follows:
find / -type f | xargs grep "private data"
On Windows NT/2000, select Search from the Start menu, choose For Files or Folders, and enter the private data in the Containing Text box.
If the data travels through multiple servers, such as the Web server and then a credit card processing server, make sure to search each server's file system. Any files discovered containing this data should be considered a security hazard, as they exist after the processes have completed executing.
This test strategy will not detect temporary files used in a transient fashion by server processes.
Access to Database Objects
This test requires the availability of the appropriate database tools and knowledge of the system's database schema. Sample data must also be prepared and stored in a test database.
Obtain a low-privileged, temporary user account for access to the database that contains the Web system data.
Next, try to query database tables commonly accessed by the system. Make sure to test all operations, including select, update, insert, and delete. Any successful queries against the database by this user indicate that the objects in question are not properly secured.
After the tests are completed, remove the temporary user account from the database.
Database User ID and Password
This strategy attempts to locate plaintext user ID and password information in Web server components. Used to connect to the site's database, this information may be hard coded into Web system componentseither in script source or in binary componentsor stored in a configuration file or the registry.
Obtain a high-privileged user account on the server containing the system components that access the database. The user account must have very high privileges, such as the root account on a UNIX system or the administrator account on a Windows NT/2000 system.
Obtain the user ID and password information used to access the database server. Note that several database accounts may be used by Web system components, as some systems may be designed to have their components connect to the database server as one of several users, to support different access levels. Therefore, it is important to obtain the complete list of accounts. Note that databases can typically maintain their own user account lists. So technically, a database account is the same as a user account, but it's not the same as a user account managed by the operating system. For example, a user named Joe might be in the database yet not have any corresponding user account managed by the operating system.
For each database account, search the server's file system for all files containing the user ID and password. On UNIX, this can be accomplished by using the find command:
find / -type f | xargs grep E "userID | password"
On Windows NT/2000, select Search from the Start menu, choose For Files or Folders, and enter the user ID in the Containing Text box. If any files are located, examine them for the presence of the password as well.
Any files discovered containing this data should be considered a security hazard, as they contain plaintext database user ID and password information. The information in these files should be properly encrypted to protect against unauthorized access.
If the Web server is running on a Windows NT/2000 platform, also search the system registry for each database account user ID and password, using the regedit utility.
Database Schema
This test requires knowledge of the database schema, preferably in documentation form with all table and column names.
Obtain a list of the interface pages that result in access to data in the site's database, such as ViewPreviousOrder.asp in the TBS case study.
Access each of these pages and save each page to disk as an HTML file in a local directory on the client computer.
Perform a Find in Files function (Windows) or a grep function (UNIX) and search for the database schema elements in the text of the HTML files. If any are found, each instance should be examined as a potential security issue.
Client Computer
This section examines the validation of security vulnerabilities in client-side ActiveX controls and cookies.
ActiveX Control Buffer Overflows
When it detects an input-length error, the component being tested must be coded to return a specific error. An ActiveX control must return a unique error code, or hresult, indicating that it has properly handled the input-length error. This code can be determined by wrapping the calls to the control in a try/catch block for JScript or setting the On Error handler for VBScript. The error code can be determined by examining the error object's error number property.
The following steps demonstrate how to perform ActiveX control input-length testing.
Obtain a list of the accepted inputs to the ActiveX control and the associated maximum length of each input. The control will have three ways of receiving input parameters: (a) PARAM attributes of the OBJECT tag, used to initialize the control with values when it is created on the page; (b) Properties that can be set through client-side script languages, such as JScript; (c) method calls from client-side scripts that take inputs. If the field length exceeds the length value for any of these inputs, the control must return the predetermined hresult code. If the code is not returned, a security flaw exists in the control
Test the inputs that are passed by the PARAM attributes of the OBJECT tag. Test one PARAM at a time and watch for the appropriate error to be returned by the control. For example:
<OBJECT ID="mycontrol" WIDTH="255" HEIGHT="50" CLASSID="CLSID:0918329-B8D0-101A-91F3-1183EA001DA3" CODEBASE="http://Homer/mycontrol.cab#Version=1,0,0,001"> <PARAM NAME="UserName" VALUE="Julie"> </OBJECT>
To test the UserName parameter, replace Julie with a string that exceeds the maximum length specified by the control's developer. Also try the test with an input string that is exactly equal to the maximum size of the input. This should be accepted by the control, but watch the behavior of the control with this input, as boundary conditions often cause problems when dealing with buffers and string operations. Use any printable character, making sure that it is within the valid set of characters that the control is willing to process. A long string of A characters will usually suffice.
For each property or method of the control, supply an input string that exceeds the maximum size by one character. The control should return the appropriate error code, as demonstrated by the call to e.number. For example, assume that the control created in step 2 has a property, customerID, and a method, AddToCart, that accepts and stores a string input:
<SCRIPT LANGUAGE="JScript"> function testTheControl() { try { mycontrol.customerID = "115A"; mycontrol.AddToCart("Television"); } catch(e) { // display the error code window.alert(e.number); } } </SCRIPT>
ActiveX Control File Access
ActiveX controls must be tested to determine whether they accept and use file names as inputs. Controls that do accept such input could result in malicious manipulation to access other files on the user's local disk.
Using the list of input parameters for the control obtained in the previous section, look for any inputs that are fully formed file names, including paths, or file name fragments. This may require some discussions with the control's developer to determine the exact usage of some of the inputs.
If the input is a fully formed file name or a fragment, a possible security problem exists. The recommended action here is to revise the control to eliminate this type of usage.
ActiveX Control Storage of Private Information
ActiveX controls are essentially full-featured programs, so they can store information in files on the user's local disk. If this information is private or confidential, the control may be a security risk. This test attempts to determine whether the control is storing any data on the local disk of a client machine.
Using the list of input parameters for the control obtained in the previous section, exercise each of the control's PARAM elements, properties, and methods, using the same value. This value should be relatively obscure, such as ABC123DEF456. Some discussion with the control's developer may be necessary to properly use the control's methods.
Once each input has been exercised, search the client machine for occurrences of this string in both the file system and the system registry. Searching the file system on a Windows machine can be accomplished by selecting Search from the Start menu, choosing For Files or Folders, and entering the string data in the Containing Text box. The registry can be searched by using the regedit tool provided with the Windows operating system. Any occurrences of the unique string in either place should be examined for potential privacy problems. In some cases, this problem could be solved by the ActiveX control making use of the Crypto API to encrypt the information prior to storing it on disk or in the registry.
Cookies
Cookies present another opportunity for the storage of sensitive user data on the local disk, which may be compromised if an intruder gains access to the user's machine. This test examines cookies set by the Web site to determine whether any confidential information is stored.
Obtain a list of the Web pages that accept private user information, such as names, addresses, telephone numbers, and credit card information.
For each page on the list, enter some test information into the fields. Make sure to note the data entered or to print out each page following entry of the data.
Examine the site's cookie file by opening it as a text file. With the Microsoft Internet Explorer browser, cookies are stored in the user's Temporary Internet Files folder, with a name similar to the following:
Cookie:<username>@<sitename>
The site name will be the host name portion of the URL. For example, in http://Homer/shoppingcart.htm, the site name would be Homer. If any of the data entered in the page is present in the cookie file, a security flaw exists. As with client-side file use, the recommended action is not to store data this way; however, the data can be encrypted to prevent cleartext access.
Secure Communications
The test strategy in this section verifies that any private information transmitted between the user's browser and the Web site is encrypted to prevent third parties from intercepting the data while it is in transit. This section requires the use of a sniffer program, such as the Windows NT/2000 Network Monitor.
Obtain a list of the server pages that accept private user information, such as names, addresses, telephone numbers, and credit card information. These pages should be the ones protected by a secure channel.
On a client machine, set the browser to warn when switching between secure and insecure communications. This will provide feedback when the secure channel is being entered and exited by the client browser.
Start the network monitoring tool. It may be useful to filter out some of the network traffic to keep the capture small. With the NT/2000 Network Monitor, this is accomplished by selecting Filter... from the Capture menu and then double-clicking the SAP/ETYPE list entry. Click the Disable All button; then select the IP ETYPE protocol from the list and click Enable.
Navigate to the page that requests private user information. You may or may not receive a warning from the browser about a switch to a secure channel. The reason is that it is possible to receive the form from the server over an unencrypted channel and then enter the secure channel when the form is sent back to the server. If you do receive a warning from the browser, select OK to proceed.
Enter values for each form field that requests sensitive information, such as first/last names, telephone numbers, addresses, credit card numbers, and so on. Note the exact values entered. Do not submit the data yet; simply enter the data into the fields.
Switch to the network monitor tool and start capturing network packets.
Switch back to the browser and submit the form and wait for the response from the server. If you have not received the warning about switching to a secure channel yet, you should receive it now. If not, the channel very likely is not secure.
Stop the capture and view the data. You should see several entries with the source and destination matching the client's name or IP address and server's name or IP address. The protocol should be HTTPS or TCP. Double-click and examine each entry with the Src Other Addr having the name or IP address of the client computer you are using. The data in these packets should be unreadable; carefully examine them for the data you entered in the form. If the packet is readable, it is not encrypted, and the site's HTML and script files should be examined, since this may constitute a security flaw.
Network
Web systems use firewalls and routers to restrict access to servers from outside the site's network. This section verifies that only the necessary ports on externally visible servers can be accessed from outside the site's network.
Obtain a list of all the IP addresses, including externally visible routers and firewalls, in use by the servers that make up the site. Also include in this list the services, such as FTP and HTTP, running on each machine and whether the hosts and/or services should be visible to outside clients. The list may look something like this:
Other ports (not visible IP Visible from Address Type Ports outside) __________________________________________________________________ 192.168.10.1 firewall None None 192.168.10.2 web server 80 (HTTP), 443 (HTTPS) 21 (FTP) 192.168.10.3 db server 1433 (SQL Server) 21 (FTP)
From a client machine outside the firewall, attempt to connect to each machine by IP address, specifying one of the ports in the list. This can be accomplished by using the TELNET utility and specifying a port number.
telnet 192.168.10.2 80 telnet 192.168.10.2 21 telnet 192.168.10.3 21
The first example should result in a connectionpress Enter a few times after the connection succeeds to see some output from the HTTP serverwhereas the second and third examples should be refused by the firewall, as this site does not want the FTP service to be used by outside clients.
External testing of a server machine can be performed most accurately by using port-scanning software against the machine. Some Web sites will do an automated port scan, free of charge. Scanning in this way will identify the services running on the machine, the ports they are listening on, and, possibly, the version. Typically, port scanners can be configured to test only the common ports, such as FTP and HTTP. Test each IP address in the list, using the port scanner. The scanner should find only the ports listed in the Visible Ports column. All other ports the scanner finds should be investigated, as they indicate possible security holes into the network.