Posts Tagged ‘xss

27
Mar
11

Preventing XSS using commons validator

This page describes the process of validating html submitted form to prevent a Cross Site Scripting attack using commons validator.

Background

Adding input validation to your application adds an extra layer of security however its only the second best method to protect against cross site scripting attacks.[1]

The best method is to is to encode the output before displaying it to the user.[2]

Regardless, adding more layers of security doesn’t hurt.

Approach

The approach taken here is to white-list characters that are allowed to be entered by creating a custom validator. Developers can use “mask” rule however this

  1. clutters up the validator.xml file
  2. could possibly interfere with a a field’s existing mask rule

Requirements

  1. Successful completion of my previous post

Procedure

We will be re-using the project created in my previous post. Or you can skip the implementation and just follow along below.

Create a Custom Validator

The following class extends the FieldChecks class provided by the struts framework. The extra method is based on the mask method of the parent class. The only difference is that the mask pattern is hard coded into the implementation of the method.

src/main/java/com/test/InfoSecurityChecks.java

package com.test;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.ValidatorUtil;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.validator.FieldChecks;
import org.apache.struts.validator.Resources;

public class InfoSecurityChecks extends FieldChecks {
	private static final long serialVersionUID = 1L;
	private static final Log log = LogFactory.getLog(InfoSecurityChecks.class);

	public InfoSecurityChecks() {
		super();
	}

	/**
	 * The code for this method was taken from the mask method of the parent
	 * class. The mask regular expression has been hard coded to only allow
	 * characters that are approved.
	 *
	 */
	public static boolean validateInfoSec(Object bean, ValidatorAction va,
			Field field, ActionErrors errors, HttpServletRequest request) {
		System.out.println("infosec validator ran");
		// The following is allowed
		// alpha numeric characters and space
		// special characters except < > ( )
		String mask = "^[A-Za-z0-9!\"\\\\#$%&'*+,/:;=\\.?@_\\`{\\|}\\~\\-\\^ ]*$";
		String value = null;
		if (isString(bean))
			value = (String) bean;
		else {
			value = ValidatorUtil.getValueAsString(bean, field.getProperty());
		}
		System.out.println(value);
		try {
			if ((!(GenericValidator.isBlankOrNull(value)))
					&& (!(GenericValidator.matchRegexp(value, mask)))) {
				errors.add(field.getKey(), Resources.getActionError(request,
						va, field));
				System.out.println("did not match returning false.");
				return false;
			}
			return true;
		} catch (Exception e) {
			 log.error(e.getMessage(), e);
		}
		return true;
	}
}

Modify the Validator Rules

Modify the validator-rules.xml and add an additional “validator” section towards the end.

src/main/webapp/WEB-INF/validator-rules.xml

      <validator name="infosec"
            classname="com.test.InfoSecurityChecks"
               method="validateInfoSec"
         methodParams="java.lang.Object,
                       org.apache.commons.validator.ValidatorAction,
                       org.apache.commons.validator.Field,
                       org.apache.struts.action.ActionErrors,
                       javax.servlet.http.HttpServletRequest"
                  msg="errors.infosec">
      </validator>

Add the following new line to the application.properties

src/main/resources/application.properties

errors.infosec=The input contains invalid characters.

Modify the validation.xml and add “infosec” to the end of the depends attribute of the “lastName” attribute of the “userInformation” form.

src/main/webapp/WEB-INF/validation.xml

    <field property="lastName" depends="required,infosec">
        <arg key="userInformation.lastName" />
    </field>

Test the application

Return to the project top level directory and execute the following command to start the jetty servlet engine.

mvn clean compile jetty:run

Navigate to the following URL:
http://localhost:8080/

An extJS form should display allowing you to enter values. Click submit and an Ajax form submission will be made to the Struts Action. Any validation failures will show next to the component.

Try entering a <script>alert(‘test xss’);</script> in the last name field.

System should display a validation failure message indicating that there are invalid characters in the input.

References

[1] XSS (Cross Site Scripting) Prevention Cheat Sheet
[2] http://www.ibm.com/developerworks/web/library/wa-secxss/




Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 75 other followers

May 2017
S M T W T F S
« Mar    
 123456
78910111213
14151617181920
21222324252627
28293031  

Blog Stats

  • 813,774 hits