Adding anti XSS NIHVIVO-3379

This commit is contained in:
briancaruso 2011-12-05 22:08:04 +00:00
parent dac5d91478
commit 36a99486f6
12 changed files with 400 additions and 41 deletions

View file

@ -38,6 +38,7 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.SelectListGeneratorV
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.FieldVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.FieldVTwo;
import edu.cornell.mannlib.vitro.webapp.web.MiscWebUtils; import edu.cornell.mannlib.vitro.webapp.web.MiscWebUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.DefaultAddMissingIndividualFormModelPreprocessor; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.DefaultAddMissingIndividualFormModelPreprocessor;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation;
/** /**
* Generates the edit configuration for a default property form. * Generates the edit configuration for a default property form.
@ -116,6 +117,9 @@ public class DefaultAddMissingIndividualFormGenerator implements EditConfigurati
//default obj property form.populateTemplate or some such method //default obj property form.populateTemplate or some such method
//Select from existing also set within template itself //Select from existing also set within template itself
setTemplate(editConfiguration, vreq); setTemplate(editConfiguration, vreq);
editConfiguration.addValidator(new AntiXssValidation());
//edit key now set in the edit request dispatch controller //edit key now set in the edit request dispatch controller
return editConfiguration; return editConfiguration;
} }

View file

@ -23,6 +23,7 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUti
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.FieldVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.FieldVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.DefaultDataPropEmptyField; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.DefaultDataPropEmptyField;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash;
public class DefaultDataPropertyFormGenerator extends BaseEditConfigurationGenerator implements EditConfigurationGenerator { public class DefaultDataPropertyFormGenerator extends BaseEditConfigurationGenerator implements EditConfigurationGenerator {
@ -82,6 +83,8 @@ public class DefaultDataPropertyFormGenerator extends BaseEditConfigurationGener
editConfiguration.addField( literalField ); editConfiguration.addField( literalField );
editConfiguration.addValidator(new AntiXssValidation());
// An empty field on an update gets special treatment // An empty field on an update gets special treatment
if( update ) { if( update ) {
// on update, allow an empty field and deal with it in DefaultDataPropEmptyField // on update, allow an empty field and deal with it in DefaultDataPropEmptyField

View file

@ -26,6 +26,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.FieldVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.FieldVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation;
import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch; import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch;
/** /**
@ -110,6 +111,9 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
//default obj property form.populateTemplate or some such method //default obj property form.populateTemplate or some such method
//Select from existing also set within template itself //Select from existing also set within template itself
setTemplate(editConfiguration, vreq); setTemplate(editConfiguration, vreq);
editConfiguration.addValidator(new AntiXssValidation());
//Set edit key //Set edit key
setEditKey(editConfiguration, vreq); setEditKey(editConfiguration, vreq);
//Adding additional data, specifically edit mode //Adding additional data, specifically edit mode

View file

@ -34,6 +34,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditN3GeneratorVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditN3GeneratorVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.SelectListGeneratorVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.SelectListGeneratorVTwo;
@ -96,6 +97,7 @@ public class NewIndividualFormGenerator implements EditConfigurationGenerator {
prepareForUpdate(vreq, session, editConfiguration); prepareForUpdate(vreq, session, editConfiguration);
editConfiguration.addValidator(new AntiXssValidation());
//Form title and submit label now moved to edit configuration template //Form title and submit label now moved to edit configuration template
//TODO: check if edit configuration template correct place to set those or whether //TODO: check if edit configuration template correct place to set those or whether

View file

@ -31,6 +31,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators.AntiXssValidation;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHash;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditN3GeneratorVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditN3GeneratorVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.SelectListGeneratorVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.SelectListGeneratorVTwo;
@ -100,6 +101,8 @@ public class RDFSLabelGenerator implements EditConfigurationGenerator {
//placing in session depends on having edit key which is handled in edit request dispatch controller //placing in session depends on having edit key which is handled in edit request dispatch controller
prepareForUpdate(vreq, session, editConfiguration); prepareForUpdate(vreq, session, editConfiguration);
editConfiguration.addValidator(new AntiXssValidation());
//Form title and submit label now moved to edit configuration template //Form title and submit label now moved to edit configuration template
setTemplate(editConfiguration, vreq); setTemplate(editConfiguration, vreq);
//Set edit key //Set edit key

View file

@ -0,0 +1,192 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.owasp.validator.html.AntiSamy;
import org.owasp.validator.html.CleanResults;
import org.owasp.validator.html.PolicyException;
import org.owasp.validator.html.ScanException;
import com.hp.hpl.jena.rdf.model.Literal;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.MultiValueEditSubmission;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.N3ValidatorVTwo;
import edu.cornell.mannlib.vitro.webapp.web.AntiScript;
/**
* Check if the submitted text has potential XSS problems.
* Error messages from this validator always start with XSS_ERROR_MESSAGE
*
* @author bdc34
*/
public class AntiXssValidation implements N3ValidatorVTwo{
List<String> fieldNamesToValidate;
/**
* Validate all fields on submission.
*/
public AntiXssValidation(){
this.fieldNamesToValidate = ALL_FIELDS;
}
/**
* Validate only fields specified in fieldNamesToValidate.
*/
public AntiXssValidation(List<String> fieldNamesToValidate){
this.fieldNamesToValidate = fieldNamesToValidate;
}
@Override
public Map<String, String> validate(EditConfigurationVTwo editConfig,
MultiValueEditSubmission editSub) {
if( editSub == null ) {
return null;
}
Map<String,String>varToErrMsg = new HashMap<String,String>();
if( fieldNamesToValidate == null ){
if( editSub.getLiteralsFromForm() != null ){
for( String name : editSub.getLiteralsFromForm().keySet()){
varToErrMsg.putAll( checkSubmissionForField( name, editSub));
}
}
if( editSub.getUrisFromForm() != null ){
for( String name : editSub.getUrisFromForm().keySet()){
varToErrMsg.putAll( checkSubmissionForField( name, editSub));
}
}
}else{
for( String fieldName : fieldNamesToValidate){
varToErrMsg.putAll( checkSubmissionForField(fieldName, editSub));
}
}
if( varToErrMsg.isEmpty() )
return null;
else
return varToErrMsg;
}
/**
* Check for XSS for a single field. Returns NO_ERROR if there
* are no errors so it can be added to a map with putAll()
*/
protected Map<String,String> checkSubmissionForField(
String fieldName, MultiValueEditSubmission editSub){
if( fieldName == null || fieldName.isEmpty() || editSub == null)
return NO_ERROR;
if( editSub.getLiteralsFromForm() != null &&
editSub.getLiteralsFromForm().containsKey(fieldName) ){
String error = null;
try {
error = literalHasXSS( editSub.getLiteralsFromForm().get(fieldName) );
} catch (ScanException e) {
error = e.getMessage();
} catch (PolicyException e) {
error = e.getMessage();
}
if( error != null ){
return Collections.singletonMap(fieldName, XSS_ERROR_MESSAGE + " " + error);
}else{
return NO_ERROR;
}
} else if (editSub.getUrisFromForm() != null &&
editSub.getUrisFromForm().containsKey(fieldName)){
String error;
try {
error = uriHasXSS( editSub.getUrisFromForm().get(fieldName));
} catch (ScanException e) {
error = e.getMessage();
} catch (PolicyException e) {
error = e.getMessage();
}
if( error != null ){
return Collections.singletonMap(fieldName, XSS_ERROR_MESSAGE + " " + error);
}else{
return NO_ERROR;
}
}else{
//field wasn't in submission
return NO_ERROR;
}
}
/**
* Check if a list of URIs has any XSS problems.
* Return null if there are none and return an error message if there are problems.
*/
private String uriHasXSS(List<String> uriList) throws ScanException, PolicyException {
AntiSamy antiSamy = AntiScript.getAntiSamyScanner();
ArrayList errorMsgs = new ArrayList();
for( String uri : uriList ){
CleanResults cr = antiSamy.scan( uri );
errorMsgs.addAll( cr.getErrorMessages() );
}
if( errorMsgs.isEmpty() ){
return null;
}else{
return StringUtils.join(errorMsgs, ", ");
}
}
/**
* Check if a List of Literals has any XSS problems.
* Return null if there are none and return an error message if there are problems.
*/
private String literalHasXSS(List<Literal> list) throws ScanException, PolicyException {
AntiSamy antiSamy = AntiScript.getAntiSamyScanner();
ArrayList errorMsgs = new ArrayList();
for( Literal literal : list ){
CleanResults cr = antiSamy.scan(literal.getLexicalForm());
errorMsgs.addAll( cr.getErrorMessages() );
String dt = literal.getDatatypeURI();
if( dt != null ){
cr = antiSamy.scan( dt );
errorMsgs.addAll( cr.getErrorMessages() );
}
String lang = literal.getLanguage() ;
if( lang != null ){
cr = antiSamy.scan( lang );
errorMsgs.addAll( cr.getErrorMessages() );
}
}
if( errorMsgs.isEmpty() )
return null;
else
return StringUtils.join(errorMsgs,", ");
}
/**
* All error messages will start with this string.
*/
public static String XSS_ERROR_MESSAGE = "Field contains unacceptable markup";
private static final Map<String,String>NO_ERROR = Collections.emptyMap();
//value indicates that all fields should be validated.
private static final List<String> ALL_FIELDS = null;
}

View file

@ -29,9 +29,7 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditSubmission; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditSubmission;
/** /**
* User: bdc34 *
* Date: Jan 24, 2008
* Time: 1:55:39 PM
*/ */
public class BasicValidation { public class BasicValidation {
@ -271,7 +269,7 @@ public class BasicValidation {
static final List<String> basicValidations; static final List<String> basicValidations;
static{ static{
basicValidations = Arrays.asList( basicValidations = Arrays.asList(
"nonempty","isDate","dateNotPast","httpUrl" ); "nonempty","isDate","dateNotPast","httpUrl" ,"anti-xss");
} }
private Log log = LogFactory.getLog(BasicValidation.class); private Log log = LogFactory.getLog(BasicValidation.class);

View file

@ -372,6 +372,7 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
if(EditConfigurationVTwoGenerator == null){ if(EditConfigurationVTwoGenerator == null){
throw new Error("Could not find EditConfigurationVTwoGenerator " + editConfGeneratorName); throw new Error("Could not find EditConfigurationVTwoGenerator " + editConfGeneratorName);
} else { } else {
log.debug("Created EditConfiguration using " + editConfGeneratorName);
return EditConfigurationVTwoGenerator.getEditConfiguration(vreq, session); return EditConfigurationVTwoGenerator.getEditConfiguration(vreq, session);
} }

View file

@ -24,10 +24,11 @@ public class AntiScript {
private static final Log log = LogFactory.getLog(AntiScript.class); private static final Log log = LogFactory.getLog(AntiScript.class);
private static Policy policy;
private static final String ANTI_SCRIPT_POLICY = "ANTI_SCRIPT_POLICY"; private static AntiSamy antiSamy;
private static final String ANTI_SCRIPT_SCANNER = "ANTI_SCRIPT_SCANNER"; private static final String ANTI_SCRIPT_SCANNER = "ANTI_SCRIPT_SCANNER";
private static String ANTI_SCRIPT_POLICY_FILE = "/WEB-INF/classes/edu/cornell/mannlib/vitro/webapp/web/antisamy-vitro-1.4.4.xml"; private static String ANTI_SCRIPT_POLICY_FILE = "/edu/cornell/mannlib/vitro/webapp/web/antisamy-vitro-1.4.4.xml";
/** /**
* This will attempt to return HTML that has been cleaned up according * This will attempt to return HTML that has been cleaned up according
@ -41,11 +42,11 @@ public class AntiScript {
* *
* This will return null if dirtyInput is null. * This will return null if dirtyInput is null.
*/ */
public static String cleanText( String dirtyInput, ServletContext context){ public static String cleanText( String dirtyInput ){
if( dirtyInput == null ) if( dirtyInput == null )
return null; return null;
AntiSamy as = getHTMLScanner(context); AntiSamy as = getAntiSamyScanner();
CleanResults cr; CleanResults cr;
try { try {
cr = as.scan(dirtyInput); cr = as.scan(dirtyInput);
@ -61,62 +62,59 @@ public class AntiScript {
/** /**
* Method to clean a URL or URI. * Method to clean a URL or URI.
*/ */
public static String cleanURI( String dirtyInput, ServletContext context){ public static String cleanURI( String dirtyInput ){
return cleanText(dirtyInput,context); return cleanText(dirtyInput);
} }
/** /**
* Method to clean all of the values in a map where the values are of * Method to clean all of the values in a map where the values are of
* type String. * type String.
*/ */
public static <T> void cleanMapValues( Map<T,String> map, ServletContext context){ public static <T> void cleanMapValues( Map<T,String> map ){
for( T key : map.keySet() ){ for( T key : map.keySet() ){
map.put(key, cleanText(map.get(key), context)); map.put(key, cleanText(map.get(key)) );
} }
} }
/** /**
* Try to get the policy from the servlet context, if none exists, create a new one. * Try to get the static policy, if none exists, create a new one.
* This is a anti-script policy for use with OWASP AntiSamy, not a vivo auth Policy. * This is a anti-script policy for use with OWASP AntiSamy, not a vivo auth Policy.
* Returns null if no policy can be created. * Returns null if no policy can be created.
*/ */
protected static Policy getAntiScriptPolicy(ServletContext context){ protected static Policy getAntiScriptPolicy( ){
Object obj = context.getAttribute( ANTI_SCRIPT_POLICY );
if( obj == null ){ if( policy == null ){
Policy newPolicy; Policy newPolicy;
try { try {
String url = ANTI_SCRIPT_POLICY_FILE; String url = ANTI_SCRIPT_POLICY_FILE;
URL policyFile= context.getResource( url ); URL policyFile= AntiScript.class.getResource( url );
newPolicy = Policy.getInstance( policyFile ); newPolicy = Policy.getInstance( policyFile );
context.setAttribute(ANTI_SCRIPT_POLICY, newPolicy);
log.debug("anti-script policy loaded successfully"); log.debug("anti-script policy loaded successfully");
return newPolicy; policy = newPolicy;
} catch (PolicyException e) { } catch (PolicyException e) {
log.error("Anti-Script policy not setup.", e); log.error("Anti-Script policy not setup.", e);
return null; return null;
} catch (MalformedURLException e) { } catch (Throwable e) {
log.error("Anti-Script policy not setup.", e); log.error("Anti-Script policy not setup.", e);
return null; return null;
} }
} else { }
return (Policy)obj;
} return policy;
} }
/** /**
* Try to get an AntiSamy HTML scanner object that is sharied across * Try to get a static AntiSamy HTML scanner object that is shared the
* the whole web application. This may return a scanner with a null * whole application. This may return a scanner with a null
* policy if the policy is not setup correctly. * policy if the policy is not setup correctly.
*/ */
protected static AntiSamy getHTMLScanner( ServletContext context){ public static AntiSamy getAntiSamyScanner( ){
Object obj = context.getAttribute( ANTI_SCRIPT_SCANNER );
if( obj == null ){ if( antiSamy == null ){
AntiSamy scanner = new AntiSamy( getAntiScriptPolicy(context)); antiSamy = new AntiSamy( getAntiScriptPolicy() );
context.setAttribute( ANTI_SCRIPT_SCANNER , scanner); log.debug("anti-script scanner loaded successfully");
log.debug("anti-script scanner loaded successfully"); }
return scanner;
}else{ return antiSamy;
return (AntiSamy) obj;
}
} }
} }

View file

@ -45,6 +45,9 @@ public abstract class BaseTemplateModel {
* that shouldn't be in a URI. * that shouldn't be in a URI.
*/ */
protected String cleanURIForDisplay( String dirty ){ protected String cleanURIForDisplay( String dirty ){
if( dirty == null )
return null;
StringBuilder clean = new StringBuilder(dirty.length()); StringBuilder clean = new StringBuilder(dirty.length());
for (char ch: dirty.toCharArray()) { for (char ch: dirty.toCharArray()) {
if (URI_CHARACTERS.indexOf(ch) != -1) { if (URI_CHARACTERS.indexOf(ch) != -1) {
@ -59,7 +62,7 @@ public abstract class BaseTemplateModel {
* Currently this only checks for XSS exploits. * Currently this only checks for XSS exploits.
*/ */
protected String cleanTextForDisplay( String dirty){ protected String cleanTextForDisplay( String dirty){
return AntiScript.cleanText(dirty, getServletContext()); return AntiScript.cleanText(dirty);
} }
/** /**
@ -67,7 +70,7 @@ public abstract class BaseTemplateModel {
* a map. Map may be modified. * a map. Map may be modified.
*/ */
protected <T> void cleanMapValuesForDisplay( Map<T,String> map){ protected <T> void cleanMapValuesForDisplay( Map<T,String> map){
AntiScript.cleanMapValues(map, getServletContext()); AntiScript.cleanMapValues(map);
} }
protected static ServletContext getServletContext() { protected static ServletContext getServletContext() {

View file

@ -0,0 +1,129 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.FieldVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.MultiValueEditSubmission;
public class AntiXssValidationTest {
@Test
public void testLiteral( ){
//test all fields constructor
AntiXssValidation validator =new AntiXssValidation();
EditConfigurationVTwo eConf = new EditConfigurationVTwo();
eConf.setEditKey("fakeEditKey");
eConf.addField( new FieldVTwo().setName("X") );
eConf.setLiteralsOnForm( Arrays.asList("X") );
Map<String, String[]> params = new HashMap<String,String[]>();
String[] vals= { "some sort of string" };
params.put("X", vals);
MultiValueEditSubmission mvEditSub =
new MultiValueEditSubmission(params,eConf);
Map<String, String> res = validator.validate(eConf, mvEditSub);
Assert.assertEquals(null, res);
}
@Test
public void testAllURI( ){
//test all fields constructor
AntiXssValidation validator =new AntiXssValidation();
EditConfigurationVTwo eConf = new EditConfigurationVTwo();
eConf.setEditKey("fakeEditKey");
eConf.setUrisOnform( Arrays.asList("X","Y","Z"));
Map<String, String[]> params = new HashMap<String,String[]>();
String[] strings0 = {"no problem 0"};
params.put("X", strings0 );
String[] strings1 = {"no problem 1"};
params.put("Y", strings1 );
String[] strings2 = {"no problem 2"};
params.put("Z", strings2 );
MultiValueEditSubmission mvEditSub =
new MultiValueEditSubmission(params,eConf);
Map<String, String> res = validator.validate(eConf, mvEditSub);
Assert.assertNull( res );
}
protected Map<String, String> testURI( String ... strings){
AntiXssValidation validator =
new AntiXssValidation(Arrays.asList("X"));
EditConfigurationVTwo eConf = new EditConfigurationVTwo();
eConf.setEditKey("fakeEditKey");
eConf.setUrisOnform( Arrays.asList("X"));
Map<String, String[]> params = new HashMap<String,String[]>();
params.put("X", strings );
MultiValueEditSubmission mvEditSub =
new MultiValueEditSubmission(params,eConf);
return validator.validate(eConf, mvEditSub);
}
@Test
public void testURIValidation(){
Map<String, String> result = testURI("http://this.should.be.fine.com/xyz#lskd?junk=a&bkeck=%23");
Assert.assertNull(result);
}
@Test
public void testURIValidationWithScriptTagLevel1(){
Map<String, String> result = null;
result = testURI("http:<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>//bad.news.com");
Assert.assertNotNull(result);
result = testURI("http:<IMG SRC=JaVaScRiPt:alert('XSS')>//bad.news.com");
Assert.assertNotNull(result);
result = testURI("http:<IMG SRC=javascript:alert('XSS')>//bad.news.com");
Assert.assertNotNull(result);
result = testURI("http:<IMG SRC=javascript:alert(&quot;XSS&quot;)>//bad.news.com");
Assert.assertNotNull(result);
result = testURI("http:<IMG SRC=\"jav\tascript:alert('XSS');\">//bad.news.com");
Assert.assertNotNull(result);
}
@Test
public void testURIValidationWithScriptTagLevel2(){
Map<String, String> result = null;
result = testURI("http:<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>//bad.news.com");
Assert.assertNotNull(result);
result = testURI("http:<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>//bad.news.com");
Assert.assertNotNull(result);
result = testURI("http:<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>//bad.news.com");
Assert.assertNotNull(result);
result = testURI("http:<<SCRIPT>alert(\"XSS\");//<</SCRIPT>//bad.news.com");
Assert.assertNotNull(result);
result = testURI("http:<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>//bad.news.com");
Assert.assertNotNull(result);
result = testURI("http:<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>//bad.news.com");
Assert.assertNotNull(result);
}
}

View file

@ -0,0 +1,22 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.web.templatemodels;
import org.junit.Test;
public class BaseTemplateModelTest {
private static String value;
@Test
public void testCleanURIofNull(){
BaseTemplateModel btm = new BaseTemplateModel(){};
//should not throw NPE
value = btm.cleanURIForDisplay( null );
//should not throw NPE
value = btm.cleanTextForDisplay( null );
}
}