Apr 6, 2014

How to handle security in Java/J2EE applications



I got inspiration to write this post because I face some questions over security, and at times we are not ready with all points to present on how to handle security - since its a big topic and will include concepts and layers. 

Security is at multiple levels. Its at the JVM level, wie write secure Java code, and we want secure web applications. 

Applets - Since we are not playing with the JVM code, but still we need to know how under the hood some security was handled in applets - 
Why security needs to be handled in applets ?
Because the class files for an applet are automatically downloaded when a user goes to the containing Web page in a browser, it is likely that a user will encounter applets from untrusted sources. Without security, it is possible for applet downloaded from untrusted source to spread virus. 
How security is handled in applets - 
Java provides a customizable "sandbox" in which Java programs run.
The sandbox for untrusted Java applets, for example, prohibits many activities, including:
Reading or writing to the local disk
Making a network connection to any host, except the host from which the applet came
Creating a new process
Loading a new dynamic library and directly calling a native method
By making it impossible for downloaded code to perform certain actions, Java's security model protects the user from the threat of hostile code.
The fundamental components responsible for Java's sandbox are:
Safety features built into the Java virtual machine (and the language)
The class loader architecture
The class file verifier
The security manager and the Java API
One of the greatest strengths of Java's security model is that two of the four components shown in the above list, the class loader and the security manager, are customizable. 

Above we talked about untrusted code. We are writing code which is trusted. While the Java security architecture can protect users and systems from hostile programs downloaded over a network, it cannot defend against implementation bugs that occur in trusted code.

We have a very nice book in market which deals with Software Security - 

Secure java Code - Below is a summary of some important points which we should remember while writing Java code -

1. Check input/requests, and if they seem unusual, check or block like for example - 


  • Request for a very huge file or heavy resources. 
  • Entries to HashMap keys with same hashcode. 
  • Regular expression in input
  • Inputs for object creation in case of De-serialization, object graph from text or binary system. 
  • Input that are handled in loops. Input should not cause infinite looping.
  • Input that results in logging. Unusual input might result in detailed or excessive logging and loggiing of unwanted information. 
  • Take care of injection - use parameterised queries usejava.sql.PreparedStatement or java.sql.CallableStatement instead ofjava.sql.Statement

2. Take precautions and safety- 
  • Release resources
  • Prevent integer overflow
  • Internal exceptions should be caught and sanitized before propagating them to upstream callers. The type of an exception may reveal sensitive information, even if the message has been removed. For instance, FileNotFoundException reveals whether or not a given file exists.
  • Do not log highly sensitive information or mask the sensitive information while logging. 
  • Clear the sensitive information even from memory when done. In rare scenario, the sensitive information can appear in core dump. 
  • If a process is started from another process, or like - passing arguments to a command line to start the JVM, pass arguments encrypted. 
  • Declare class, interface, variables, etc. public, protected or private as appropriate. Use private unless you have good reason not to. 
  • Design classes and methods for inheritance or declare them final. Prefer composition over inheritance.
  • Changes to superclass method should be scrutinized because they might affect the subclass behavior and occasionally safety. 
  • Do not let other classes make changes in highly sensitive information, like for eg. if program A maintains a list L, which has highly sensitive data, let program B perform only read on L, or give a copy of L to B for manipulation. 
  • Provide copy methods for sensitive classes. 
  • Implement properly equals(), hashCode(), and toString(). 
  • private variables, and public getter() and setter(). 
  • Make public static fields final, and they are constants only. 
  • Static factory method for object construction is more safe than public constructor. 
  • To restrict untrusted code from instantiating classes, use SecurityManager. 
  • If constructor throws and an exception, object is in partially initialized state - this state should be guarded from attacker. (JDK6 and later by default prevent this).  
  • Avoid calling methods from constructors. 
  • Avoid serialization of class that might hold sensitive information. If need serialization, then take suggested steps. 
  • Libraries(Shared lib) should be granted permissions as generous the application code, which will use it. 
  • Sensitive operations - Callback methods, doPrivilidged(), 
  • Careful while caching results.
  • Careful while sharing contexts. 
Apart from above mentioned, there are several other checks we need to keep in mind. Please follow below links for more detailed information - 

http://www.oracle.com/technetwork/java/seccodeguide-139067.html
https://www.securecoding.cert.org/confluence/display/java/The+CERT+Oracle+Secure+Coding+Standard+for+Java

Security in J2EE, Web applications - 

Handling Security in web applications is a huge task. We have to think of numerous obvious threats and their standard ways to deal. No doubt there are tricky ways in which web applications are attacked, but here lets first talk about the obvious ones.
Top Security threats to Online Applications by OWASP - 
(Ref - https://www.owasp.org/index.php/Category:OWASP_Top_Ten_2013_Project )
I would highly recommend reading the complete report on OWASP site. 

Below is the summary - 


1. Injection - The attacker can inject malicious data. To prevent always keep input(/or untrusted data) separate from the command and query. Like for eg. Parametrized Queries prevent SQL Injection.
(Ref. - https://www.owasp.org/index.php/Query_Parameterization_Cheat_Sheet)

2. Session Management - Generally there are flaws in ways we handle - Login, Logout, Password management, Timeouts, remember me, Secret question, etc. We have protect user credentials, session Id, and user data.
If you want to verify your application against standards for session management, then download the complete guide/tests -
http://sourceforge.net/projects/owasp/files/ASVS/OWASP%20ASVS%202013%20Beta%20_v1.0.pdf/download
Handle Authentication - Case insensitive userID, Strong password, Store UserID/Password in secure manner - encode(preferably one way) before storing in DB, Second level authentication OR Multi-factor authentication should be present ( like secret question OR OTP), Second level authentication for critical features (like OTP for fund transfer), Error messages should be very generic (like "login failed" for incorrect userID and/or password ), Number of failed attempts should be restricted, and carefully crafted "Forgot password" feature - forgot password should have second level authentication, correct userID, and option to set new password.
Session ID - In order to keep the authenticated state and track the users progress within the web application, applications provide users with a session identifier (session ID or token) that is assigned at session creation time, and is shared and exchanged by the user and the web application for the duration of the session (it is sent on every HTTP request). The session ID is a “name=value” pair. The session ID name can disclose the technologies and programming languages used by the web application - JSESSIONID( for J2EE).
J2EE provides its own session management features and implementations. 
Secure Session and Session ID - 
It is mandatory to use HTTPS connection for the entire web session, in order to protect session ID. 
The session ID exchange mechanism based on cookies provides multiple security features in the form of cookie attributes that can be used to protect the exchange of the session ID. 
It is mandatory to set expiration timeouts for every session - Idle(inactivity) timeout is must and possibly Absolute(max. time period a session can be active regardless of activity). 
A session timeout should redirect the client side browser to logout page - this is handled by JavaScript, and context should be cleared on server side. 
Even after the session has been closed, it might be possible to access the private or sensitive data exchanged within the session and session ID through the web browser cache.  Use -
“Cache-Control: no-cache,no-store” and “Pragma: no-cache” HTTP headers - block sensitive data to cached
“Cache-Control: no-cache="Set-Cookie, Set-Cookie2"" - to block session ID to be cached. 
If user loads the login page and performs no activity, Reload the login page after specified time. 
Logout user if browser is closed.
Logout user if user logs in from some other browser, tab or device. Like for example log out user from online application, if user logs in from the Mobile. 
Attackers use set of IP address to and sends random multiple session ID, in order to guess a valid session ID. Web application should track such IP address and block them.
All session related events (creation, destruction) should be logged.

3. Cross Site Scripting (XSS) -
Any user input in any page is untrusted data.  If we are sending that untrusted data back to user(/browser), we are prone to XSS. 
Acc to OWASP - "XSS is the most prevalent web application security flaw. XSS flaws occur when an application includes user supplied data in a page sent to the browser without properly validating or escaping that content.". 
Attacker can send scripts which will be included in page on victim's browser, can hijack session, insert hostile content, redirect user, etc. 
OWASP recommends places where untrusted data should be placed in HTML, and if data is placed somewhere else, like in javascript (which is not recommended), then how to prevent XSS(properly escape all untrusted data). 
More details are available on OWASP site - 
https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
A very nice summary on 
http://help.sap.com/saphelp_nw73ehp1/helpdata/en/47/814743532348c3a8485de6dfd76899/content.htm?frameset=/en/81/233d54d8c744c09b4434babf7b0879/frameset.htm&fullscreen=true

4. Insecure Direct Object references - 
Passed few years I never worked on any application which exposes direct object references. This problem comes in small applications where for example, we can have code like - 
1. String query = "SELECT * FROM accts WHERE account = ?"; 
    PreparedStatement pstmt = connection.prepareStatement(query , … ); 
    pstmt.setString( 1, request.getParameter("acct")); 
    ResultSet results = pstmt.executeQuery( );
Here user can pass some other account number(not belonging to his or her), and can get the information. 
2. If account details are fetched by web service, and only parameter needs to be passed is the account number. 
Both of the above problems can be resolved by adding extra parameter, for eg. customerID.
If we have the customerID of the logged in customerID and we include customerID in SQL Query, or we have customerID also in the input request of webservice. Then we will not get any records, if customer passes an account number which doesn't belongs to him. 
Safe Query is like - 
String query = "SELECT * FROM accts WHERE account = ? and customerID=?"; 
Note customer doesn't know customerID. 
A similar SQL is below, where customer wants to fetch cart details based on CartID- 
int cartID = Integer.parseInt( request.getParameter( "cartID" ) );
User user = (User)request.getSession().getAttribute( "user" );
String query = "SELECT * FROM table WHERE 
     cartID=" + cartID + " AND userID=" + user.getID();

5. Sensitive Data Exposure - 
The most common flaw is simply not encrypting sensitive data.
Some examples how we prevent sensitive data exposure.
1. Use string encryption algorithm while encrypting sensitive data like password.
2. If sensitive information like Credit Card Number is stored in Db, encrypt. Mask data while displaying in browser and while logging. Do not put sensitive data in comments.
3. Prefer one way encryption. Like password is encrypted and stored in DB with salt token. Next time user enters password, use salt token and generate the encrypted value. Now compare the newly generated encrypted value with the stored value.
4. Use SSL, also use https web service URL's.
5. Don't store sensitive information, unless needed.
6. Disable auto complete in forms with sensitive data.

 6. Cross Site Request Forgery (CSRF) - 
Attacker knows a valid request, like for eg. a valid fund transfer request - 
http://example.com/app/transferFunds?amount=1500 &destinationAccount=4673243243
 Attacker though some technique like an image, XSS, etc. tricks user to submit this request, and just in case User session is active(or user is authenticated at that time), then request will be submitted with valid session ID, and this successfully executed. 
Attacker sends a image with code like below - 

Synchronizer Token pattern - Generate a random challenge token associated with user's current session. Challenge token is inserted in user forms and links, i.e. when user invokes an operation HTTP request includes this token. We are assuming it is not possible for attacker to guess or know this token, thus attacker's request will fail. 
"In general, developers need only generate this token once for the current session. After initial generation of this token, the value is stored in the session and is utilized for each subsequent request until the session expires. When a request is issued by the end-user, the server-side component must verify the existence and validity of the token in the request as compared to the token found in the session. If the token was not found within the request or the value provided does not match the value within the session, then the request should be aborted, token should be reset and the event logged as a potential CSRF attack in progress". 
(from - https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet)


Above were some points, but the actual list is very huge. But above are some very common ones. 


Security in Web Services - 

Security in Web Services is handled at two levels - Transport level and Application level. 
Transport level security includes authentication, confidentiality, message integrity, and exchanging secure key between client and server. 
Application level security extends transport level security and includes Data confidentiality(data is encrypted, XML encryption), Data integrity & authenticity( XML signature), etc. 
Summary of web services security requirements - 
  1. The use of transport security to protect the communication channel between the Web service consumer and Web service provider.
  2. Message-level security to ensure confidentiality by digitally encrypting message parts; integrity using digital signatures; and authentication by requiring username, X.509, or SAML tokens.
Indeed above all is not done pragmatically, instead application servers provide these features. 

Security in Java EE 

It is mentioned in Websphere Application server Red book that 
Security is a vast topic but can be thought of in two categories:
Physical security
Physical security refers to protection against physical threats, such as controlling physical
access to systems and protecting the environment of the systems.
Logical security
Logical security is connected to a specific IT solution, architecture, and application design.
It deals with all aspects of access to runtime resources and data.
Three Tier architecture offers the benefit that, if a security breach occurs in one of the
tiers, only that level is compromised. Only the necessary ports can be opened between layers
that exchange information. This way, the information flows from one level to the other in a
controlled manner.
Usually, web servers in the first tier are protected by one firewall that filters data from the
outside network. They are usually also protected by another firewall that filters information
that the web servers forward to application servers in the second tier. This concept is known
as a DMZ. The primary objective of the DMZ is to protect sensitive business logic or
information that is hosted in the application servers or databases. It shields this data from
possible attacks from untrusted networks on the Internet.

Share:

No comments

Post a Comment

Comment

© Shift, ShEkUP, Shape, and Surprise | All rights reserved.
Blogger Template Crafted by pipdig