This site is the archived OWASP Foundation Wiki and is no longer accepting Account Requests.
To view the new OWASP Foundation website, please visit https://owasp.org

Java Server Faces

From OWASP
Revision as of 07:33, 15 May 2007 by Sammyrulez (talk | contribs) (MyFaces)

Jump to: navigation, search

Status

Content to be finalised. Needs reviewing

Author

Sam Reghenzi

Web security.. before you start

This document is about security in web applications developed using the Java Server Faces (JSF) framework. The reader should be aware of the meaning of common terms of both JSF (converters, validators, managed beans) and web security (injection etc.)


JSF Standards and roles

JavaServer Faces (JSF) is a Java-based Web application framework that implements the Model-View-Controller pattern and simplifies the development of web interfaces for Java EE applications.

In a standard MVC JSF should do the V (of view) and part of the C (of Control). JSF components could present almost any basic interface model. The framework also provide part of the Control in the meaning of:

  • Navigation Handling
  • Error Handling
  • Action and event Management
  • Input validation
  • Value conversion.

These elements are defined by the JSF standard (jcp 127) so that any attacker is aware of the inner mechanism and life cycle of a JSF based application. JSF does not implement it's own security model but instead relies on standard J2EE security. This means that both application server security model, JAAS or other ACL implementations could be used with teh JSF framework without any integration effort. But Access Control is just one face of security - all the faces should be implemented in a secure manner in order to consider the application itself secure.

Client-side state saving

A JSF application can save the state of its components in the client response or on the server. Saving state on the client may be required because some users turn off cookies support, but it can increase response times when connections are slow. Saving state on the server may have the disadvantage of high memory consumption for the user, but it does minimize bandwidth requirements. Since client-side state saving stores data in the client , it should be used wisely, or not used at all. An attacker that can manipulate a user's data could manage a data tampering or worst, a privilege escalation exploit. Unencrypted data is quite easy to manipulate and most of the client-side saved data are serialized Java objects which can contain a wealth of sensitive data. If you plan to use client-side state saving carefully consider which information you decide to store in the POJO/DTO in order to minimise these risks.

Components

Converters

Converter could be a source of threat since it converts string in Java objects. An attacker could inject malicious code or tampered data to make the converter itself misbehave and expose protected data. The converter system is not insecure by itself, but conversion, since it is a security touch point for business logic and persistent data, should be handled carefully. Input should always be validated after being converted. In JSF lingo you should always have a validator if a conversion occurs. See next section on how to implement a security aware validator.

Validators

Validation is your chance to verify that the input is as expected. This means that the input should be validated both from a domain view and from a security view. If input represents a string that in your domain should be from 10 to 254 characters long, the same string should be validated also to prevent SQL Injection and XSS attacks. Since many security checks are done using dictionary algorithms it's useful to have a validator that implements those checks and extends it to implement your domain validator. For example:

public class TenToHundredsValidator extends SecureValidator() {
   public void validate(...) {
      
      super.validate(...); // Do security checks
      
      domainvalidate(....);
   }
}          
  


ManagedBeans

Managed beans are the gears of JSF based application. Developers can access FacesContext statically and this is potentially dangerous. This is a common short cut for everything in the JSF layer, but manipulating this data could be harmful. Relying on security principals, and software engineering, is always a good approach. Calls such as:

   FacesContext.getCurrentInstance().getExternalContext().getRequestParameter("name")

are dangerous because the whole validation stack is bypassed. You can read parameters but consider them as tainted input. Use Validators described above also if you are not in the validation phase . Validators are also an effective way to refactor your validation code and to prevent code repetition. FacesContext also allows access to user principal data; this data could be used to verify if the current user can actually execute the business logic in the managed Bean. This practice should be adopted in favour of rendering or not the commandLinks that lead to the action of the managed Bean. A structured adoption of an execution based security framework , such as ACEGI (see the Appendix), could be a good enforcement of the security of the managed bean.

Custom components

If the use of custom components is required in the application, the security depends on how the components are developed. Third party components should be delivered with a security report and support from the specific vendor or community. If you develop custom components you should be aware of the same old security issues of web development:

  • Do not thrust request parameter
  • Do not thrust cookies
  • Always consider that session could be hijacked

Since the component tree is assembled server side it can be trusted so if your custom component needs to read data from a sibling component it should be considered a safe operation although you will have to make assumptions on element names of the tree.

Implementations

Since more than one JSF Implementation exists, bugs of the implementation should be first on the security list.

MyFaces

There aren't major or critical security bugs registered in the current stable release of MyFaces (1.1.5). Client state saving is still the weak point and should be used wisely. My Faces comes also with a Security Extension (http://wiki.apache.org/myfaces/SecurityContext) that allows to safely and easily retrieve authenticated user details.

The MyFaces resource filter could be a source of threat. It is designed to expose resources from a jar file and could therefore, be considered, potentially dangerous. Note there aren't any claimed security flaws nor exploits in the resource filter, but the nature of this component makes it a good target for attackers. Since all it has to do is serve data it is recommended that a dispatcher be added to the filter mapping element. This should lower the possibility of an attacker successfully manipulating the server request. For more information see: http://myfaces.apache.org/tomahawk/extensionsFilter.htm

There is also an easy way to enable encryption when using client save state

<context-param> <param-name>org.apache.myfaces.secret</param-name> <param-value>NzY1NDMyMTA=</param-value> </context-param>

Supported encryption methods are BlowFish, 3DES, AES and are definde bya a context parameter <context-param> <param-name>org.apache.myfaces.algorithm</param-name> <param-value>Blowfish</param-value> </context-param>

SUN Reference Implementation

Quoting from the documentation: There are several ways for a web application to store session state on the client tier. One possible solution is to use Cookies to store the state on the client. However, cookies have limitations in size and are not ideal in cases where you want to store session state on the client. The state that needs to be stored on the client is first serialized into a byte array. This byte array is then encrypted using industrial-strength 3DES with cipher-block-chaining (CBC) and an initialization vector. To make the content tamper-resistant, we then create a message authentication code (using SHA1 algorithm) from the encrypted content and the initialization vector. The initialization vector, the message authentication code, and the encrypted content is then combined in a single byte array. Finally, this resulting byte array is converted into a base64 string which is stored in a hidden FORM field on the client. This solution is secure because it uses a strong crypto algorithm and also uses a MAC for tamper-resistance. We also generate all the random numbers (for example, to generate the initialization vectors and the password) using the cryptographically-secure SecureRandom class. Note that the encryption keys are NEVER sent to the client or sent on the wire. These keys are used only on the server-side to encrypt and decrypt the state. One challenge is to decide what encryption keys to use. The encryption keys should not be known to the client, but still be associated with the client. We solve this problem by generating these keys from a password that is generated randomly and stored in the HttpSession. This strategy for key generation through password is pluggable in our solution and can be changed if needed.

EUxx

http://jroller.com/page/eu stated the following: It seems there are few gaps in this claim. Data sent to the client look like this: [MAC][IV][ENCDATA] As you can see, MAC and IV values are known to the client. It means that nothing can stop client from tampering ENCDATA block and then generate a new MAC. This can be improved with using signature based on public key scheme instead of MAC. However that will increase amount of computations for building message data and will require to store public key in HttpSession. Another potential security issue is related to the usage of block cipher. By the nature of Object Serialization Stream Protocol, every encrypted plain text will have common patterns. More over, because client can indirectly control content of the encrypted data by submitting specially crafted requests to the server, that some data from request will be sent back in encrypted form). This can open the door for "known-text" attack and I'm not sure how good "industrial-strength" ciphers against such attacks. Again, this can be improved by generating secure key for every request, but it will create additional troubles on concurrent scenarios and will require that key will be distributed across the cluster on every change. So, I think that above issues has to be investigated more deep and proper security analysis must be done before suggesting any solution that is using some forms of cryptography.

ICE Faces

TODO