Skip to main content

skip to main content

developerWorks  >  Web development | Open source  >

Build extra secure Web applications

A new protection framework helps you guard against action and data tampering

developerWorks
Document options

Document options requiring JavaScript are not displayed


Rate this page

Help us improve this content


Level: Intermediate

Derek Fong (dtfong@ca.ibm.com), I.T. Architect, IBM Canada

01 Nov 2005

Developers constantly fight the problems associated with action and data tampering in Web applications. This article provides a framework to secure these vulnerabilities. You can embed this framework, which offers a logical security design, in common presentation frameworks, such as Struts.

The purpose of Web application security design is to eliminate vulnerabilities. Well-known security design elements that are solely based on user credentials, such as authentication and authorization, work well for basic security requirements. However, data received from the client needs further scrutiny to extend the security perimeter from common design elements to application code. To satisfy this requirement, I offer a new security design framework that covers two common types of vulnerability: action tampering and parameter manipulation (also known as data tampering).

I'll introduce the framework at the presentation tier to handle sanity checks on static data sent by the browser. The framework can also detect action events from the browser and provide simple navigation control to the Web application.

Motivation for more security

Consider the scenario in which a malicious user uses proxy tools to hijack data sent by the browser. The impact can be severe, as the server will then process unexpected data. The following scenarios illustrate Web application vulnerabilities in more detail.

Web page navigation

Web page navigation control pertains to the application's access policy. Your access policy must dictate the possible navigation path for a specific user role in order to prevent a malicious user from navigating to a page (for example, through bookmarks) to which he or she does not have access.

HTML tag injection

Similar to page navigation control, HTML tag injection occurs when a malicious user tries to modify the HTML content before the server sends the data back to the browser. HTML tag tampering can include a hyperlink, Submit button, or any other form tag. For instance, if a Web page contains two Submit buttons and only displays one at a time based on certain conditions, a malicious user can use a proxy tool to add the second button to the Web page before it displays on the browser. The user can then submit the action to which he or she doesn't have access.

Parameter manipulation

Parameter manipulation (or data tampering) allows a malicious user to alter the data sent between the browser and the Web application server. A user can often tamper with parameters that contain URL query strings and hidden fields. For instance, if the Web page contains a hidden field that represents the customer ID, a malicious user can alter the value of the hidden field before the browser sends the data to the server.

The solution I'll describe here handles Web application vulnerabilities, minimizes the impact to application code, and is loosely coupled with application code and scalable for future requirements.



Back to top


Applying the framework

You can apply the protection framework when:

  • A Web application/Struts framework requires simple navigation controls.
  • A Web application needs to acknowledge events from user actions (such as Back and Refresh buttons).
  • A Web application requires protection for vulnerabilities on page static data; for example form action, links, buttons, and hidden fields.


Back to top


Model structure

To prevent a malicious user from hijacking HTML static contents in a Web page, the framework applies a server-side validation technique. The framework's program model, shown in Figure 1, describes the technique's design.


Figure 1. Class diagram for the protection framework
Class diagram for the protection framework

Processor

Processor defines operations to protect a user action that is modeled as an ActionParams. It also acts as a singleton object for handling requests from clients. Processor registers a user action with ParamsRepository and generates a reference code. It verifies user actions (Post, Get, and Put) through an http request with a reference code.

ParamsRepository

ParamsRepository maintains reference to all ActionParams objects. It provides basic access operations to retrieve and store ActionParams in an http session, and provides a mechanism to generate a reference code.

ActionParams

ActionParams defines an interface common to all supported query actions and static data. It implements a validate operation to validate query actions and static data. You can extend ActionParams to support application-specific requirements.

FormActionParams

FormActionParams extends ActionParams to support HTML form actions and static (hidden) fields. It also overrides the validate method to support form action validation.



Back to top


Collaboration of framework objects

This section describes the processes in which a client interacts with the framework to register and verify user actions.

Client registers static content for data protection

First, the client creates and passes an instance of the ActionParams object to Processor. Processor and ParamRepository then interact to store the ActionParams instance and return a reference code to the client, as shown in Figure 2.


Figure 2. Client registers for data protection
Client registers for data protection

Server verifies data received from the client

Processor then forwards a reference code from the client to ParamRepository for a specific ActionParams. Processor interacts with the ActionParams instance to verify user requests (see Figure 3).


Figure 3. Server verifies user action
Server verifies user action


Back to top


Implementation considerations

Now, I'll cover design details that you should be aware of when implementing this framework.

Code uniqueness

The reference code you generate for each ActionParams must be unique within a Web page; you should also be able to duplicate it across different pages. However, if you extend the framework to support double-click detection (see Other Extensions), the reference code has to be unique across the application.

Code lifecycle

Figure 4 outlines the reference code's lifecycle.


Figure 4. Reference code lifecycle
Reference code lifecycle

Each JSP request from the browser will generate a set of new reference codes and store them in the http session. When the user submits a request to the server, a reference code will map to the ActionParams in the session. Once the Processor completes the verification, it will erase all the code in the http session.

Exception handling

The framework does not throw any exceptions to the caller. You can handle the returned error code according to your application needs. In general, the application should terminate the user session and route back to the Welcome/Log On page if it detects any vulnerabilities.

Encryption approach

ParamsRepository uses http session to store the protected information. You can also encrypt the protected data and store it on the Web page directly. When you submit the data to the server, you send the encrypted data as well. Processor will decrypt the encrypted data and validate it against the real parameters. This approach can reduce the session size; however, it makes the performance much slower.



Back to top


Scenario walkthroughs

Next, I'll describe different scenarios in which you will need to protect the static content from a JSP. Then I'll show how the protection framework can solve the security vulnerabilities during runtime. These scenarios will give you a better understanding of the framework.

Scenario 1: JavaServer Page scriptlet

To define JSP scriptlets for all hyperlinks and form hidden fields, you must:

  1. Define action and parameters as ActionParams for each Processor JSP scriptlet.
  2. Define a Processor JSP scriptlet for hyperlinks with ActionParams as a parameter, as the code in Figure 5 demonstrates.
    Figure 5. Scriptlet to protect hyperlink
    Scriptlet to protect hyperlink
  3. Define a Processor JSP scriptlet for a hidden field with ActionParams as the parameter, as the code in Figure 6 demonstrates.
    Figure 6. Scriptlet to protect hidden field
    Scriptlet to protect hidden field

When the server loads the JSP, it executes the scriptlets and invokes Processor. Processor saves the protected data into ParamsRepository, which resides in the http session. Processor then returns the reference code to the Web page and displays as hyperlink parameters or hidden fields. See Figure 7 for the reference code (in red).


Figure 7. Result HTML
Result HTML

Scenario 2: Verify user action at a normal condition

In this scenario, the user clicks Submit on the Web page and then:

  1. The handler (for example, RequestProcessor or ActionServlet in Struts) on the server side invokes Processor.
  2. Processor then extracts the reference code from the http request and sends it to ParamsRepository. Since the user clicks the Submit button, the browser sends the reference code x2w3e (see Figure 7) to the server.
  3. ParamsRepository finds the matching ActionParams instance and returns it to Processor, as Figure 8 shows.
    Figure 8. ActionParams stored in ParamsRepository
    ActionParams stored in ParamsRepository
  4. Processor then verifies the user-submitted action with the retrieved ActionParams. The ActionParams instance for this scenario is a FormActionParams, and FormActionParams's validate method is invoked. Since the data sent to the server didn't change, Processor will return successful code, as Figure 9 shows.
    Figure 9. Verify ActionParams with FormActionParams in ParamsRepository
    Verify ActionParams with FormActionParams in ParamsRepository

Scenario 3: Verify user action with data tampering

In this case, when the user clicks Submit on the Web page:

  1. The user modifies the hidden value from 12345 to XYZ before the browser sends the request to the server.
  2. Steps 2 through 4 from Scenario 2 are repeated.
  3. Processor verifies that the parameters from the user request are different from the FormActionParams instance in ParamsRepository. Processor returns an error code.

As Figure 10 shows, ActionParams contains an invalid parameter ID XYZ, which Processor compares against the valid parameter ID 12345 in the ParamsRespository.


Figure 10. Processor verifies the received ActionParams
Processor verifies the received ActionParams

This verification prevents tampering from action/parameter manipulation and HTML tag injection since any modification to action/parameters fails on the validation.

Scenario 4: Verify user action with modified reference code

When a user clicks Submit on the Web page in this scenario:

  1. The user modifies the reference code value from x2w3e to hackValue in the hidden field tag before the browser sends the request to the server.
  2. The handler (for example, RequestProcessor or ActionServlet in Struts) on the server side then invokes Processor.
  3. Processor extracts the reference code from the http request and sends it to ParamsRepository. Since the user modifies the value, the browser sends the reference code hackValue to the server instead.
  4. ParamsRepository cannot find the matching ActionParams instance.
  5. As Figure 11 shows, Processor then cannot find the received code in ParamsRepository.
    Figure 11. Processor cannot find the received reference code
    Processor unable to find the received reference code
  6. Processor returns an error code.
  7. Because ParamsRepository dictates the possible actions for a particular Web page, the protection framework rejects any unidentified actions sent to it. This prevents Web navigation hijacking (such as bookmarked URLs).

Scenario 5: Verify user action with no code

Finally, when the user clicks Submit on the Web page here:

  1. The user removes the reference code's hidden field tag before the browser sends the request to the server.
  2. The handler (for example, RequestProcessor or ActionServlet in Struts) on the server side invokes Processor.
  3. Processor determines that no code was retrieved from the request and returns an error code.


Back to top


Sample code

The following code shows how to implement the framework in Java.

ParamsRepository

The storeParams method stores the ActionParams into a map within the http session. The code parameter identifies a particular ActionParams instance. You can choose other types of implementation to store the ActionParams since the implementation is isolated to the caller, as Figure 12 shows.


Figure 12. storeParams method implementation
storeParams method implementation

The RetrieveParams method returns an ActionParams instance based on the reference code, as Figure 13 shows.


Figure 13. retrieveParams method implementation
retrieveParams method implementation

ActionParams

The validate method allows ActionParams to validate itself with another instance. It delegates the validation of action and parameters to different methods, as Figure 14 shows.


Figure 14. The validate method implementation
The validate method implementation

FormActionParams

FormActionParams overrides the doValidateParams method to validate the static hidden fields inside the form (see Figure 15).


Figure 15. The doValidateParams method
The doValidateParams method

Processor

Processor invokes the verifyAction method to validate the user action, and it returns error code if the validation fails. Table 1 describes the possible scenarios in which Processor submits an error code.


Table 1. Processor produces different error codes for each of the following scenarios:
ScenariosError CodeReason
Check if the reference code is missing from the http request.CODEMISSING_ERRUser sends an unknown request to the server.
Check if the code exists in the ParamsRepository through the verifyWithRepository method.INVALIDCODE_ERRUser sends a previously bookmarked request to the server.
Check if a user has tampered with the static data in the http request.DATATAMPERING_ERRUser modifies the data being sent to the server.

The verifyAction method allows user actions to be verified against the ActionParams stored in the repository (see Figure 16).


Figure 16. Verify action
Verify action


Back to top


Struts

You can easily integrate the protection framework with the Struts tag library so that the framework implementation is transparent. To integrate the framework into Struts, you must inherit the following Struts tag libraries.

Form and hidden tag libraries

To protect form action and hidden fields, you modify Struts' FormTag and HiddenTag to invoke the Processor. Create a subclass that:

  • Extends Struts HiddenTag class; collects all hidden field parameters and stores them into the pageContext attribute.
  • Extends Struts FormTag class; overrides doAfterBody method to register the pageContext attribute and form action with Processor. The returned reference code outputs as a hidden field (see Figure 17).

Figure 17. FormTag's doAfterBody method
FormTag's doAfterBody method

Link tag library

To protect links, you can modify the Struts LinkTag to invoke the Processor. Create a subclass that:

Extends Struts LinkTag class; overrides the calculateURL method to populate the ActionParams object and register with the Processor. The returned reference code will be attached to the end of the URL, as shown in Figure 18.


Figure 18. The calculateURL method
The calculateURL method

When you integrate the protection framework with Struts, you can simply apply the Struts tag libraries in the JSP; this applies the framework automatically.



Back to top


Other extensions

The framework can support other types of protection if you extend ActionParams. Similarly to FormActionParams, you can extend drop-down-box protection from ActionParams to validate the selected value with the list of valid drop-down values. By maintaining the previously processed code value, the framework can detect the double-click event with synchronized user requests. If you receive a request with the same code value, assign the previous response to this request.



Back to top


In conclusion

This article describes the common types of Web application vulnerabilities and provides a framework to address these issues. The framework covers the logical security aspect of a Web application and protects static data on the Web page. While the framework can mitigate the risk of threats, designers should iteratively analyze the application architecture and identify any potentially vulnerable areas. This allows you to enhance and modify the framework to accommodate new types of threats.



Resources

Learn

Get products and technologies

Discuss
  • Cert.org: Track the most up-to-date news about security vulnerabilities and statistics.

  • BugTraq: Discuss vulnerabilities and security flaws on this public mailing list.

  • developerWorks blogs: Get involved in the developerWorks community.


About the author

Derek Fong is an IT architect in the IBM Global Service, Enterprise Application Development team. Derek has expertise in J2EE application design and development. He received his computer science degree (B.Math) from the University of Waterloo in 1994.




Rate this page


Please take a moment to complete this form to help us better serve you.



YesNoDon't know
 


 


12345
Not
useful
Extremely
useful
 


Back to top