Data AccessCore JavaApp FrameworksViewTestingBuildingDeploymentDev ToolsSecurityOpinions
Showing posts with label Application. Show all posts
Showing posts with label Application. Show all posts

Monday, December 5, 2011

Changing the Session Identifier (JSESSIONID) on Authentication. Protecting against Session Fixation attacks in Java Web Environments

It is a standard security practice to change the session identifier (JSESSIONID) after a successful login or authentication.

The attack scenario with this vulnerability is that a user can open a browser on a shared terminal and record the session identifier set by the application. Later when any other user of the system logs into the application without closing instances of that browser the same cookie will be used to track the victim's session.

Alternatively, if the application is susceptible to cross-site scripting on a publicly accessible page (most damagingly the home page), an attacker can use this vulnerability to learn the value of the session identifier, because the cookie does not change since it was first set. The attacker now knows the value of the session token can hijack the victim's session. This is a limited session fixation attack where the attacker does not have control over the value of the session identifier, but is able to know its value through various means before and after a user authenticates.

Most times, invalidating the session and creating a new one may suffice. However, if you are storing variables or objects, you may need to carry these variables or objects from the old session into the new session.

Below is a javax.servlet.Filter. This filter protects against the Session Fixation attacks described above. The filter looks for a specific session attribute, the (NEW_SESSION_INDICATOR) attribute. If one is found, the filter copies out relevant session data to a map, invalidates the session, creates a new session and loads the new session with the old session data.

The filter is simply mapped in your web.xml. Any place you successfully authenticate, an attribute is added to the session (NEW_SESSION_INDICATOR).

The code below follows:

import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class NewSessionFilter implements Filter {
  
  private static Logger logger = Logger.getLogger(NewSessionFilter.class.getName());
 
  public static final String NEW_SESSION_INDICATOR = "filter.NewSessionFilter";
  
  public void destroy() {}
  
  @SuppressWarnings("unchecked")
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
    if (request instanceof HttpServletRequest){
      HttpServletRequest httpRequest = (HttpServletRequest) request;
      if (httpRequest.getSession(false) != null && 
          httpRequest.getSession(false).getAttribute(NEW_SESSION_INDICATOR) != null
      ){
        //copy session attributes from new session to a map. 
        HttpSession session = httpRequest.getSession();
        HashMap old = new HashMap();
        Enumeration keys = (Enumeration) session.getAttributeNames();
        while (keys.hasMoreElements()) {
          String key = keys.nextElement();
          if (!NEW_SESSION_INDICATOR.equals(key)) {
            old.put(key, session.getAttribute(key));
            session.removeAttribute(key);
          }
        }
        logger.info("session invalidated on " + httpRequest.getRequestURI());
  
        //invalidation session and create new session.
        session.invalidate();
        session = httpRequest.getSession(true);
 
        //copy key value pairs from map to new session.
        for (Map.Entry entry : old.entrySet()) {
          session.setAttribute(entry.getKey(), entry.getValue());
        }
 
        logger.info((new StringBuffer()).append("new Session for URI '")
             .append(httpRequest.getRequestURI()).append("':")
             .append( session.getId()).toString());
      }
    }
    chain.doFilter(request, response);
  }
  
  public void init(FilterConfig filterconfig) {}
}

Any questions about this posting or filter, comment below and I'll be sure to answer.

Wednesday, November 30, 2011

Steps to a CAPTCHA Implementation using JAVA/JSP

CAPTCHA can quickly and easily protect your web application against brute force and bot attacks or abuse. There are just a few simple steps to a CAPTCHA implementation in Java/JSP. The solution is simple and the documentation is quite clear, so I only provide the steps and quick links to those resources.

Step 1: Signup for a CAPTCHA account and generate keys for your website domains.
Navigate to http://www.google.com/recaptcha and signup for an account. After obtaining a login, generate keys for your domain.

Step 2: Find the developers guide for CAPTCHA
Navigate to http://code.google.com/apis/recaptcha/intro.html. From here, you'll find all the information you need. Notice in the left hand menu, there's a Java/JSP Plugin link available. Click into that.

Step 3: Download the Java/JSP Plugin and Implement
Navigate to http://code.google.com/apis/recaptcha/docs/java.html where you will find a link to download the plugin, which is a set of Java classes. Extract the source files into your web applications java source tree. The directions on the page are extremely straight forward.

The form page looks like:
 
<%@ page import="net.tanesha.recaptcha.ReCaptcha" %>
<%@ page import="net.tanesha.recaptcha.ReCaptchaFactory" %>

<html>
<body>
<form action="" method="post">
   <%
      ReCaptcha c = ReCaptchaFactory.newReCaptcha("your_public_key", "your_private_key", false);
      out.print(c.createRecaptchaHtml(null, null));
   %>
   <input type="submit" value="submit" />
</form>
</body>
</html>
You also may be using reCaptcha over https. In that case, follow the instructions from this page: http://code.google.com/apis/recaptcha/docs/tips.html
<script type="text/javascript"
   src="https://www.google.com/recaptcha/api/challenge?k=your_public_key">
</script>

<noscript>
   <iframe src="https://www.google.com/recaptcha/api/noscript?k=your_public_key"
       height="300" width="500" frameborder="0"></iframe><br>
   <textarea name="recaptcha_challenge_field" rows="3" cols="40">
   </textarea>
   <input type="hidden" name="recaptcha_response_field"
       value="manual_challenge">
</noscript>
When the form is submitted, the reCaptcha entries can be verified easily.
<%@ page import="net.tanesha.recaptcha.ReCaptchaImpl" %>
<%@ page import="net.tanesha.recaptcha.ReCaptchaResponse" %>

    <html>
       <body>
       <%
        String remoteAddr = request.getRemoteAddr();
        ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
        reCaptcha.setPrivateKey("your_private_key");

        String challenge = request.getParameter("recaptcha_challenge_field");
        String uresponse = request.getParameter("recaptcha_response_field");
        ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(remoteAddr, challenge, uresponse);

        if (reCaptchaResponse.isValid()) {
          out.print("Answer was entered correctly!");
        } else {
          out.print("Answer is wrong");
        }
      %>
      </body>
    </html>
Step 4: Give the JVM a time interval to refresh its DNS cache
By default the Java Virtual Machine (JVM) caches all DNS lookups forever instead of using the time-to-live (TTL) value which is specified in the DNS record of each host. To fix this issue for good, you can pass -Dsun.net.inetaddr.ttl=30 to your app-server (this tells Java to only cache DNS for 30 seconds).

There is a great article on the JVM and DNS caching. A must read at http://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/1887

The steps above are quick and easy to implement, post back and let me know if you have any issues with the implementation and I will try and assist.

Thursday, November 17, 2011

Disabling certain HTTP Methods in Tomcat

HTTP protocol defines eight methods that can be performed on a resource on the HTTP server. GET, POST and HEAD are the most common methods that are used to access information provided by a web server. The other methods such as OPTIONS, PUT, DELETE, CONNECT and TRACE are not normally used in the general operation of a web server can potentially pose a security risk for any web application. So it is good practice to restrict the response to specific HTTP Methods.

First, determine which HTTP Methods your installation is responding too. I use browser plug-ins that enable me to submit HTTP requests, specifying the URL and HTTP method. There are various plugins available for Chrome and Firefox and I do not make any recommendations here.

Second, according to your test results, configure your Tomcat installtion to not respond for certain HTTP Methods. This can be configured at the instance level by inserting a <security-constraint> element directly under the <web-app> element, in the installations web.xml file located at.
[tomcatinstallation]/conf/web.xml

Below is the added configuration.


<security-constraint>
<web-resource-collection>
<web-resource-name>restricted methods</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>TRACE</http-method>
<http-method>PUT</http-method>
<http-method>OPTIONS</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint />
</security-constraint>


The configuration above will disable the HTTP Methods TRACE, PUT, OPTIONS or DELETE.

Any questions, comment and I'll be sure to answer them.

Saturday, November 6, 2010

JAX-RS @Path Precedence Rules

The other day I needed to figure out how the JAX-RS provider resolves ambiguous path expressions passed in the @javax.ws.rs.Path annotation. I learned about the provider's precedence rules and wanted to document them here with a short example.

For example, say we have the following @javax.ws.rs.Path expressions in the following class:

@Path("/users") 
public class UserResource {

  @GET
  @Path("{id : .+}")
  public String getUser(@PathParam("id") String id){
    ....
  }


  @GET
  @Path("{id : .+}/address")
  public String getAddress(@PathParam("id") String id){
    ....
  }
}

Note that .+ will match any stream of characters after "/users".
Now, suppose the following GET request was submitted.

GET /users/32/address

The request actually matches both expressions, but the request would be routed to the getAddress(@PathParam("id") String id) method. The JAX-RS provider determines which method to call based on a set of precedence rules. On deployment, the JAX-RS provider gathers and sorts all URI expressions contained within all known @Path annotations based on the following logic:

  1. The number of literal characters contained within the expression, sorted in descending order. In the example above, the getAddress(@PathParam("id") String id) method gets precedence over the getUser(@PathParam("id") String id) method. The getUser(@PathParam("id") String id) method contains 7 literal characters (/users/). The getAddress @PathParam("id") String id) method contains 14 literal characters (/users/ + address).
  2. The number of template expressions within the expression, sorted in descending order. For example, an expression containing {id}/{name} would get precedence over {id}.
  3. Finally, the number of regular expressions contained within the expression. For example, {id : .+} would get precedence over {id}.

In closing, the following URI expressions are sorted by the order of precedence above.

  1. /users/{id}/{name}/address
  2. /users/{id : .+}/address
  3. /users/{id}/address
  4. /users/{id : .+}

Any questions, leave a comment and I'll be sure to answer.

Sunday, October 18, 2009

Forcing a JSP to recompile

You can force Tomcat to recompile a jsp from any web brower by making a request to:

http://hostname/path/yourPage.jsp?jsp_precompile=true

The jsp_recompile parameter in the request will force the request to compile the page and load it into the ClassLoader. This is only true if you are jsps are outside of the WEB-INF folder.

Tuesday, September 8, 2009

Accessing HTTP Header with OGNL

OGNL stands for Object-Graph Navigation Language; it is an expression language for getting and setting properties of Java objects. You use the same expression for both getting and setting the value of a property.

Struts2 adds on top of OGNL by providing support for a 'Value Stack'. While OGNL operates under the assumption there is only one "root", XWork's ValueStack concept requires there be many "roots". Have a quick read on OGNL basics.

When referring to non-root objects are accessed with a (#) sign.

Accessing an HTTP Header can be achieved by the following code.
<s:property value="#header.myHeaderPropKey"/> or
<s:property value="#header['myHeaderPropKey']"/> or

Wednesday, July 15, 2009

Branching in CVS with Eclipse

Sometimes you find such a well written article on a specific topic that you feel that it just needs to be shared.

I have gone to this article on branching and merging in CVS with Eclipse numerous times for more confidence, particularly before a merge.

http://www.eclipse.org/articles/article.php?file=Article-BranchingWithEclipseAndCVS/article1.html

Monday, July 6, 2009

Preparable CRUD actions with multiple prepare methods

Many of the Struts2 Tutorials guide you towards stuffing multiple CRUD operations for a single entity within a single action. Sounds nice, but what happens when you need to prepare these actions differently?

Your first instinct might tell you to implement multiple actions for that one entity (one per CRUD operation, or maybe even stuff two inside one action).

However, you can add multiple prepare{METHOD}() like prepareDoDelete(),
prepareDoUpdate(). If you follow this convention, the appropriate prepare method will be called before your action method.

The following is a snippet from the Struts 2 Documentation at:
http://struts.apache.org/2.0.11/docs/prepare-interceptor.html

In PrepareInterceptor

Applies only when action implements Preparable

1. if the action class have prepare{MethodName}(), it will be invoked
2. else if the action class have prepareDo(MethodName()}(), it will be invoked
3. no matter if 1] or 2] is performed, if alwaysinvokePrepare property of the interceptor is "true" (which is by default "true"), prepare() will be invoked.

Monday, June 15, 2009

Using Static Helper Classes - Java Memory and the Initialization on Demand Holder Idiom

A recent discussion about design patterns and data delegator classes was brought up recently in the tomcat-users mailing list. It is common to find that many web applications use several delegate classes providing access to some data source. Delegate classes are often implemented using the singleton-design pattern, which proposes that at any time there can only be one instance of a singleton (object) created by the JVM.

Theoretically, questions come into mind concerning the governance surrounding instantiation and synchronization of these singleton classes, especially in a multi-threaded environment.

In this post, we'll go over some approaches posted in the thread and provide a best option.

  • Static Initizialization
  • Double Checked Locking (later only on post 1.5 jvm)
  • Initialize-On-Demand Holder Class Idiom (MOST PREFERRED)


Static Initialization
class BeanBag {
private static final SomeBean someBean = new SomeBean();
private static final AnotherBean anotherBean = new AnotherBean();

public static SomeBean getSomeBean() { return someBean; }
public static AnotherBean getAnotherBean() { return anotherBean; }
}

The initialization happens at the loading time of the class but there is no guarantee to be synchronized. The static class property someBean will be available at first call to getSomeBean(). This works 99% of the time, I have never had a problem with it.

Double Lock Checking
class BeanBag {
private static volatile SomeBean someBean = null;

public static SomeBean getSomeBean() {
if (someBean==null){
synchronized(BeanBag.class){
if (someBean==null){
someBean = new SomeBean();
}
}
}
return someBean;
}
}

The difference here, is the singleton instance is not actually instantiated until the getSomeBean() method is called. This provides a more lazy instantiation paradigm if needed. Here we can synchronize the block when SomeBean is instantiated.

Initialize-On-Demand Holder Class Idiom
class BeanBag {
//Inner Class
private static class BeanBagHolder {
public static SomeBean someBean = new SomeBean();
}

public static Something getInstance() {
return BeanBagHolder.someBean;
}
}

This idiom derives its thread safety from the fact that operations that are part of class initialization, which is guaranteed by the JVM. It derives its lazy initialization from the fact that the inner class is not loaded until some thread references one of its fields or methods. This provides the best of both options and guaranteed to be thread-safe by the JVM.

The last option is the most preferred and this article goes into greater detail about Java Memory Model.

Sunday, June 14, 2009

Struts2: Accessing Session Variables in JSP's

Struts 2 places named objects including the session onto the OGNL stack. Named objects can easily be retrieves using the s:property tag. For example:

<s:property value="%{#session.User.firstName}"/>


Struts 2 supports other named objects that can be accessed the same way. Suppose the attribute name attrName for all examples below.

Request parameter : #parameters['attrName ']
Request attribute : #request.attrName
Session attribute : #session.attrName
Application Attribute : #application.attrName

For more on OGNL basics, click here.

Tuesday, April 14, 2009

Converting Camelcase to SEO friendly strings

Recently, I've been working on a simple code generator that generates code, facilitating CRUD operations on a simple database table. I quickly needed to find a way to turn a CamelCase string into an SEO friendly string, converting a string like, "camelCase" to "camel-case".

Below is a code snippet that does just that. It isn't the most efficient code, but it does get the job done. I've been using this code to generate Struts2, Spring JDBC CRUD code, following conventions dictated by the Struts2 Convention Plugin.

There is a dependency on the commons-lang package, which you will need in your build path to compile:

The code snippet follows:

package com.edwardwebnerd.tools.generator;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.apache.log4j.Logger;

public class StringConverter{

private static final char [] capitalLetters = new char[] {'A','B','C','D','E','F',
'G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

public static String toSearchEngineOptimized(String aString){
ArrayList stringPieces = new ArrayList();
int firstCapital = StringUtils.indexOfAny(aString, capitalLetters);
int tempIndex = 0;

while(firstCapital > 0){
String snippet = aString.substring(tempIndex, firstCapitalIndex);
tempIndex = firstCapital;
stringPieces.add(StringUtils.uncapitalize(snippet));
firstCapital = 
StringUtils.indexOfAny(aString.substring(firstCapital), capitalLetters);

}
stringPieces.add(StringUtils.uncapitalize(aString.substring(tempIndex)));

String foldername = "";
for(int i = 0; i < stringPieces.size(); i++){
if(i == 0)
foldername = stringPieces.get(i);
else
foldername = foldername + "-" + stringPieces.get(i);
}

return foldername;
} 


If you have any questions, please just comment and I'll get back to you.

Wednesday, March 4, 2009

Sorting java.util.List with a java.util.Comparator using java.util.Collections

Sorting objects in a List is a piece of code that every java programmer will write more than once in their lifetime. Any object that implements the java.util.List interface can utilize the sort method contained within the java.util.Collections class to sort the list, using a java.util.Comparator.

Below is a short tutorial and code sample.

First, let's define our object model.

package com.company.model;

public class MilkDelivery {

private int daysTilExpiration;

public MilkDelivery(int daysTilExpiration){ 
this.daysTilExpiration = daysTilExpiration; 
}

public int getDaysTilExpiration() { 
return daysTilExpiration; 
}

public void setDaysTilExpiration(int daysTilExpiration) { 
this.daysTilExpiration = daysTilExpiration; }
}


Second, let's write a Comparator and implement the compare method.

package com.company.model.comparator;

import java.util.Comparator;

import com.company.model.MilkDelivery;

public class MilkDeliveryComparator implements Comparator {

/** Supports sorting from days til expiration ascending */
public int compare(MilkDelivery o1, MilkDelivery o2) {

//Cast down
MilkDelivery delivery1 = (MilkDelivery) o1;
MilkDelivery delivery2 = (MilkDelivery) o2;

if(delivery1.getDaysTilExpiration() > delivery2.getDaysTilExpiration()){
return 1;    
}else if(delivery1.getDaysTilExpiration() == delivery2.getDaysTilExpiration()){
return 0;
}else if(delivery1.getDaysTilExpiration() < delivery2.getDaysTilExpiration()){
return -1;

//or a much more graceful solution....
//return (delivery1.getDaysTilExpiration() - delivery2.getDaysTilExpiration());
}
}
Last but not least, lets write a test class.
package com.company.test;

import java.util.ArrayList;
import java.util.Collections;

import com.company.model.MilkDelivery;
import com.company.model.comparator.MilkDeliveryComparator;

public class MilkTest {

public static void main(String [] args) throws Exception{

ArrayList deliveries = new ArrayList();

deliveries.add(new MilkDelivery(2));
deliveries.add(new MilkDelivery(3));
deliveries.add(new MilkDelivery(1));
deliveries.add(new MilkDelivery(4));

//Sort
Collections.sort(deliveries, new MilkDeliveryComparator());

for(int i = 0; i < deliveries.size(); i++){
MilkDelivery milkDelivery = deliveries.get(i);
System.out.println("Delivery(" + i + ")  Days til Expiration:" + 
milkDelivery.getDaysTilExpiration());
}
}
}


The output should read:
Delivery(0) Days til Expiration:1
Delivery(1) Days til Expiration:2
Delivery(2) Days til Expiration:3
Delivery(3) Days til Expiration:4

Tuesday, February 17, 2009

Customizing an HTML Struts2 Tag

The Struts2 Tags come with the notion of packaged themes or templates. These packaged themes are not meant for changing the display of presentation, but enables a developer to align the package or theme selection, with the HTML presentation implementation (CSS, AJAX, XHTML, or even old school, simple HTML).

In addition the Struts2 Tag library comes with the ability to override the default package implementations provided. Some of the default packaged themes may perform as desired, but in some instances, you may have to customize the tags display output.

Below, I've provided two great starting points in helping you overload your templates and customizing the behaviour of your Struts2 tags.

http://struts.apache.org/2.0.14/docs/themes-and-templates.html
http://struts.apache.org/2.0.14/docs/template-loading.html

Tuesday, January 27, 2009

java.util.List to Object array (Object []) of a specified type

The tip below can help you in the data access tier or the application tier.

The java.lang.reflect.Array class provides static methods to dynamically create and access Java arrays. Any java collection or list can easily be converted into an Object array. There are two method calls, that I preferably squish into one line to get the job done. The first method call is:

Array.newInstance(Class componentType, int length) throws NegativeArraySizeException 


The method creates a new array with the specified component type and length. You can also cast down to have returned an array of your specified component type.

The second method call is defined in the java.util.List interface.

public Object[] toArray(Object[] a)


The method returns an array containing all of the elements in the List in the correct order where the runtime type of the returned array is that of the specified array.

Coupling the two calls above can allow you to quickly transform your ArrayList of objects into an object array of the specified object's component type.

Have a look at the sample code below for an ArrayList of strings to be converted into a String [].

ArrayList theStrings = new ArrayList();
theStrings.add("Hello");
theStrings.add("Aloha");
theStrings.add("Bonjour");

//Return String [].
String [] theStringArray = 
(String[])theStrings.toArray(
(String[])Array.newInstance(java.lang.String.class, theStrings.size())
);


With one line, you'll be able to turn your list of Java objects into an array of objects of the object's component type.

Questions, just comment and I'll be sure to get back to you.

Monday, December 29, 2008

javax.imageio.ImageIO and degrading JPEG

JPEG is a lossy compression encoding algorithm. Each time you encode a JPEG image, you lose image quality because of the cosine coefficients dropped in order to perform the compression.

Using the read and write methods from javax.imageio.ImageIO.read and javax.imageio.ImageIO.write method will amplify this quality loss, because of varying detail levels during the read and write. You may be reading a jpeg and 90% detail and writing it with 50% detail.

Avoid jpeg interpretation of image files unless image processing is required.

Thursday, December 4, 2008

Filtering IP traffic using a Java Filter - RemoteAddrFilter

I recently wrote a Java Filter, which is a replica of the org.apache.catalina.valves.RemoteAddrValve implementation. It performs filtering based on comparing the requestors remote IP address against a set of regular expressions, configured in the Filter's initialization parameters. If an IP addresses is to be rejected it is rejected with a Forbidden HTTP response.

This provided useful because Valves are attached to the servlet container while a Filter can be mapped to any url pattern at the application level rather than at the container level.

GET THE CODE
Here is a link to the filter code. (RemoteAddrFilter.java)

This filter is configured by setting the allow and/or deny properties to a comma-delimited list of regular expressions to which the requestors remote address will be compared. Evaluation proceeds as follows:
  • The filter initializes reading the allow and/or deny properties and converting them to a comma-delimited list of regular expressions to which the requester's remote address will be compared.
  • If there are any deny expressions configured, the property will be compared to each such expression. If a match is found, this request will be rejected with a "Forbidden" HTTP response.
  • If there are any allow expressions configured, the property will be compared to each such expression. If a match is found, this request will be allowed to pass through to the next Filter in the current pipeline.
  • If one or more deny expressions was specified but no allow expressions, allow this request to pass through (because none of the deny expressions matched it).
  • The request will be rejected with a "Forbidden" HTTP response.
The filter is configured the same way all Java Filter's. This filter takes two initial parameters. The value of those properties should be set to a comma-delimited list of regular expressions to which the requestors remote address will be compared.

CONFIGURE
The filter is added to your context via the web.xml. Below is an example configuration.

<filter>
   <filter-name>RemoteAddrFilter</filter-name>
   <filter-class>RemoteAddrFilter<filter-class>
   <init-param>
      <param-name>allow</param-name>
      <param-value>192.168.1.*</param-value>
   </init-param>
   <init-param>
      <param-name>deny</param-name>
      <param-value>163.122.111.*</param-value>
   </init-param>
</filter>


DEPENDENCIES
There is a dependency with Jakarta Regexp.