Plan of Attack - The Test Plan


Plan of Attack—The Test Plan

On projects in which there is a clear division of labor between a development team and test team, the test team should come up with a test plan for the project, and the development team should review it. If your project is made up entirely of developers with no test team, the development team should create a test plan in conjunction with the specifications and other design documents. If you’re in the midst of development and don’t have a test plan, drop everything—although you should finish this chapter first—and go through the exercise of creating a test plan. You might be inclined to reconsider all those great features you’ve planned, especially when you see how much effort will be required to adequately test them and how much risk a certain feature represents to your application. The plan should include the following:

  • Usage scenarios, which exhaustively cover all ways the application can be used, both in appropriate and (more importantly) inappropriate ways.

  • Summary of tests to be performed listed in priority order. (Stay tuned for a discussion on prioritizing tests later in this chapter.)

  • A schedule that lays out when the tests will be identified, how long to allow for testing, and how the test schedule correlates with the development schedule.

  • Target environments where testing will be performed, such as the various operating systems where the product is designed to run—for example, Microsoft Windows XP, Windows 2000, and Windows Me; target languages such as English and Japanese; and other notable configurations such as running the application on Windows XP logged on as a nonadministrative user.

A critical part of the test plan—this should be no surprise—will be to include tests for security. The plan should treat security as a distinct feature that requires specific tests. Emphasizing security in a test plan has these benefits:

  • A security-focused test plan helps you keep ahead of the attacker. The best time to lock down your application is before it gets into the hacker’s hands.

  • Factoring in security-focused tests gives you a more accurate estimate of how much time it will take to develop and test the application. These tests help to prevent any surprises down the road, such as a major security issue uncovered late in the development process.

  • A test plan (in conjunction with a threat analysis, as presented in Chapter 14) will help shine a big, bright spotlight on features that are quick and easy to implement but also prove to be a security nightmare, and in doing so, the test plan will give you a chance to rethink these features. For example, it might be an easy development task to create an extensibility model for your application—a model where third-party developers create add-in components to extend the functionality of your application. Permitting an arbitrary component to load and run in the context of your application requires you to anticipate everything the component might be able to do. It opens your application up to significant quality and security risks, and as a result, requires you to do extensive testing to ensure your application is safeguarded from any unacceptable action the component might try.

  • A security-focused test plan (as part of the threat-analysis phase) forces you to think about ways your application is susceptible to attack. It gives you a chance to brainstorm, organize your thoughts, and remember those thoughts in written form.

To create security-focused tests (as part of your test plan), you first need to identify ways an attacker might be able to compromise the application. In other words, you need to come up with various scenarios based on what an attacker might do.

Brainstorm—Generate Security-Related Scenarios

Forget about deadlines, money, or any other practical concerns for a moment, and let your imagination run wild to generate usage, or more accurately, “abusage” scenarios that could be used to compromise your application. When it comes to testing for security, you’ll want to think about all the devious things a person could do with your application.

Take the Attacker’s View

A technique that will help generate useful scenarios is to take an attacker’s view of your application. To an attacker, your application is not a nifty UI, it’s all the stuff behind your UI that gives her an exclusive, backstage pass to wreak havoc. One of the first things an attacker will do when she installs your application— namely a Windows Forms application or component—is to take an inventory of all the components installed by your application. She will look at where components are installed on the hard disk, the registry entries associated with those components, the public functions exposed by the components, and all data files installed by your application. As discussed in Chapter 6 and Chapter 7, all these things represent input to your application that can potentially be manipulated to do bad things.

The attacker will run tools to scan through your application’s binaries— EXEs and DLLs—looking for stored secrets such as passwords or pass-phrases contained within your built application (which shouldn’t be there if the application was designed securely).

In the case of Web applications, the attacker will run tools that crawl the Web site generated by your ASP.NET application and create a mirror image of that site. She will look through all the HTML files for comments that reveal information about your application or the server where it runs—information such as IP addresses or names of other servers that might be exposed. She will look at all input fields, including hidden fields, as a potential in-road for launching a SQL or cross-site scripting attack. She will also look at all embedded script, such as VBScript, and will disable the execution of it—which can be done by toggling a setting within her Internet browser—in an attempt to bypass your client-side input validation.

The attacker techniques described herein are commonly referred to as decomposing, profiling, or footprinting your application. This is equivalent to a burglar getting the blueprints to your house or office building to determine the easiest points of entry. Figure 9-1 lays out a sample blueprint of an application.

click to expand
Figure 9-1: An attacker’s blueprint of your application

Create a Blueprint of Your Application

You should take the same approach that a hacker would and create your own blueprint of the application to assess vulnerable points of attack. You can create your blueprint by reviewing your source code and the file list that you include in your setup application. Your blueprint should include:

  • All components—namely built .EXE and .DLLs—that make up your application

  • All Public functions exposed by the .DLLs in your application

  • All files that serve as input to your application

  • All files your application creates, including temporary files

  • Input fields on each form of your application

  • Clipboard data pasted in by the application

  • Environment variables your application depends on

  • Command-line arguments your application depends on

  • All registry entries your application either reads from or writes to

  • All third-party components your application calls

  • All external .EXEs your application spawns during execution

  • All databases your application connects to

  • For Web applications, all URL names your application uses

  • All network sockets your application opens

Note

Having access to your source code is a convenience you have when creating a blueprint for your application, but having this access really gives you little advantage over an attacker. Never count on your source code or any complex logic contained within your application to hide secrets. There are a number of tools and techniques to help an attacker reverse-engineer your code. Your safest bet is to assume the attacker has access to your code. For example, a Visual Basic .NET assembly—application EXE or component DLL—is quite easy to reverse-engineer by using a tool such as the Intermediate Language Disassembler (ILDasm.Exe). In fact, you can run ILDasm.Exe provided by the .NET Framework to open any compiled .NET application or component. ILDasm.EXE gives you a view of all the classes and .NET executable instructions (known as MSIL) that make up your application or component. Although ILDasm does not give you a view of the original source code (or comments), you can easily tell by the MSIL instructions what the application or component does. In addition, any stored secrets, such as passwords stored in constants, will be plainly visible when viewed using ILDasm. If C# is easier for you to read than MSIL, you can use tools such as Anakrino, which is available on the Web, to reverse-engineer a compiled .NET assembly to C#.

The items in this list generally serve as input to an attacker. As you learned in Chapter 6 and Chapter 7, attacks are usually launched by means of input. Think of ways that input—items such as those given in the previous list—can be manipulated or deprived to make your application either:

  • Crash, which could lead to a denial of service attack—or worse, a buffer overrun, which could allow the attacker to take over the machine or network where the application is running

  • Generate an error that reveals important details about your application

  • Elevate the privileges of the attacker by allowing him to obtain information or perform actions he should not be allowed to perform

Create Scenarios Based on Inroads for Attack

You should create scenarios focused on attacking (by various means, such as supplying malformed input) elements of your blueprint in an attempt to force any of the undesirable results listed previously. Following are examples of scenarios you should include in your test plan, which is based on your application’s blueprint and what a hacker would do with it:

  • For Web applications, attempt to launch a SQL-injection or cross-site scripting attack by entering SQL statements or VBScript in all input fields.

  • Modify the contents of an XML file that an application uses to read in its settings. For example, if the XML file contains a string to set the application title, you can try changing the title to an enormously long string, a number, or a set of extended characters (such as Japanese characters) in the hope of crashing the application or causing an exception.

  • Survey the Public functions exposed by a Visual Basic .NET class library object intended to run on a network server. For example, you might find that a server object contains Public functions such as the following, which were not meant to be Public:

    Public Function GetCreditCardNumber(ByVal custID As Integer) _
    As String
    Public Function GetCustomerName(ByVal custID As Integer) As String

    You could easily create your own Visual Basic .NET application to obtain private customer information by calling the exposed functions directly and passing arbitrary custID values to find customers and associated credit card numbers.

  • In the case of an ASP.NET application, use a nontraditional Web browser or raw HTML viewer to change the values of hidden fields, such as a hidden field containing a product price, in an attempt to fool the application into giving you a discount.

  • Try forcing an error by passing data to break SQL queries that would give you the name of the Microsoft SQL Server and database. You could use this information to attempt to connect to the SQL Server database and obtain the data directly from the database.

  • Place a .DLL with the same name as another .DLL that the application requires somewhere else on the computer, and try to spoof the application into loading it. Note that strong-named .NET assemblies, as presented in Chapter 10, help to prevent against this type of attack. You should consider strong-naming your assemblies for this reason.

  • In the case of a Web application, attempt to use a Web address (URL) that references an HTML page, an ASP.NET page, or a configuration file (such as a Web.Config file) that you should not be granted access to. A common form of this attack is an attempt to bypass a sequence of steps—such as the steps to locate, purchase, and ship a product— enforced by your Web application. For example, in the case of an online shopping application, an attacker will select a product to purchase and attempt to bypass the payment page by going directly to the shipping page in an effort to receive the product for free.

Get Focused—Prioritize Scenarios

Unless you want to dedicate the rest of your life and the lives of your team to preparing to ship your application, you must face the practical matter that you cannot do everything when it comes to testing. However, you must satisfy your goal of shipping a quality and secure application. The best way to strike a balance between shipping your application in a reasonable amount of time and performing enough testing to ensure quality and security is to keep yourself and your team focused on the most important scenarios—so you need to prioritize.

Not all test scenarios are created equal; some are more important than others. The importance of scenarios depends on your application. For example, if you’re creating a Web-based shopping application, testing to make sure all input fields are resilient against bad input is far more important than verifying that all input fields are displayed in the exact intended position on the screen. If the application crashes because of a character such as X being entered instead of a number, this far outweighs the problem of your text boxes being off-center by 1 pixel. However, if you’re creating a Windows Forms game application, which requires no free-form text input, testing that focuses on pixel- level accuracy is more important than verifying text input.

An effective way of prioritizing the important scenarios is to take a break from writing code and meet with the members of your team—including members from all disciplines, such as development, testing, documentation, and product support (especially since those guys are usually more fun to hang out with anyway). Having members of the documentation team involved helps to defend against proposals that call for documenting security problems as a cheap (and ineffective) substitute for making the necessary fix. Get their input to help you rank the scenarios by importance. An effective ranking strategy is to assign each scenario a priority number, such as 1 to 4 (where 1 is the highest priority). You could create application ship criteria that states the product cannot ship until the application performs as expected for priority 1 and 2 scenarios. For example, the prioritization of scenarios could determine ship criteria by using the scale shown in Table 9-1.

Table 9-1: Security Test-Scenario Priority Scale

Scenario Priority

Description

1

Priority 1 scenarios focus on threats having a high impact on application security. An example of a priority 1 scenario test is to make sure that in your data-entry application you cannot enter into any input fields SQL statements that manipulate the underlying database. The application cannot ship with any bugs relating to a priority 1 scenario. It is crucial that you create (and run) tests for all priority 1 scenarios.

2

Priority 2 scenarios deal with threats having a moderate impact on application security, or cases where the application doesn’t work as expected in the secure environment where it is meant to run. The scenario presented in Chapter 2 of not being able to run your application from a network share because of a code-access security violation is an example of a priority 2 scenario. Forcing the user to run the application from his local machine is an inconvenience to the user. The application should be fixed to run in all security zones in which it is intended to run. You should create tests for all priority 2 scenarios.

3

Priority 3 scenarios focus on issues that don’t seriously impede application security but would improve the aesthetics of the application from a security standpoint. For example, if the scenario involves a user attempting to log on to your application and the application shows a logon failed error—ostensibly because of an invalid user name and password—when in fact the server the application is on is down for maintenance, the application should instead show an error message warning the user the server is down for maintenance. This might annoy the user who retries logging on several times thinking he mistyped his password.

4

Priority 4 scenarios have no noticeable impact on security. You explicitly call out these scenarios as ones you will not test. For example, a scenario involving a security-related error message where the error message text contains trailing blanks (not visible to the user) does not rank high enough to test.

Note

You need to include all scenarios in the test plan, no matter how trivial they seem. When it comes to testing, it’s often just as important to see the scenarios you consciously decide not to test as it is to see those that you’ve decided are critical to test. You should continually review the test plan throughout the product-development cycle and question the priority ranking of all scenarios. If a new feature is added that makes a lower-priority scenario more critical or a serious bug related to a priority 4 scenario is found that causes you to elevate the scenario’s priority, you have a chance to redirect your testing effort midstream.

Prioritize Security-Related Scenarios Based on Threats

For the purpose of prioritizing security-related scenarios, evaluate how much of a threat each scenario is to your application. For example, if your application does not use a back-end database to store or retrieve information—and your application doesn’t call components that use a back-end database—SQL-injection attacks are most likely not a threat. However, if your Visual Basic .NET Web application takes user input and uses it as part of the resulting output, cross-site scripting attacks are a definite threat. You can use the STRIDE—an acronym representing general types of attacks such as spoofing, tampering with data, repudiation, information disclosure, denial of service, and elevation of privilege—threat-modeling process discussed in Chapter 15 to help rank security- related test scenarios.

Generate Tests

Once you’ve completed the process of brainstorming and prioritizing test scenarios, you need tests to evaluate how your application responds to the scenarios you have identified. When creating tests to match each scenario in your test plan, put practical considerations—such as how the tests will be implemented or the amount of time they will take—on hold. As in the case of generating scenarios, you want to freely brainstorm what tests will be needed. The important part of this exercise is to generate a complete list of tests, which you can then prioritize. For example, assume you have a priority 1 scenario listed in your test plan that states: “Ensure that only valid user names can be entered in the user name input field.” You’ll need to create an exhaustive list of the tests needed to validate the scenario. In this case, if a valid user name is defined as a name that is limited to 16 characters and can contain only alphabetic names, the following tests could be used to test the scenario:

  • Input an empty string.

  • Input a string longer than 16 characters.

  • Input a string containing numeric data and symbols.

  • Input a string containing embedded extended character codes such as a NULL Chr(0) , Tabs Chr(9), Carriage Return Chr(10), LineFeed Chr(12), and Backspace Chr(8).

  • Input strings in other languages, such as Japanese.

  • Input a valid alphabetic string containing mixed-case characters.

  • Input a string containing embedded SQL statements.

  • Input a string containing the name of an existing file.

  • Input a user name that contains valid characters but is not a user listed in the user database.

  • Enter invalid user names over and over again in a loop.

  • Run more than one instance of the application, and enter the same or different user names simultaneously.

  • Try all the preceding tests on various platforms, such as Windows Me and Windows XP.

  • Try the preceding tests in various contexts—for example, run many other kinds of applications, such as Microsoft Office applications, to force a low-memory condition and then try the previous scenarios.

As you can see, you can create quite a number of tests to validate a given scenario. The list could continue on ad infinitum. Stop at the point you feel comfortable that you have covered all the important cases.

Filter and Prioritize Tests for Each Scenario

To maintain focus and not get sucked into a testing black hole of having to implement a seemingly infinite number of tests, you should prioritize the tests identified for each scenario based on the following criteria:

  • Relevance to the scenario being tested Ask yourself whether the test will indicate a critical flaw or lack of functionality if it fails. For example, testing the background color of a text box to ensure it is white might not be relevant to the scenario of checking for a SQL- injection attack through that text box. On the other hand, if the text- box background color is meant to turn red to signify invalid input, a test verifying the background color is red—when the invalid input containing SQL statements is entered—might be relevant.

  • Applicability to multiple scenarios If a test associated with a scenario other than the one you are evaluating can also be used for the scenario you are evaluating, add a note to the test plan that the test will provide coverage for both scenarios.

  • Cost to perform or implement the test This is a practical consideration that you cannot overlook. If the test requires a great deal of effort to create or run, consider breaking the test down into smaller parts or finding other ways of creating the test that will give you the same level of validation.

In the process of creating a blueprint, brainstorming scenarios, and brainstorming the tests that go along with the scenarios, you might uncover flaws in the design of your application. If you decide to redesign to help reduce risk and make your application more secure, retrace the steps of creating the application blueprint and scenarios based on the updated design. Testing is a process, and the test plan is a living document. You should plan to iterate through your tests and test plan several times throughout the development cycle as changes are made to the product or other important test scenarios are discovered.




Security for Microsoft Visual Basic  .NET
Security for Microsoft Visual Basic .NET
ISBN: 735619190
EAN: N/A
Year: 2003
Pages: 168

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