Create secure Java applications productively, Part 2

Maximize security in your Java Web application with Rational AppScan

This is the second in a two-part tutorial series on creating secure Java®-based Web applications using Rational® Application Developer, Data Studio and Rational AppScan. In Part 1 you developed a Java Web application with Rational Application Developer, and then deployed the application on WebSphere Application Server with Java Server Pages (JSP). This tutorial shows you how to scan the Wealth application created in Part 1 using Rational AppScan to discover and fix all known Web security vulnerabilities. It also shows how to re-scan your application and generate reports.

David Whitelegg (dw@itsecurityexpert.co.uk), Freelance writer and developer, Freelance Writer

Author photoDavid Whitelegg is a UK based Certified Information Security Systems Professional (CISSP) and Cisco Certified Security Professional (CCSP), and has been working within Information Security for almost 15 years. David has been actively involved in securing high profile Web Applications, including high volume e-commerce and payment solutions, ensuring their full compliance with the Payment Card Industry Data Security Standard (PCI DSS) Level 1. David is also an active Information Security blogger and runs the ITSecurityExpert.co.uk Web site.



04 May 2008

Also available in Vietnamese

Before you start

This tutorial is recommended to Web application developers, Web application testers, quality assurance teams, information security professionals and anyone else wishing to ensure their Web applications are free from all known Web security vulnerabilities. This tutorial will show how to achieve this goal using IBM Rational AppScan.

About this series

This two-part series aims to broaden your Web application development skills through the use of Rational Application Developer, Data Studio and Rational AppScan.

  • Part 1 uses the IDE capabilities of Rational Application Developer and the pureQuery features of Data Studio to efficiently create a Java-based wealth management Web application.
  • In Part 2 you are going to take advantage of the many Rational AppScan features available to harden, or make secure, the Java application by discovering vulnerabilities and fixing them so that you can be confident about deploying your Web application.

About this tutorial

This tutorial will show you how to install, configure and use Rational AppScan to scan the Wealth Java Web application created in Part 1 (see Resources). You will use Rational AppScan scans to ensure your Web application is free from Web security vulnerabilities. Along the way you will learn how to achieve the most out of Rational AppScan, including:

  • Deployment strategy
  • Customizing a scan template
  • Performing a scan
  • Interpreting and learning from scan results
  • Producing scan reports
  • Using Rational AppScan extensions

This tutorial starts with an overview of Web application security. The overview explains the importance of using Rational AppScan, to ensure the elimination of Web security vulnerabilities within the application development process of a public facing Web application. There is also an overview of Rational AppScan deployment and licensing considerations to help you get the most out of using Rational AppScan.

System requirements

To complete the steps in this tutorial you need:

  • A copy of IBM Rational AppScan Standard Edition. A full or temporary Rational AppScan license. The downloaded trial version of Rational AppScan only allows the scan of a default Web site. It may be possible to obtain a temporary short term Rational AppScan license from your IBM Rational Sales contact.
  • A Laptop with network connectivity to the Tutorial 1 workstation/server.

Rational AppScan and Web application security overview

In this section we'll take a look at the state of Web application security on the Internet in general, and the role that Rational AppScan plays in making Web applications more secure.

Web application security overview

With the explosion of Web applications and Web 2.0 content on the Internet, the demand for increased Web application functionality has resulted in ever larger and more complex Web applications, particularly within e-commerce Web sites and social networking type Web sites. In parallel to this trend, there has been another more sinister raising trend, the exploitation of code vulnerabilities within Web applications by hackers and criminals. This has lead to a very real and dedicated attack vector discipline, Web Application Hacking.

The evidence shows an increasing number of attacks and actual data breaches occurring at the Web application layer, as opposed to the traditional attacks at the network layer. The network infrastructure of any public facing Web solution is still as important as ever, but we have now reached a stage where network level infrastructure can be made relatively bullet proof. Therefore hackers are now focusing their efforts on more affluent areas of security weakness, which they are finding within the Web application code. Hackers are specifically targeting the high value data behind and controlled by the Web application, data which often has significant real value.

Consider the perimeter firewall, which provides protection against network layer attacks practically straight out of the box, yet a network firewall offers almost no protection against Web application level vulnerabilities. For example, the firewall may only allow https network traffic to a Web server, but the firewall does not inspect nor care about the actual HTML Web application content passing through to the Web server, which is what can be exploited. The stakes are high, as even the slightest weakness within Web application code, such as within a simple field input validation, can cause business critical vulnerabilities, leading to financial losses and severe damage to customer trust in the business brand.

Typical results of hackers exploiting Web application code vulnerabilities can allow an attacker to completely bypass the Web login system, steal user Web sessions, cause a complete Web application outage, and directly interrogate, access, and manipulate the data on the backend database.

There is a real risk of Web application vulnerabilities being exploited, especially if the application data has high value associated with it, such as payment card information, even sensitive personal data has sellable value. There is also an increase in the number of legal, regulatory and industry standards imposing large fines as a result of a data breach. Keep in mind that once a Web application is made available on the Internet, anyone in the world is able to access the application, including those pesky hackers. These hackers will have an unlimited amount of time to find and exploit any vulnerability or weakness within the Web application code. Given how the Web application created for this tutorial series has a financial theme and sensitive information worth protecting, namely a personal real estate portfolio, the importance of releasing the Wealth Web Application without vulnerabilities is clear.

Given this background and the ever increasing importance business is placing on data security, developing Web applications clean of security vulnerabilities is very much a key requirement and should be a fundamental objective of any public Web application. In this tutorial you'll use IBM's Rational AppScan to ensure the Wealth Java Web application created in Part 1 of this series, is free from all known Web application vulnerabilities, ensuring the Web application is secure enough to be placed on the Internet.

Rational AppScan overview

IBM's Rational AppScan is the market leading security suite for Web application vulnerability testing. Using Rational AppScan can help you ensure that any developed Web application is secure enough to be placed on the Internet. Rational AppScan is a powerful and customizable scanning tool, and can not only be used within the development and testing process, but is often used by security auditors and compliance officers for penetration testing, and even quality assurance teams and business management.

Rational AppScan's primary function is to scan and test for Web application vulnerabilities, and it is able to carry out thousands of vulnerability security tests such as SQL Injection, Cross-Site Scripting (XSS) and Buffer Overflow. The security tests within Rational AppScan are also regularly updated; new tests and test updates are added into the Rational AppScan test portfolio as new Web application vulnerabilities are discovered.

Rational AppScan reports and licensing

Rational AppScan has comprehensive reporting functionality built in, allowing scan results to be reproduced into a formatted report structure within an Adobe PDF file. These reports are all fully customizable within Rational AppScan. See Downloads to view all of the reports that were generated throughout the process followed in this tutorial. Rational AppScan comes with a multitude of default defined report formats that fit the vast majority of international legal standards, and industry specific regulatory requirements. These include Payment Card Industry Data Security Standard (PCI DSS), SOX, HIPPA, the OWASP Top Ten, WASC Threat Classification, ISO 17799/27001 and the SANS Top Ten to name a few.

Before purchasing Rational AppScan, it is worth taking some time to consider how you intend to deploy and use Rational AppScan within your environment. As part of this should have a good understanding of the Rational AppScan licensing system, and the two typical methods of Rational AppScan deployment. The Rational AppScan license works on a "per installed machine" basis as opposed to a "per user basis"; therefore, AppScan is installed and fixed to specific system but this system (and AppScan) can be used by many users. The application license ties the Rational AppScan application to the host system's MAC address (network hardware) and the hard disk serial number. So before deploying Rational AppScan take some time to consider and decide the best installation strategy.

The first typical option is to install Rational AppScan on a central "Test" server, which allows good management and control of the Application usage. This type of strategy is recommended if you intend to use Rational AppScan within a single testing environment.

Laptop installation

Installing Rational AppScan on a dedicated laptop provides greater flexibility than a server installation. If you are planning to use Rational AppScan within multiple test environments on different networks, this is the recommended strategy to adopt.

Before finalizing your deployment strategy, you must consider whether the intended usage of Rational AppScan is within the spirit of the license agreement. For instance, buying a single license of Rational AppScan for testing Web application development within a specific site would be deemed acceptable usage.

Note: The Rational AppScan licensing system is changed to match the standard IBM Rational licensing structure by the end of 2008.

In this tutorial you will install and use Rational AppScan on a laptop that has network connectivity to the system hosting the Wealth Java Web Application created in Part 1. However, Rational AppScan can be installed on the same system you used in Part 1, and run scans locally on that system.


Install Rational AppScan

In this section you'll install Rational AppScan application on a laptop. Rational AppScan can be installed and operated from just about any modern Microsoft® Windows® based platform that has Java Runtime installed.

Installation steps

Installing the Rational AppScan application on a laptop is a relatively straightforward process.

  1. Double-click the installation file to launch the InstallShield wizard, as shown in Figure 1.
    Figure 1. Launching the InstallShield wizard
    Launching the InstallShield wizard
    If the installation detects Microsoft .NET Framework 2.0 or higher is not installed, which is a requirement, the installation process will install Microsoft .NET Framework 3.0 prior to moving on with the installation process.
  2. Read and click I accept the terms in the license agreement and click Next.
    Figure 2. The licensing agreement
    The licensing agreement
  3. Accept the default installation folder.
    Figure 3. Choosing an installation folder
    Choosing an installation folder

The Rational AppScan application is now installed. However, before using Rational AppScan and running scans, you need to do a bit of house keeping.

Rational AppScan Software update overview

When Rational AppScan launches, it automatically interrogates the IBM Servers to check whether Rational AppScan is up-to-date. Should an update be available, which is usually the case when running Rational AppScan for the first time, Rational AppScan proceeds to automatically download and apply it.

Rational AppScan updates are similar to those found in Anti-Virus products, in that new Web application vulnerabilities are regularly discovered. Therefore the Rational AppScan support team introduces new tests and changes to the existing library of tests within Rational AppScan, by the way of software updates. This process ensures Rational AppScan is able to test Web applications against the very latest security vulnerabilities.

For the update process to work, your Rational AppScan workstation or server must have Internet connectivity. This update process is essential for post installation and can be done on a periodic basis thereafter. Updates can also be downloaded manually from the customer support portal for developers working in locked down environments where outside connectivity is not allowed.

Rational AppScan update

Now it's time to update Rational AppScan.

  1. Launch Rational AppScan to see Figure 4.
    Figure 4. Rational AppScan connects to IBM Servers to check if updates are required
    Rational AppScan connects to IBM Servers to check if updates are required
  2. Click Install to begin the automatic download and install process (see Figure 5).
    Figure 5. Updates are automatically installed
    Updates are automatically installed
  3. Once the install process is completed, click View Update Log from Figure 5, which show the actual update details. Now that the update has completed, it is time to license Rational AppScan.

Rational AppScan licensing overview

Let's walk through the steps to license Rational AppScan.

  1. Re-launch Rational AppScan and click on the Security Issues tab in the left pane. As part of your purchase of AppScan (or trial request), you are provided with an email containing a License Serial Key (LSK) and instructions where to download the AppScan license file. Click Help > License (see Figure 6).
    Figure 6. Select the License options
    Select the License options
  2. On the License options window shown in Figure 7, click Obtain License Online.
    Figure 7. Click Obtain License Online
    select Obtain License Online
  3. The AppScan licensing Web site opens, https://licensing.watchfire.com (see Figure 8). Complete the form, filling in all the red fields.
    Figure 8. AppScan licensing Web site form
    AppScan licensing Web site form
  4. For the next part of the licensing form, you need to know the MAC address and hard disk volume serial number of the system where AppScan is installed. The online generated license file locks the AppScan application installation and usage to a specific system.
  5. To find these details, at a DOS prompt (run cmd in Windows), type ipconfig/all, which displays the MAC address of your network card. Then execute vol, which displays your hard disk drive volume serial number. Fill in the system details in the bottom portion of the AppScan licensing Web site form shown in Figure 9.
    Figure 9. System details portion of the AppScan licensing Web site form
    System details portion of the AppScan licensing Web site form
  6. And finally, agree to the License Agreement by clicking Continue at the bottom of the screen (see Figure 10).
    Figure 10. Agree to the License Agreement
    Agree to the License Agreement
  7. Once you have your license file, import it into AppScan. Return to Figure 6 and again select the License option from the Help drop-down menu to launch the License options screen from Figure 7. This time click on Load License File.
  8. Navigate to the downloaded license file in the AppScan License directory and click Open (see Figure 11).
    Figure 11. The downloaded license file in the AppScan License directory
    The downloaded license file in the AppScan License directory

Congratulations! Rational Appscan is now ready to use.


Rational AppScan in action

Now that you have installed Rational AppScan, it's time to get your application ready for testing, and then run a scan on the Wealth application.

Prepare the Web application for testing

In this tutorial you have installed Rational AppScan onto a different system to the workstation where you installed Rational Application Developer, Data Studio, and then developed the Wealth Java Web Application in Part 1 (see Resources). If you are short on hardware, Rational AppScan can be installed on the same system as Rational Application Developer and you are able to scan the Wealth Web application locally by entering http://localhost:9080/wealth/ as the scan URL.

Obtain permission before scanning

Before using AppScan to scan a Web application, ensure you have obtained permission to scan from the Web site owner. This is especially important when scanning Web applications outside your test environments. Scanning third party Web sites with AppScan without permission can have serious legal consequences.

We need to ensure your Wealth Java application is online and operating correctly on your Rational Application Developer platform. Within Rational Application Developer, go to Open Web Perspective > Web, then select the Servers tab (see Figure 12), and see if the Web server has started. If not, right-click and select Start. Depending on the power of your hardware, it may take a moment or two before WebSphere and your Wealth Web application is up.

Figure 12. Launch WebSphere within Rational Application Developer
Launch WebSphere within Rational Application Developer

Next you need to test that you can access your Wealth Web Application from your Rational AppScan Laptop. First ensure the laptop in on the same network by opening up your Web browser and typing in http://<ip address of RAD>:9080/Wealth/login.jsp.

In your case the Rational Application Developer workstation has an IP address of 192.168.0.4, so your URL is http://192.168.0.4:9080/Wealth/login.jsp.

Once opened, test the Wealth Web application is working properly, by logging in and clicking a few links to ensure everything is responding as it should.

Now you know the Wealth Web application is working and can be seen by the Rational AppScan device, so you are ready to conduct your first scan.

Before you scan, however, it's worth understanding Rational AppScan scan templates.

Scan templates overview

Rational AppScan is a powerful vulnerability scanning tool and is capable of running of thousands of vulnerability tests against a multitude of vulnerability areas. Some of these test areas, such as testing the Web server and Web services, aren't relevant to ensuring your application code is clear of vulnerabilities. Therefore you need to tailor your vulnerability scan, and cut out the areas you aren't interested in scanning.

Rational AppScan uses scan templates, which are saved scan configurations used to perform specific types of vulnerability scans. Scan templates allow us to apply and save specific customization to your intended scans. Rational AppScan comes with several predefined scan templates, all of which can be used on the fly. However, there are many advantages in customizing your own specific scan template, such as ensuring the exact same scan is used in rescans and sharing of the scan template with other developers and teams.

Scan the application

Use and save your own customized scan template, in case there are problems to be fixed within code and a rescan is required.

  1. From the Rational AppScan Welcome Window, select Create New Scan or from within Rational AppScan, Click the File drop down menu and select New (see Figure 13).
    Figure 13. Rational AppScan Welcome Window
    Rational AppScan Welcome Window
  2. Next ensure the Launch Scan Configuration wizard is checked and click Default from the Predefined Templates (see Figure 14).
    Figure 14. Launch Scan Configuration wizard is checked
    Launch Scan Configuration wizard is checked
  3. We are then asked the type of scan you want to perform, a Web Application Scan or Web Service Scan. A Web Service Scan covers infrastructure, such as the configuration of the Web server. This type of scan isn't relevant within your development process, so select Web Application Scan, which will scan specifically for vulnerabilities within the Web application (see Figure 15).
    Figure 15. Selecting Web Application Scan
    Selecting Web Application Scan
  4. You are presented with a screen asking for the scan Starting URL (see Figure 16)
    Figure 16. Screen asking for the scan Starting URL
    Screen asking for the scan Starting URL
  5. At this point you have option of selecting Full Scan Configuration, which allows detailed customization of the scan, but in this tutorial you'll stick to the Scan Configuration wizard, as your Web application is fairly small and uncomplicated. Enter the URL of your Web application, http://192.168.0.4:9080/Wealth/.
    Do not enter login.jsp or welcome.jsp, just the URL root, as Rational AppScan will discover and analyse all aspects of the Web application from that point.
    The case-sensitive path is particularly important to enable if your Web server is operating on case-sensitive operating system platform such as Linux or Unix.
    If you need to configure proxy settings to access the target Web application server, there is an option at the bottom of this screen to do that. Instead of using IP addresses, your target Web application could be a full Internet address or internal domain name. If there appears to be proxy issues, you should go into this screen and modify the settings. Please note AppScan does not support proxy exceptions. If localhost is set as an exception in Internet Explorer, you should set it to Don't Use Proxy in AppScan.
  6. Click Next to reach the Login management screen (see Figure 17).
    Figure 17. Login management
    Login management

Login management

Login management is a key part of the scan. You want Rational AppScan to test everything a user can do and see; therefore Rational AppScan needs to be able to authenticate (login) into your Wealth Web application as a regular user. You have several options open to you, one is to be prompted, which means every time Rational AppScan finds a login page, it will stop the scan and display that page on your screen. You then login as if you were a user, Rational AppScan records those login details and then uses them to log into the Web application and continue on with the testing.

To make your scan operate slicker and avoid any scan halts, go for the automatic options. Provide Rational AppScan with the login details before the start of the scan and have them saved within your scan template for future scans.

  1. Select the Automatic radio button in Figure 17, and then enter a username of tyler and a password of tyler (or whatever username and password you used as part of the development of the Wealth Java App in Part 1.
  2. You have the option of configuring "In-Session" detections, should Rational AppScan have issues managing user Web sessions and finding the logout page etc. For this tutorial, this won't be an issue.
  3. Click Next.
  4. A Rational AppScan "Policy" refers to specific groups of Rational AppScan tests.
    You need to just run Web application tests within your scan, so you need to narrow the number of tests performed to just Web application tests. Select the Application-Only Policy and click Next (see Figure 18).
    Figure 18. Selecting the Test Policy
    Selecting the Test Policy
  5. Finally, Rational AppScan is asking if you are ready to start the scan; you are, so click the Start a full automatic scan radio button and then click Next (see Figure 19).
    Figure 19. Gentleman Start your Engines!
    Gentleman Start your Engines
  6. Your Scan needs to be saved, so select Yes (see Figure 20).
    Figure 20. One last thing before starting the scan
    one last thing
  7. Enter a name of WealthScan (see Figure 21) and click Save.
    Figure 21. Enter scan name
    enter scan name

The scan starts.

Scan performance

The time it takes for the scan to complete depends on the complexity and size of the target Web application, bandwidth, processing speed, and the number of tests directed within the scan. Your application is relativity small so your scan should only take a few minutes to complete.

As the scan is performed, first Rational AppScan determines to the scope of the Web application, and lists Web application files and URLs to be scanned. Next Rational AppScan engages each part of the Web application with an array of Web application vulnerabilities scans, as selecting within the policy.

As the Scan is running, select View > Scan Log. You can see the specific details of the scan. In Figure 22, you can see the automatic user logons working (highlighted in blue), various scan details and analysis being performed, and tests fail messages returned highlighted in red.

Figure 22. Keeping a closer eye on what's going on
Keeping a closer eye on what's going on

In the bottom-right area of Rational AppScan you find the Issue Severity Gauge, which updates in real time with scan. Under this is the number of discovered and visited URLs within the Web app and the outstanding and completed tests. Figure 23 shows the stats at the end of your first scan.

Figure 23. Issue Severity Gauge
Issue Severity Gauge

Scan completion

The results are in, and it's not good news for your Wealth Java Web application. Rational AppScan has returned a total of 18 issues, which Rational AppScan has severity classified. So you have 8 that are High Risk Vulnerabilities discovered, 3 Medium Risk, 2 Low Risk and 3 Information related issues, which all require investigation and resolving.

Fear not, Rational AppScan is far from finished in helping secure your application. If you have ever experienced a third-party Web application penetration test, quite often the subsequent report just tells you there is a problem without explaining what the vulnerability clearly is, how to fix it, or any details on the actual test they used to discover it. Well, Rational AppScan does all these things for you.

Rational AppScan shows each of the issues it has discovered by the ".jsp" file where it was found, then type of issue by severity as in Figure 24.

Figure 24. Scan results
scan results

It's time to understand what these detected issues are, but don't worry, this is where Rational AppScan really comes into its own.

Click on the first issue, which happens to be a Cross-Site Script (XSS) vulnerability. Details are populated on the bottom-right window pane (see Figure 25). It's a good idea at this point to expand this window pane size.

Figure 25. Understanding a discovered security issue
Understanding a discovered security issue

Advisory

Within the Advisory section, Rational AppScan explains in full detail the type of security vulnerability it has found. In this case it is an XSS vulnerability. At the top is a brief overview of vulnerability and its severity, followed by a detailed text description in the bottom left of the window. On the right side there is a video explanation of the issue, which is a fantastic learning aid.

Back to the left side of the Advisory. If you need further information, there is a link to a specific page on the WASC (Web Application Security Consortium) site, providing even further information and advice (see Resources for a link). WASC is an organization devoted to Web application security.

If you don't know what an XSS vulnerability is, go ahead and read what Rational AppScan has to say and watch the video.


Fixing the vulnerabilities

Now that you've scanned your application and discovered the vulnerabilities, it's time to fix the problems using Rational AppScan.

Fix recommendation

So now you are well versed in understanding what an XSS issue is and why it is a problem that must be eliminated. It's time to learn how to fix it. Click the Fix Recommendation tab shown in Figure 26.

Figure 26. The fix
the fix

Rational AppScan explains in a developer friendly way how to fix the issue within the Web app.

Rational AppScan even provides example lines of Java code that can prevent the problem (see Figure 27). Rational AppScan really makes it almost child's play to fix the discovered issue, even for most "green" of developers.

Figure 27. Fix code courtesy of Rational AppScan
Fix code courtesy of Rational AppScan

Request/Response

The "Request/Response" provides information about the actual test that Rational AppScan carried out against your Web application. Rational AppScan works by first sending a normal request, and it then sends the same request again, but it is modified with the vulnerability test. If you look at Figure 28, which shows the "Test" open, the text highlighted in red is the actual test (known as a variant) which Rational AppScan fired at your Web application. This allows you to see the specific detail of the test. Note how the code window shows the test and the red shows what was modified, allowing you to select the AB highlighter button to zoom to the part of the response where the signature was found that verified the result. You can use this information to replay the attack manually or craft your own specific tests of the same type and then save it within Rational AppScan. You can even show results of the test within a Web browser.

Figure 28. Request/Response
request/response

A variant is the slight change of the original test request that Rational AppScan sent to your Web application server.

If you doubt the validity of the test results flagged up by Rational AppScan, you are able to report a false position to the IBM Rational AppScan support team. This process involves Rational AppScan e-mailing the details of the test to IBM for analysis, but don't worry these details are sent encrypted by default.

Fix specific issues

Rational AppScan tell you there is a Cross-Site Scripting (XSS) vulnerability within http://192.168.0.4:9080/wealth/realestate.jsp, which means that the address field entry can be used to inject scripts (<scripts>) and therefore allow a cross-site script attack to take place. This type of attack can lead to an attacker stealing or manipulating an authenticated user's Web session.

As you look at your overall Rational AppScan results, it is clear it has similar XSS problems within city, create, state, value, zip, as these have all been flagged as being vulnerable to "Stored Cross-Site-Scripting".

Check the Fix Recommendation tab. Rational AppScan tells how to fix these issues by filtering out non valid characters, such as "&" ";" "<" "@", and even provides some Java code to do the job.

So you need to add field input validation checks within your Java code, and you'll use the code in Listing 1 to do that, which states to only accept alpha numeric characters.

Listing 1. Field input validation checks
    if(request.getMethod().equals("POST")){
        Pattern input = Pattern.compile("[a-zA-Z0-9]*");
         Matcher m = input.matcher(userid);
         boolean match = m.matches();

Looking at your second vulnerability on the list, Rational AppScan is telling you http://192.168.0.4:9080/wealth/ and http://192.168.0.4:9080/wealth/login.jsp are vulnerable to Session Fixation. Rational AppScan tells you that a user's Web session could be stolen or manipulated because your Web application is allowing session IDs to be created by your user's Web browser. Rational AppScan explains the fix: You need to ensure your Web Application does not accept sessions created by the user's browsers. Therefore you need to invalidate the users current session and generate a new random session ID after the user has been authenticated. To do this you need to add the code in Listing 2 to login.jsp, which invalidates the existing Web session and allows your Web application to create a new one.

Listing 2. Invalidating the existing Web session
         session.invalidate();
        session = request.getSession(true);
        session.setAttribute("userid", userid);

And on the logout.jsp, you need to kill the session: session.setAttribute("userid", null);.

The third issue on your list is another classic Web application security flaw: SQL Injection. SQL Injection allows an attacker to manipulate the backend database by allowing SQL commands to be executed within your Web application entry fields. Rational AppScan tell you the zip field is affected. Again, as with XSS, Rational AppScan explains field validation in a way to fix this vulnerability.

That fixes the high level issues. Next you see there are several medium level issues referring to Database Error Pattern Found.

Database Error Pattern means a test returned back a database error. A likely cause for this error is lack of user input sanitization, which can mean your application could be vulnerable to SQL Injection or XSS. Check the recommendation. You need to ensure you fully sanitize user input in your code, which should prevent this database error and possible vulnerability in the next scan.

Next there are two low level issues on your list, which are both Session Identifier Not Updated. Rational AppScan is telling you it is possible to steal or manipulate user sessions or cookies. Again, like with the Session Fixation issue, you need your Web application to create the user's session ID.

Looking at the bottom of your list of issues, you see three information level issues, which mean these issues aren't actual Web application vulnerabilities as such, but could be a possible issue and threat, in that readable comments have been found by Rational AppScan within the .jsp files. Rational AppScan is warning you that these comments might contain sensitive information you might not want the public or a hacker to read. The classic I have come across in real life when testing Web applications in the field, is developers leaving back door administrator usernames and passwords in comments field, to help assist testers. So you need to check out these comments or better still remove all comments from your code. Remember your code is public facing, so security best practices is to remove comments from the code, thus eliminating the possibility of disclosing any information about the Web application to a hacker.

By clicking the Remediation tasks on the left side, you are able to filter on just the list of required fixes (see Figure 29).

Figure 29. Remediation tasks
Remediation tasks

Finally it is worth checking Application Data, which tells you everything that Rational AppScan has picked up about your Web application, so you will see the directory tree layout and all the WebPages Rational AppScan discovered along the way. It should always double-check to ensure Rational AppScan has correctly discovered all of the Web Application files.

Before you make the changes to your code, look at the Rational AppScan reports briefly, as the natural process is to produce a security report, which is then supplied to the developer(s), who is tasked to make the fixes.

Rational AppScan security report

You have a list of issues that you need your developer to fix. You need to provide them with your Rational AppScan results and recommended fixes in a nice report format.

  1. With your scan still open in Rational AppScan, select Tools > Report (see Figure 30).
    Figure 30. Start the reports wizard
    Start the Reports wizard
  2. Within reporting you find plenty of preloaded Rational AppScan reports filtered under several topic headings. Because you want to produce an internal report to help developers resolve the issues, stick with the default report. Type Security Report.
  3. Select Developer from the choice of templates.
  4. Complete the report options as in Figure 31. Note the Web application was coded in Java not .NET or PHP, so deselect those two from the report, as you don't need to know how to fix the issues in those languages.
    Figure 31. Create a report
    Create a report
  5. Click Layout (see Figure 32), that allows you to customize the look of the report should you want to add a company logo and anything specific in the report page tiles. One tip for the real world is to add Company Confidential within the page footer. You really should be regarding these reports as highly sensitive information within your organization.
    Figure 32. Reporting with bells and whistles
    Reporting with bells and whistles
  6. Select Save and name your report (see Figure 33)
    Figure 33. Saving and naming your report
    saving and naming your repot

Your report is saved as a PDF file.

So your report is now ready to be provided to the developer, which in the case of this tutorial is you! So you need to run through the report findings and correct your Java Web application code.

Fix the Java code

By now you should have a good understanding of what needs fixing and how, so it's time to fix the security vulnerabilities within the code.

Open Rational Application Developer and make the following changes highlighted in bold (see Listing 3), or you can just cut and paste the entire section to save time.

Listing 3. Updated login.jsp with initial new Session on Web Server and Validation Checks
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<jsp:useBean id="users" class="com.ibm.ds.users.UsersDataImpl" scope="page" /> 
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@page import="com.ibm.ds.users.Users" %>
<%@page import="pureQuery.example.*" %>
<%@page import="com.ibm.pdq.runtime.*" %>
<%@page import="java.util.regex.*" %>
<html>
<head>
<title>login</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="GENERATOR" content="Rational Application Developer">
</head>
<body>
<h1>Login</h1>

<%
    String userid = request.getParameter("userid");
    String password = request.getParameter("password");
    
    session.invalidate();
    session = request.getSession(true);
    session.setAttribute("userid", userid);
 
    if(request.getMethod().equals("POST")){
    
        boolean matchu = false;
        boolean matchp = false;
        
        if(userid != null && !userid.equals("") &&password != null && !password.equals("")){
            Pattern input = Pattern.compile("[a-zA-Z0-9]*");
             Matcher m = input.matcher(userid);
             matchu = m.matches();
             
            input = Pattern.compile("[a-zA-Z0-9]*");
             m = input.matcher(password);
             matchp = m.matches();
        }

        if(matchu && matchp && (userid != null && 
		                                   !userid.equals(""))  &&
           (password != null && !password.equals(""))  &&
            userid.length() <= 50 && password.length() <= 50 && 
            request.getParameter("login") != null &&request.getParameter("login").equals("Login")){
            
            Data d = SampleUtil.getData("jdbc:db2://localhost:50000/WEALTH", 
		    "<enter_username_here>", "<enter_password_here>");
            users.setData(d);
            Users u = users.getUsers(userid);
            
            if(u != null && u.getPassword().equals(password)){
                session.setAttribute("userid", userid);
                response.sendRedirect("welcome.jsp");
            }
            else{
                out.println("Error logging in.<br/><br/>");
            }
        }
        else
            out.println("Error logging in.<br/><br/>");
    }
%> 
<form method="post">
    userid: <input name="userid"/><br/>
    Password: <input name="password" type="password"/><br/>
    <input type="submit" name="login" value="Login"/>
</form>
</body>
</html>

Note that the HTML comments were converted into JSP comments. Here you also implement the previously discussed changes, including input validation, where if the username or password are not alphanumeric, they are rejected and never make it to SQL or Java String comparisons. Note you're also making sure a POST request was issued, and that the Login button named "login" is correctly valued as "login" in the POST request.

The fix in Listing 4 ensures that any user is logged out of your Wealth application when they should be.

Listing 4. Updated logout.jsp. Tear down the session
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<html>
<head>
<title>logout</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="GENERATOR" content="Rational Application Developer">
</head>
<body>
<%
    String userid = (String)session.getAttribute("userid");
    if(userid != null){
        session.setAttribute("userid", null);
        session.invalidate();
        response.sendRedirect("login.jsp");
    }
%>
</body>
</html>

Other than changing the comment from HTML to JSP, the session is properly teared down so that a user really is logged out completely.

In Listing 5 you make changes to the code to prevent SQL injection attacks from occurring in your application.

Listing 5. Updated realestate.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<jsp:useBean id="realestate" class="com.ibm.ds.realestate.RealestateDataImpl" 
                                                              scope="page" /> 
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@page import="java.util.Iterator" %>
<%@page import="com.ibm.ds.realestate.Realestate" %>
<%@page import="pureQuery.example.*" %>
<%@page import="com.ibm.pdq.runtime.*" %>
<%@page import="java.math.BigDecimal" %>
<%@page import="java.util.regex.*" %>
<html>
<head>
<title>realestate</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="GENERATOR" content="Rational Application Developer">
</head>
<body>
<h1>Your realestate holdings</h1>
<table
 border="1"><tr><th>Address</th><th>City</th>
 <th>Zip</th><th>State</th><th>Value</th></tr>
<%
    String userid = (String)session.getAttribute("userid");
    
    if(userid == null){
        response.sendRedirect("login.jsp");
    }
    Data d = SampleUtil.getData("jdbc:db2://localhost:50000/WEALTH", 
	"<enter_username_here>", "<enter_password_here>");
    realestate.setData(d);
    Iterator i = realestate.getRealestates(userid);
    
    Realestate curr = null;
    
    double total = 0;
    while(i.hasNext()){
        curr = (Realestate) i.next();
        out.println("<tr><td>"+curr.getAddress()+"</td><td>"
		                                      +curr.getCity()+
                    "</td><td>"+curr.getZip()+"</td><td>"
					                +curr.getState()+
                    "</td><td>$"+curr.getPropertyValue()
					                +"</td></tr>");
        total += curr.getPropertyValue().doubleValue();
    }
    if(total > 0)
        total = Math.round(total*100.0)/100.0;
%>
</table>
<h3>Total value: $<% out.print(total); %></h3>
<br><h4>Enter new real estate:</h4> 
<%
    if(request.getMethod().equals("POST") && request.getParameter("create" )
	                                       != null){
        String address = request.getParameter("address");
        String city = request.getParameter("city");
        String state = request.getParameter("state");
        String zip = request.getParameter("zip");
        String value = request.getParameter("value");
        
        if(!address.equals("") && !city.equals("")  &&
           !zip.equals("") && !state.equals("") && !value.equals("")){
            Pattern input = Pattern.compile("[a-zA-Z0-9\\p{Blank}]*");
             Matcher m = input.matcher(address);
             boolean matcha = m.matches();
             
            input = Pattern.compile("[a-zA-Z\\p{Blank}]*");
             m = input.matcher(city);
             boolean matchc = m.matches();
             
            input = Pattern.compile("[a-zA-Z][a-zA-Z]");
             m = input.matcher(state);
             boolean matchs = m.matches();
             
            input = Pattern.compile("[0-9][0-9][0-9][0-9][0-9]");
             m = input.matcher(zip);
             boolean matchz = m.matches();
            
            if(matcha && matchc && matchs && matchz){
                try{
                    realestate.createRealestate(new BigDecimal(value), address, city, 
					                     zip, state, userid);
                    response.sendRedirect("realestate.jsp");
                }catch(Exception e){ out.println("Error adding new real estate.
				                                      <br/><br/>"); }
            }
            else
                out.println("Error adding new real estate.<br/><br/>");
        }
        else
            out.println("Error adding new real estate.<br/><br/>");
    }
 %>
<form method="post">
    Address: <input name="address"/><br/>
    City: <input name="city"/><br/>
    Zip: <input name="zip"/><br/>
    State: <input name="state"/><br/>
    Value: $<input name="value"/><br/>
    <input type="submit" name="create" value="Create"/>
</form>
<a href="welcome.jsp">back</a>
</body>
</html>

Here the four string and integer input fields need input validation placed on them to avoid SQL injection attacks pointed out by Rational AppScan. The BigDecimal class does internal input validation, and so you don't really need to perform input validation on the value parameter, though you might find it useful to display useful errors to users. If everything passes input validation, then the new real estate record is added to the database. Again the HTML comments were converted to JSP comments so that they don't appear in the HTML at all.

Listing 6. Updated securities.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<jsp:useBean id="securities" class="com.ibm.ds.securities.SecuritiesDataImpl" 
                                                              scope="page" /> 
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@page import="java.util.Iterator" %>
<%@page import="com.ibm.ds.securities.Securities" %>
<%@page import="pureQuery.example.*" %>
<%@page import="com.ibm.pdq.runtime.*" %>
<%@page import="java.net.*" %>
<%@page import="java.io.*" %>
<html>

<head>
<title>securities</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="GENERATOR" content="Rational Application Developer">
</head>
<body>
<h1>Your stock and options holdings</h1>
<table
 border="1"><tr><th>Sybmol</th><th>Description</th>
 <th>Quantity*</th><th>Type</th><th>Current price**
 </th><th>Total value</th><th>Quote date</th></tr>
<%
    String userid = (String)session.getAttribute("userid");
    
    if(userid == null){
        response.sendRedirect("login.jsp");
    }
    Data d = SampleUtil.getData("jdbc:db2://localhost:50000/WEALTH", 
	<enter_username_here>", "<enter_password_here>");
    securities.setData(d);
    Iterator i = securities.getSecuritiess(userid);
    
    Securities curr = null;
    double total = 0;
    while(i.hasNext()){
        curr = (Securities) i.next();
        
        String str = "http://finance.yahoo.com/d/quotes.csv?s="+curr.getSymbol()
		                                                          +"&f=nd1l1";
        URL url = new URL(str);
        URLConnection conn = url.openConnection();
        DataInputStream in = new DataInputStream ( conn.getInputStream (  )  ) ;
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String line = null;
        if(br.ready())
            line = br.readLine();
        
        String company = line.substring(line.indexOf('"')+1,
                                        line.indexOf('"', line.indexOf('"')+1));
        
        String date = line.substring(line.indexOf("\",\"")+3,
                                     line.indexOf("\",", line.indexOf("\",\"")+4));
        
        String price = line.substring(line.indexOf("\",", line.indexOf("\",\"")+4)+2);
        
        int multQuantity = curr.getQuantity();
        if(curr.getSecuritytype().equals("option"))
            multQuantity = curr.getQuantity()*100;
        
        float totalValue = Float.parseFloat(price)*multQuantity;
        totalValue = (float)(Math.round(totalValue*100.0)/100.0);
        
        out.println("<tr><td>"+curr.getSymbol()+"</td><td>"
		       +company+
                    "</td><td>"+curr.getQuantity()+"</td><td>"+
                    curr.getSecuritytype()+"</td><td>$"+price+
                    "</td><td>$"+totalValue+"</td><td>"
			+date+"</td></tr>");
        
        total += totalValue;
    }
    if(total > 0)
        total = Math.round(total*100.0)/100.0;
%>
</table>
<h3>Total value: $<% out.print(total); %></h3>
* # of contracts for options<br/>** Delayed quotes, as retrieved from 
                                                    Yahoo! Finance&trade;
<br/><br/><a href="welcome.jsp">back</a>
</body>
</html>

The only error this class had was the comments in the HTML. Note the change here from the HTML comment to a JSP comment.

Finally, invalidate the session (see Listing 7).

Listing 7. Updated welcome.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<html>
<head>
<title>welcome</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="GENERATOR" content="Rational Application Developer">
</head>
<body>
<%
    String userid = (String)session.getAttribute("userid");
  
    session.invalidate();
    session = request.getSession(true);
    session.setAttribute("userid", userid);
    
    if(userid == null){
        response.sendRedirect("login.jsp");
    }
%>
<h1>Welcome <% out.print(userid); %>!</h1>
See your <a href="securities.jsp">securities</a><br/>
See your <a href="realestate.jsp">real estate</a><br/><br/>
<a href="logout.jsp">logout</a>
</body>
</html>

Lastly, modify the HTML comment in welcome.jsp to JSP comments, and invalidate the session as discussed previously.

After updating the jsp's within Rational Application Developer, test everything is working with the Wealth Web application.

The second scan

Now that you have updated your Java code and tested that the Wealth Web Application is working, it is time to run Rational AppScan again and see how many vulnerabilities you have fixed.

Before running the another Scan, check your database tables data, since the previous Rational AppScan Scan might have populated tables with new rows of test data, including XSS, which can cause testing errors. In this case notice Rational AppScan added 50 or so entries in your securities table.

Once your tables have been checked and your Wealth Web App has been checked, you're all set for another scan.

Within Rational AppScan, click New or File > New (see Figure 34).

Figure 34. Select your previously created Scan Template, WealthScan
Select your previously created Scan Template, WealthScan

Next the Wizard starts again with the previous scan template information and settings populated. You want to repeat the exact same scan so accept these settings and press Next 3 times, select Application-Only and then click Finish.

Next you are prompted to save your second scan. Name it WeathScan2, after which the scan will commence.

Once the Scan has completed, you should notice the previous detected Security vulnerabilities have all been resolved and a clear report is displayed.

.

You have successfully cleaned the Wealth Web Application of all know security vulnerabilities!


Rational Appscan report choices and extensions

In this last section you'll see some of the various reports you can create and extensions you can use with Rational AppScan.

Rational AppScan reports

Now that your Web Application is free from security vulnerabilities, you can create some professional Quality Assurance reports. Such reports can be provided as part of release control process, proving your Web application has been successfully security tested, and is fit to be placed on the Internet (see Downloads to view the reports generated from your scans).

So with your last scan still open in Rational AppScan, select Tools > Report.

Now select an appropriate report template. Figure 35 shows an example of a standard report.

Figure 35. Industry standard reports
Industry standard reports

Figure 36 shows a list of the various regulatory compliance reports that can be selected.

Figure 36. Regulatory compliance reports
Regulatory compliance reports

Delta analysis reports

When testing large Web applications, it can take several scans by Rational AppScan before all the security bugs are ironed out. On occasion you will notice as you fix one security issue, several further security issues appear. Therefore, it can be useful to produce delta analysis reports to show your progress.

Delta Analysis compares a past scan with a current scan; they are straight forward to create. Within your existing scan you want to compare, select Tools > Report > Delta Analysis Report, and then navigate to a second saved scan you want to compare in your report (see Figure 37).

Figure 37. Delta analysis reports
Delta analysis reports

Rational AppScan empowers you to create your own specific report templates (see Figure 38), which is a simple and easy to learn process.

Figure 38. Creating your own report
Creating your own report

Rational AppScan extensions

Another useful and fully customisable feature within Rational AppScan is the use of Rational AppScan Extensions. Extensions are add-ons which add additional functionality and capabilities to Rational AppScan (see Figure 39). They can add anything from exploitation tools, to e-mail notification and to my personal favorite extension that exports the scan results straight into a PowerPoint Presentation.

Figure 39. Select the Extension Manager in Rational AppScan
Select the Extension Manager in Rational AppScan

Rational AppScan extensions are easy to write and integrate in Rational AppScan. IBM holds several freely downloadable extensions (see Figure 40) ready for integration at http://axf.watchfire.com/.

Figure 40. Select Install
Select Install

One of the most useful extensions available to download from IBM is the Email Notification Extension. To demonstrate how easy they are to integrate and how they work, here's a mini extension tutorial.

  1. First browse to http://axf.watchfire.com/ and download Mail-E-Vent Extension.

    The extension is downloaded as a zip file, but do not unzip this file, as the .zip format is correct for importing into Rational AppScan (see Figure 41).

    Figure 41. Navigate to your downloaded Mail-E-Vent Zip file
    Navigate to your downloaded Mail-E-Vent Zip file
  2. The Mail Extension is installed.
  3. Close the Rational AppScan application and then reopen it (see Figure 42).
    Figure 42. Return to the Extension Manager and open the new "Mail-E-Vent" Setup
    open the new mail e-vent
  4. Select Save and Test Settings, and check your in box for the test e-mail (see Figure 43). And that's all there is to it!
    Figure 43. Successful test email
    Successful test email

Now Rational AppScan will automatically send an e-mail notification (and a report where applicable), when a Scan ends, when Rational AppScan loses connectivity to the Web application, and when the scan pauses requesting a login prompt to be completed. This particular extension can be extremely useful when scanning larger and more complex Web applications, which can take a while. So you are able to go off and get on with something else, safe in the knowledge you'll receive an e-mail should Rational AppScan "need" you, which you have to say is pretty cool.

Finally you can easily create an extension yourself. IBM provides the source code for all the extensions featured on their Web site, so you can see how simple they are to produce. In no time at all you are able to integrate Rational AppScan into your business systems and produce extra features to meet any specific requirements you have.


Summary

You have ensured your Wealth Java Web Application created in Part 1 of this series is free from all known security vulnerabilities. The final revision of the Wealth Web Application can be uploaded to an Internet Web server, without you having to be concerned about it being hacked at the Web application level. Along the way in this tutorial you learned the importance of Web application security, taking time to work out a Rational AppScan deployment strategy, customizing a scan template, how to perform a scan, interpreting the results, fixing the vulnerabilities within the Web application code, and producing security reports.


Download

DescriptionNameSize
Generated reportsreports.zip875KB

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Rational software on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Rational, Information Management, Java technology, Security, DevOps
ArticleID=306658
ArticleTitle=Create secure Java applications productively, Part 2
publish-date=05042008