Printable Version Printable Version

Protecting web application from Path Traversal Attack

Jan 4th, 2010 | By admin | Category: Web Technologies

Path Traversal Attack , What it is ?

A Path Traversal attack targets the files and directories which are saved outside the root folder. An attacker aims for a files path stored in the web server. An attacker use the combination of dot-dot-slash(../) to browse to arbitrary directories and files. The dot-dot-slash sequence helps an attacker to move up in any directory location. The attacker not only can access any arbitrary files/directories from your web server , it is possible to upload some malicious files to some location in your web server , if the proper care is not taken.

The attack can be made in several different ways. An attacker might not use the dot-dot-slash patter directly in the url , rather can use the Encoding and double encoding value of dot(.) and slash(/).
..%2f represents ../
..%255c represents ..\
%2e%2e\ represents ..\ and so on.
Hence an attacker can use the following type of urls to play with your web server files and directories,
http://web_site.com/toGetFiles?file=../../../../dir/file
http://web_site.com/toGetFiles?file=…%255cdir/file
depending on your operating systems.

How to protect the web application from this attack ?

Anything from an web application can be accessed using a request to the application. Hence we need a strict sanity check for all the possible dot-dot-slash patterns on each request coming to the web application.
The check should be performed well before a request reaches in a state to have response for it. It means , a web application pre-filter should be written to achieve this.

You need to do modification in the web.xml of your web application. Add the following tag in your web application :

Listing 1 : Add filter tag to web.xml file

<filter>
    <filter-name>PTA</filter-name>
        <display-name>PTA</display-name>
        <description>This is a Pre-filter for PTA Prevention</description>
    <filter-class>com.etechGuide.fw.filter.PathTraversalFilter</filter-class>
</filter>
<filter-mapping>
         <filter-name> PTA</filter-name>
         <url-pattern>/*</url-pattern>
</filter-mapping>

As we are looking for filtering all the request and we would like to pass all the request through the filter. Hence we will be writing a Request Wrapper to code our filter logic. Look at the following filter definition.

Listing 2 : The PathTraversalFilter code

public class PathTraversalFilter implements Filter {
	private FilterConfig filterConfig;
	public void init(FilterConfig filterConfig)
                              throws ServletException {
		this.filterConfig = filterConfig;
	}

	public void destroy() {
		this.filterConfig = null;
	}

	public void doFilter(ServletRequest request,
                 ServletResponse response,FilterChain chain)
                           throws IOException, ServletException {

		chain.doFilter(new RequestWrapper((HttpServletRequest) request),
				response);

	}
}

At the line number 16 we wrap the request to filter out all the malicious attacks for Path Traversals. have a look at the RequestWrapper.java file where the actual filtering bypass takes place.

Listing 3 : The RequestWrapper code

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public final class RequestWrapper extends HttpServletRequestWrapper {

	public RequestWrapper(HttpServletRequest servletRequest) {
		super(servletRequest);
	}

	public String[] getParameterValues(String parameter) {

	  String[] values = super.getParameterValues(parameter);
	  if (values==null)  {
                  return null;
          }
	  int count = values.length;
	  String[] encodedValues = new String[count];
	  for (int i = 0; i < count; i++) {
                 encodedValues[i] = cleanPTA(values[i]);
	   }
	  return encodedValues;
	}

	public String getParameter(String parameter) {
		  String value = super.getParameter(parameter);
		  if (value == null) {
		         return null;
                  }
		  return cleanPTA(value);
	}

	public String getHeader(String name) {
	    String value = super.getHeader(name);
	    if (value == null)
	        return null;
	    return cleanPTA(value);

	}

	private String cleanPTA(String value) {
		// Bypassing all possible dot-dot-slash
                value = value.replaceAll("%2e", "");
		value = value.replaceAll("%2f", "");
		value = value.replaceAll("%5c", "");
		value = value.replaceAll("%25u002e", "");
		value = value.replaceAll("%25u002f", "");
		value = value.replaceAll("%25u005c", "");
		value = value.replaceAll("%c0", "");
		value = value.replaceAll("%ae", "");
		value = value.replaceAll("%af", "");
		value = value.replaceAll("%c1", "");
		value = value.replaceAll("%9c", "");
		value = value.replaceAll("%e0", "");
		value = value.replaceAll("%80", "");
		value = value.replaceAll("%f0", "");
		value = value.replaceAll("%81", "");
		value = value.replaceAll("%f8", "");
		value = value.replaceAll("%fc", "");
		value = value.replaceAll("%25uff3C", "");
		value = value.replaceAll("%25u002E", "");
		value = value.replaceAll("%5C", "");
		value = value.replaceAll("%2F", "");
		value = value.replaceAll("%25uff0E", "");
		value = value.replaceAll("%25uff0F", "");
		value = value.replaceAll("%25ufe68", "");
		value = value.replaceAll("%00", "");
		value = value.replaceAll("%2A", "");
		value = value.replaceAll("%25", "");
		value = value.replaceAll("\\|", ""); 

                /* File.separator is different from one OS to another.
                    Hence the additional check is done below
                */
		String sFileName = value
				.substring(value.lastIndexOf(File.separator) + 1);

		if (sFileName.indexOf("..") >= 0) {
			sFileName = value.substring(value.lastIndexOf("..") + 2);
		}
		if (sFileName.indexOf("\\") >= 0) {
			sFileName = value.substring(value.lastIndexOf("\\") + 1);
		} if (sFileName.indexOf("/") >= 0) {
			sFileName = value.substring(value.lastIndexOf("/") + 1);
		}
		return sFileName;
	}
}

cleanPTA(String value) method of above class does all the bypassing. This method is open for modification to the reader of this post. The logic can be changed as per the need but the basic by passing is all about what is done above.

Once a request reaches your web application , it has to go through the filter. The filter uses a wrapper on each request and filter out all the malicious attacks.

  • Share/Save/Bookmark

Leave Comment