diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultAddMissingIndividualFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultAddMissingIndividualFormGenerator.java index 52a863212..54dc60d40 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultAddMissingIndividualFormGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultAddMissingIndividualFormGenerator.java @@ -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.web.MiscWebUtils; 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. @@ -116,6 +117,9 @@ public class DefaultAddMissingIndividualFormGenerator implements EditConfigurati //default obj property form.populateTemplate or some such method //Select from existing also set within template itself setTemplate(editConfiguration, vreq); + + editConfiguration.addValidator(new AntiXssValidation()); + //edit key now set in the edit request dispatch controller return editConfiguration; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultDataPropertyFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultDataPropertyFormGenerator.java index b9513ae8a..f1ad939fc 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultDataPropertyFormGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultDataPropertyFormGenerator.java @@ -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.FieldVTwo; 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; public class DefaultDataPropertyFormGenerator extends BaseEditConfigurationGenerator implements EditConfigurationGenerator { @@ -82,6 +83,8 @@ public class DefaultDataPropertyFormGenerator extends BaseEditConfigurationGener editConfiguration.addField( literalField ); + editConfiguration.addValidator(new AntiXssValidation()); + // An empty field on an update gets special treatment if( update ) { // on update, allow an empty field and deal with it in DefaultDataPropEmptyField diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java index c178b8fc7..20cce39f7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java @@ -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.EditConfigurationVTwo; 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; /** @@ -110,6 +111,9 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene //default obj property form.populateTemplate or some such method //Select from existing also set within template itself setTemplate(editConfiguration, vreq); + + editConfiguration.addValidator(new AntiXssValidation()); + //Set edit key setEditKey(editConfiguration, vreq); //Adding additional data, specifically edit mode diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/NewIndividualFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/NewIndividualFormGenerator.java index 5dae44677..19b31cc46 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/NewIndividualFormGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/NewIndividualFormGenerator.java @@ -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.edit.n3editing.VTwo.EditConfigurationVTwo; 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.VTwo.EditN3GeneratorVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.SelectListGeneratorVTwo; @@ -96,6 +97,7 @@ public class NewIndividualFormGenerator implements EditConfigurationGenerator { prepareForUpdate(vreq, session, editConfiguration); + editConfiguration.addValidator(new AntiXssValidation()); //Form title and submit label now moved to edit configuration template //TODO: check if edit configuration template correct place to set those or whether diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/RDFSLabelGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/RDFSLabelGenerator.java index 4330e0614..591ca667e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/RDFSLabelGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/RDFSLabelGenerator.java @@ -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.edit.n3editing.VTwo.EditConfigurationVTwo; 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.VTwo.EditN3GeneratorVTwo; 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 prepareForUpdate(vreq, session, editConfiguration); + editConfiguration.addValidator(new AntiXssValidation()); + //Form title and submit label now moved to edit configuration template setTemplate(editConfiguration, vreq); //Set edit key diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/validators/AntiXssValidation.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/validators/AntiXssValidation.java new file mode 100644 index 000000000..c8f436ce9 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/validators/AntiXssValidation.java @@ -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 fieldNamesToValidate; + + + /** + * Validate all fields on submission. + */ + public AntiXssValidation(){ + this.fieldNamesToValidate = ALL_FIELDS; + } + + /** + * Validate only fields specified in fieldNamesToValidate. + */ + public AntiXssValidation(List fieldNamesToValidate){ + this.fieldNamesToValidate = fieldNamesToValidate; + } + + @Override + public Map validate(EditConfigurationVTwo editConfig, + MultiValueEditSubmission editSub) { + + if( editSub == null ) { + return null; + } + + MapvarToErrMsg = new HashMap(); + 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 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 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 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 MapNO_ERROR = Collections.emptyMap(); + + //value indicates that all fields should be validated. + private static final List ALL_FIELDS = null; +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/validators/BasicValidation.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/validators/BasicValidation.java index e2c30274b..623a05f79 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/validators/BasicValidation.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/validators/BasicValidation.java @@ -29,9 +29,7 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditSubmission; /** - * User: bdc34 - * Date: Jan 24, 2008 - * Time: 1:55:39 PM + * */ public class BasicValidation { @@ -271,7 +269,7 @@ public class BasicValidation { static final List basicValidations; static{ basicValidations = Arrays.asList( - "nonempty","isDate","dateNotPast","httpUrl" ); + "nonempty","isDate","dateNotPast","httpUrl" ,"anti-xss"); } private Log log = LogFactory.getLog(BasicValidation.class); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java index 8e1a9f64a..978833fb8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java @@ -372,6 +372,7 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { if(EditConfigurationVTwoGenerator == null){ throw new Error("Could not find EditConfigurationVTwoGenerator " + editConfGeneratorName); } else { + log.debug("Created EditConfiguration using " + editConfGeneratorName); return EditConfigurationVTwoGenerator.getEditConfiguration(vreq, session); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/AntiScript.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/AntiScript.java index 517965fb7..39aad1985 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/AntiScript.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/AntiScript.java @@ -24,10 +24,11 @@ public class AntiScript { private static final Log log = LogFactory.getLog(AntiScript.class); - - private static final String ANTI_SCRIPT_POLICY = "ANTI_SCRIPT_POLICY"; + private static Policy policy; + private static AntiSamy antiSamy; + 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 @@ -41,11 +42,11 @@ public class AntiScript { * * 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 ) return null; - AntiSamy as = getHTMLScanner(context); + AntiSamy as = getAntiSamyScanner(); CleanResults cr; try { cr = as.scan(dirtyInput); @@ -61,62 +62,59 @@ public class AntiScript { /** * Method to clean a URL or URI. */ - public static String cleanURI( String dirtyInput, ServletContext context){ - return cleanText(dirtyInput,context); + public static String cleanURI( String dirtyInput ){ + return cleanText(dirtyInput); } /** * Method to clean all of the values in a map where the values are of * type String. */ - public static void cleanMapValues( Map map, ServletContext context){ + public static void cleanMapValues( Map map ){ 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. * Returns null if no policy can be created. */ - protected static Policy getAntiScriptPolicy(ServletContext context){ - Object obj = context.getAttribute( ANTI_SCRIPT_POLICY ); - if( obj == null ){ + protected static Policy getAntiScriptPolicy( ){ + + if( policy == null ){ Policy newPolicy; try { - String url = ANTI_SCRIPT_POLICY_FILE; - URL policyFile= context.getResource( url ); - newPolicy = Policy.getInstance( policyFile ); - context.setAttribute(ANTI_SCRIPT_POLICY, newPolicy); + String url = ANTI_SCRIPT_POLICY_FILE; + URL policyFile= AntiScript.class.getResource( url ); + newPolicy = Policy.getInstance( policyFile ); log.debug("anti-script policy loaded successfully"); - return newPolicy; + policy = newPolicy; } catch (PolicyException e) { log.error("Anti-Script policy not setup.", e); return null; - } catch (MalformedURLException e) { + } catch (Throwable e) { log.error("Anti-Script policy not setup.", e); return null; - } - } else { - return (Policy)obj; - } + } + } + + return policy; } /** - * Try to get an AntiSamy HTML scanner object that is sharied across - * the whole web application. This may return a scanner with a null + * Try to get a static AntiSamy HTML scanner object that is shared the + * whole application. This may return a scanner with a null * policy if the policy is not setup correctly. */ - protected static AntiSamy getHTMLScanner( ServletContext context){ - Object obj = context.getAttribute( ANTI_SCRIPT_SCANNER ); - if( obj == null ){ - AntiSamy scanner = new AntiSamy( getAntiScriptPolicy(context)); - context.setAttribute( ANTI_SCRIPT_SCANNER , scanner); - log.debug("anti-script scanner loaded successfully"); - return scanner; - }else{ - return (AntiSamy) obj; - } + public static AntiSamy getAntiSamyScanner( ){ + + if( antiSamy == null ){ + antiSamy = new AntiSamy( getAntiScriptPolicy() ); + log.debug("anti-script scanner loaded successfully"); + } + + return antiSamy; } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/BaseTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/BaseTemplateModel.java index ebd2aed21..740377a49 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/BaseTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/BaseTemplateModel.java @@ -45,6 +45,9 @@ public abstract class BaseTemplateModel { * that shouldn't be in a URI. */ protected String cleanURIForDisplay( String dirty ){ + if( dirty == null ) + return null; + StringBuilder clean = new StringBuilder(dirty.length()); for (char ch: dirty.toCharArray()) { if (URI_CHARACTERS.indexOf(ch) != -1) { @@ -59,7 +62,7 @@ public abstract class BaseTemplateModel { * Currently this only checks for XSS exploits. */ 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. */ protected void cleanMapValuesForDisplay( Map map){ - AntiScript.cleanMapValues(map, getServletContext()); + AntiScript.cleanMapValues(map); } protected static ServletContext getServletContext() { diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/validators/AntiXssValidationTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/validators/AntiXssValidationTest.java new file mode 100644 index 000000000..ee11903e1 --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/validators/AntiXssValidationTest.java @@ -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 params = new HashMap(); + String[] vals= { "some sort of string" }; + params.put("X", vals); + + MultiValueEditSubmission mvEditSub = + new MultiValueEditSubmission(params,eConf); + + Map 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 params = new HashMap(); + 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 res = validator.validate(eConf, mvEditSub); + Assert.assertNull( res ); + } + + protected Map testURI( String ... strings){ + + AntiXssValidation validator = + new AntiXssValidation(Arrays.asList("X")); + + EditConfigurationVTwo eConf = new EditConfigurationVTwo(); + eConf.setEditKey("fakeEditKey"); + eConf.setUrisOnform( Arrays.asList("X")); + + Map params = new HashMap(); + params.put("X", strings ); + + MultiValueEditSubmission mvEditSub = + new MultiValueEditSubmission(params,eConf); + + return validator.validate(eConf, mvEditSub); + } + + @Test + public void testURIValidation(){ + Map result = testURI("http://this.should.be.fine.com/xyz#lskd?junk=a&bkeck=%23"); + Assert.assertNull(result); + } + + @Test + public void testURIValidationWithScriptTagLevel1(){ + Map result = null; + result = testURI("http://bad.news.com"); + Assert.assertNotNull(result); + + result = testURI("http://bad.news.com"); + Assert.assertNotNull(result); + + result = testURI("http://bad.news.com"); + Assert.assertNotNull(result); + + result = testURI("http://bad.news.com"); + Assert.assertNotNull(result); + + result = testURI("http://bad.news.com"); + Assert.assertNotNull(result); + } + + @Test + public void testURIValidationWithScriptTagLevel2(){ + Map result = null; + result = testURI("http://bad.news.com"); + Assert.assertNotNull(result); + + result = testURI("http://bad.news.com"); + Assert.assertNotNull(result); + + result = testURI("http://bad.news.com"); + Assert.assertNotNull(result); + + result = testURI("http:<//bad.news.com"); + Assert.assertNotNull(result); + + result = testURI("http://bad.news.com"); + Assert.assertNotNull(result); + + result = testURI("http://bad.news.com"); + Assert.assertNotNull(result); + } + + +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/web/templatemodels/BaseTemplateModelTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/web/templatemodels/BaseTemplateModelTest.java new file mode 100644 index 000000000..6e71200b2 --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/web/templatemodels/BaseTemplateModelTest.java @@ -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 ); + } + +}