From 8a588580e3d332b9e6920db49e3c8a8adc79a872 Mon Sep 17 00:00:00 2001 From: srosse <stephane.rosse@frentix.com> Date: Fri, 24 May 2019 17:06:15 +0200 Subject: [PATCH] OO-4069: replace antisamy with java-html-sanitizer --- NOTICE.TXT | 3 +- pom.xml | 49 +- .../modules/bc/components/ListRenderer.java | 1 - .../richText/RichTextElementImpl.java | 2 +- .../core/logging/OLATRuntimeException.java | 14 +- .../java/org/olat/core/util/StringHelper.java | 4 +- .../olat/core/util/filter/FilterFactory.java | 20 +- .../filter/impl/OWASPAntiSamyXSSFilter.java | 284 +--- .../core/util/filter/impl/OpenOLATPolicy.java | 303 ++++ .../impl/_resources/antisamy-tinymce.xml | 1393 ----------------- .../filter/impl/_resources/antisamy-wiki.xml | 1321 ---------------- .../export/QTIExportFormatterCSVType1.java | 5 +- .../export/QTIExportFormatterCSVType3.java | 4 +- .../model/xml/Onyx38ToQtiWorksHandler.java | 19 +- .../handlers/CopyAndConvertVisitor.java | 4 +- .../olat/modules/webFeed/FeedViewHelper.java | 4 +- .../modules/wiki/WikiArticleSearchForm.java | 11 +- .../wikiToHtml/WikiMarkupRenderer.java | 2 +- .../util/filter/impl/XSSFilterParamTest.java | 141 +- .../core/util/filter/impl/XSSFilterTest.java | 84 - .../java/org/olat/test/AllTestsJunit4.java | 1 - 21 files changed, 443 insertions(+), 3226 deletions(-) create mode 100644 src/main/java/org/olat/core/util/filter/impl/OpenOLATPolicy.java delete mode 100644 src/main/java/org/olat/core/util/filter/impl/_resources/antisamy-tinymce.xml delete mode 100644 src/main/java/org/olat/core/util/filter/impl/_resources/antisamy-wiki.xml delete mode 100644 src/test/java/org/olat/core/util/filter/impl/XSSFilterTest.java diff --git a/NOTICE.TXT b/NOTICE.TXT index bf17af8d167..5eb0a0078fa 100644 --- a/NOTICE.TXT +++ b/NOTICE.TXT @@ -116,6 +116,7 @@ This product uses software based on the Apache Software License like * flv.js (Apache Software License, Version 2.0) [https://github.com/Bilibili/flv.js] * hls.js (Apache Software License, Version 2.0) [https://github.com/video-dev/hls.js] * JJWT (Apache Software License, Version 2.0) [https://github.com/jwtk/jjwt] +* Java-html-sanitizer (Apache Software License, Version 2.0) [https://github.com/OWASP/java-html-sanitizer] ----------------------------------------------------------------------- This produce uses software based on the MIT License @@ -140,7 +141,6 @@ This produce uses software based on the MIT License ----------------------------------------------------------------------- This product uses software based on the BSD License -* antisamy (BSD license.) [https://www.owasp.org/index.php/Category:OWASP_AntiSamy_Project] * XStream (BSD style) [http://xstream.codehaus.org] * dom4j (BSD style license) [http://dom4j.sourceforge.net] * Mail (CDDL-1.0, BSD, GPL-2.0, GNU-Classpath) [http://kenai.com/projects/javamail] @@ -210,3 +210,4 @@ This product uses software based on specific License * jcodec (see http://jcodec.org/lic.html) [http://jcodec.org] * periodic (none) [https://github.com/tra/periodic] * typeahead.js (see src/main/webapp/WEB-INF/lib/licenses/typeahead.licence.txt) [https://github.com/twitter/typeahead.js/blob/master/LICENSE] +* validator.nu htmlparser (https://github.com/validator/htmlparser/blob/validator-nu/LICENSE.txt) [https://github.com/validator/htmlparser/blob/validator-nu/LICENSE.txt] diff --git a/pom.xml b/pom.xml index f7d4bbb6928..a7b47c51d17 100644 --- a/pom.xml +++ b/pom.xml @@ -1385,8 +1385,8 @@ <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> - <source>1.8</source> - <target>1.8</target> + <source>${targetJdk}</source> + <target>${targetJdk}</target> <encoding>UTF-8</encoding> </configuration> </plugin> @@ -2171,20 +2171,9 @@ <version>1.4.13</version> </dependency> <dependency> - <groupId>net.sourceforge.nekohtml</groupId> - <artifactId>nekohtml</artifactId> - <version>1.9.22</version> - </dependency> - <dependency> - <groupId>org.owasp.antisamy</groupId> - <artifactId>antisamy</artifactId> - <version>1.5.8</version> - <exclusions> - <exclusion> - <groupId>xml-apis</groupId> - <artifactId>xml-apis</artifactId> - </exclusion> - </exclusions> + <groupId>com.googlecode.owasp-java-html-sanitizer</groupId> + <artifactId>owasp-java-html-sanitizer</artifactId> + <version>20190503.1</version> </dependency> <dependency> <groupId>org.w3c.css</groupId> @@ -2375,31 +2364,6 @@ <artifactId>xstream</artifactId> <version>1.4.11.1</version> </dependency> - <dependency> - <groupId>xerces</groupId> - <artifactId>xercesImpl</artifactId> - <version>2.12.0</version> - <!-- prevents duplicate --> - <exclusions> - <exclusion> - <groupId>xml-apis</groupId> - <artifactId>xml-apis</artifactId> - </exclusion> - <exclusion> - <groupId>xerces</groupId> - <artifactId>xmlParserAPIs</artifactId> - </exclusion> - <exclusion> - <groupId>jdom</groupId> - <artifactId>jdom</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>xml-apis</groupId> - <artifactId>xml-apis</artifactId> - <version>1.4.01</version> - </dependency> <dependency> <groupId>com.sun.mail</groupId> <artifactId>jakarta.mail</artifactId> @@ -2598,8 +2562,7 @@ <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> - <version>23.0</version> - <scope>test</scope> + <version>27.1-jre</version> </dependency> <!-- selenium first --> <dependency> diff --git a/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java b/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java index 82acd484c3c..c62b3aebec5 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java +++ b/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java @@ -282,7 +282,6 @@ public class ListRenderer { if (isContainer) { // for directories... normal module URIs // needs encoding, not done in buildHrefAndOnclick! - //FIXME: SR: refactor encode: move to ubu.buildHrefAndOnclick String pathAndNameEncoded = ubu.encodeUrl(pathAndName); ubu.buildHrefAndOnclick(sb, pathAndNameEncoded, iframePostEnabled, false, true); } else { // for files, add PARAM_SERV command diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/richText/RichTextElementImpl.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/richText/RichTextElementImpl.java index f6d39fefb5f..778af68748b 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/richText/RichTextElementImpl.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/richText/RichTextElementImpl.java @@ -112,7 +112,7 @@ public class RichTextElementImpl extends AbstractTextElement implements @Override public String getValue() { String val = getRawValue(); - Filter xssFilter = FilterFactory.getXSSFilter(val.length() + 1); + Filter xssFilter = FilterFactory.getXSSFilter(); val = xssFilter.filter(val); for (Filter filter : configuration.getValueFilters()) { val = filter.filter(val); diff --git a/src/main/java/org/olat/core/logging/OLATRuntimeException.java b/src/main/java/org/olat/core/logging/OLATRuntimeException.java index 143e1b1ff49..895edfc14a3 100644 --- a/src/main/java/org/olat/core/logging/OLATRuntimeException.java +++ b/src/main/java/org/olat/core/logging/OLATRuntimeException.java @@ -32,11 +32,11 @@ import org.olat.core.util.filter.FilterFactory; public class OLATRuntimeException extends RuntimeException { private static final long serialVersionUID = -1627846608356883591L; - private String logMsg; - private String usrMsgKey; - private String usrMsgPackage; - private String[] usrMsgArgs; - private Class<?> throwingClazz; + private final String logMsg; + private final String usrMsgKey; + private final String usrMsgPackage; + private final String[] usrMsgArgs; + private final Class<?> throwingClazz; /** * @param throwing class @@ -97,7 +97,7 @@ public class OLATRuntimeException extends RuntimeException { * @return HTML fragment. */ public static String throwableToHtml(Throwable th) { - StringBuilder sb = new StringBuilder("<br />"); + StringBuilder sb = new StringBuilder("<br>"); if (th == null) { sb.append("n/a"); } @@ -114,7 +114,7 @@ public class OLATRuntimeException extends RuntimeException { ca = ca.getCause(); } } - return FilterFactory.getXSSFilter(10000).filter(sb.toString()); + return FilterFactory.getXSSFilter().filter(sb.toString()); } private static void toHtml(StringBuilder sb, Throwable th) { diff --git a/src/main/java/org/olat/core/util/StringHelper.java b/src/main/java/org/olat/core/util/StringHelper.java index b40c7185dbe..70a80cfd01e 100644 --- a/src/main/java/org/olat/core/util/StringHelper.java +++ b/src/main/java/org/olat/core/util/StringHelper.java @@ -425,9 +425,7 @@ public class StringHelper { } public static final boolean xssScanForErrors(String str) { - OWASPAntiSamyXSSFilter filter = new OWASPAntiSamyXSSFilter(); - filter.filter(str); - return filter.getNumOfErrors() > 0; + return new OWASPAntiSamyXSSFilter().errors(str); } public static final String escapeJava(String str) { diff --git a/src/main/java/org/olat/core/util/filter/FilterFactory.java b/src/main/java/org/olat/core/util/filter/FilterFactory.java index 681fac8ae17..3876af82b35 100644 --- a/src/main/java/org/olat/core/util/filter/FilterFactory.java +++ b/src/main/java/org/olat/core/util/filter/FilterFactory.java @@ -24,7 +24,6 @@ import org.olat.core.util.filter.impl.AddBaseURLToMediaRelativeURLFilter; import org.olat.core.util.filter.impl.ConditionalHTMLCommentsFilter; import org.olat.core.util.filter.impl.HtmlFilter; import org.olat.core.util.filter.impl.OWASPAntiSamyXSSFilter; -import org.olat.core.util.filter.impl.OWASPAntiSamyXSSFilter.Variant; import org.olat.core.util.filter.impl.SimpleHTMLTagsFilter; import org.olat.core.util.filter.impl.SmileysCssToDataUriFilter; import org.olat.core.util.filter.impl.XMLValidCharacterFilter; @@ -97,24 +96,9 @@ public class FilterFactory { * @param set the maximum length allowed by the xss filter, -1 take the default value from the policy file * @return */ - public static Filter getXSSFilter(int maxLength) { + public static Filter getXSSFilter() { // currently the XSS filter is statefull - return new OWASPAntiSamyXSSFilter(maxLength, false); - } - - /** - * - * @param maxLength - * @return - */ - public static Filter getXSSFilterForTextField(int maxLength) { - // currently the XSS filter is statefull - return new OWASPAntiSamyXSSFilter(maxLength, false, Variant.tinyMce, false); - } - - public static Filter getXSSFilterForWiki(int maxLength) { - // currently the XSS filter is statefull - return new OWASPAntiSamyXSSFilter(maxLength, false, Variant.wiki, false); + return new OWASPAntiSamyXSSFilter(); } /** diff --git a/src/main/java/org/olat/core/util/filter/impl/OWASPAntiSamyXSSFilter.java b/src/main/java/org/olat/core/util/filter/impl/OWASPAntiSamyXSSFilter.java index 067a9ebc933..1938767a649 100644 --- a/src/main/java/org/olat/core/util/filter/impl/OWASPAntiSamyXSSFilter.java +++ b/src/main/java/org/olat/core/util/filter/impl/OWASPAntiSamyXSSFilter.java @@ -19,30 +19,8 @@ */ package org.olat.core.util.filter.impl; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; - -import org.apache.logging.log4j.Logger; -import org.olat.core.logging.OLATRuntimeException; -import org.olat.core.logging.Tracing; import org.olat.core.util.filter.Filter; -import org.olat.core.util.vfs.VFSManager; -import org.owasp.validator.html.AntiSamy; -import org.owasp.validator.html.CleanResults; -import org.owasp.validator.html.Policy; -import org.owasp.validator.html.PolicyException; -import org.owasp.validator.html.ScanException; -import org.xml.sax.Attributes; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -import nu.validator.htmlparser.common.XmlViolationPolicy; -import nu.validator.htmlparser.sax.HtmlParser; +import org.owasp.html.HtmlChangeListener; /** * Description:<br> @@ -61,255 +39,43 @@ import nu.validator.htmlparser.sax.HtmlParser; */ public class OWASPAntiSamyXSSFilter implements Filter { - private static final Logger log = Tracing.createLoggerFor(OWASPAntiSamyXSSFilter.class); - - //to be found in /_resources - private static final String POLICY_FILE = "antisamy-tinymce.xml"; - private static final String WIKI_POLICY_FILE = "antisamy-wiki.xml"; - private static boolean jUnitDebug; - private CleanResults cr; - private final int maxLength; - private final Variant variant; - private final boolean entityEncodeIntlChars; - - private static Policy tinyMcePolicy; - private static Policy internalionalTinyMcePolicy; - private static Policy wikiPolicy; - private static Policy internalionalWikiPolicy; - - static { - String fPath = VFSManager.sanitizePath(OWASPAntiSamyXSSFilter.class.getPackage().getName()); - fPath = fPath.replace('.', '/'); - String tinyPath = fPath + "/_resources/" + POLICY_FILE; - try(InputStream inStream = OWASPAntiSamyXSSFilter.class.getResourceAsStream(tinyPath)) { - tinyMcePolicy = Policy.getInstance(inStream); - internalionalTinyMcePolicy = tinyMcePolicy.cloneWithDirective("entityEncodeIntlChars", "false"); - } catch (Exception e) { - log.error("", e); - } - - String wikiPath = fPath + "/_resources/" + WIKI_POLICY_FILE; - try(InputStream inStream = OWASPAntiSamyXSSFilter.class.getResourceAsStream(wikiPath)) { - wikiPolicy = Policy.getInstance(inStream); - internalionalWikiPolicy = wikiPolicy.cloneWithDirective("entityEncodeIntlChars", "false"); - } catch (Exception e) { - log.error("", e); - } - } - - public OWASPAntiSamyXSSFilter(){ - this(-1, true, Variant.tinyMce, false); - } - - /** - * @param maxLength - * @param junitDebug - */ - public OWASPAntiSamyXSSFilter(int maxLength, boolean junitDebug){ - this(maxLength, true, Variant.tinyMce, junitDebug); - } - - public OWASPAntiSamyXSSFilter(int maxLength, boolean entityEncodeIntlChars, Variant variant, boolean junitDebug){ - OWASPAntiSamyXSSFilter.jUnitDebug = junitDebug; - this.variant = variant; - this.maxLength = maxLength; - this.entityEncodeIntlChars = entityEncodeIntlChars; + public OWASPAntiSamyXSSFilter() { + // } @Override public String filter(String original) { if (original == null) { - log.debug("Filter-Input was null, is this intended?"); return null; } - String output = getCleanHTML(original); - if (original.equals(output)) { - // works - } else { - String errMsg = getOrPrintErrorMessages(); - if (!errMsg.equals("")) { - log.warn(" Filter applied! => message from filter, check if this should not be allowed: " + errMsg); - log.info(" Original Input: \n" + original); - log.info(" Filter Result: \n" + output); - } else { - log.debug(" Filter result doesn't match input! / no message from filter! maybe only some formatting differences."); - } - } - return output; - } - - private void printOriginStackTrace() { - // use stacktrace to find out more where the filter was used - OLATRuntimeException ore = new OLATRuntimeException("XSSFilter dummy", null); - final Writer result = new StringWriter(); - final PrintWriter printWriter = new PrintWriter(result); - ore.printStackTrace(printWriter); - } - - private String getCleanHTML(String original) { - Policy policy; - if(variant == Variant.wiki) { - if(entityEncodeIntlChars) { - policy = wikiPolicy; - } else { - policy = internalionalWikiPolicy; - } - } else { - if(entityEncodeIntlChars) { - policy = tinyMcePolicy; - } else { - policy = internalionalTinyMcePolicy; - } - } - - if(maxLength > 0) { - policy = policy.cloneWithDirective("maxInputSize", Integer.toString(maxLength)); - } - - AntiSamy as = new AntiSamy(); - cr = null; - try { - cr = as.scan(original, policy); - } catch (ScanException e) { - log.error("XSS Filter scan error", e); - printOriginStackTrace(); - } catch (PolicyException e) { - log.error("XSS Filter policy error", e); - printOriginStackTrace(); - } catch (IllegalStateException e) { - //Bug in Batik with rgb values in percent: rgb(100%,20%,0%) - getCleanHTMLFromBatikBug(original, policy); - } - String output; - try { - output = cr.getCleanHTML(); - } catch (Exception | Error e){ - output = ""; - log.error("Error getting cleaned HTML from string::" + original, e); - } - if (jUnitDebug) System.out.println("OWASP-AntiSamy-Outp: " + output); - getOrPrintErrorMessages(); - if (jUnitDebug) System.out.println("OWASP-ParseTime: " + cr.getScanTime()); - - return output; + return OpenOLATPolicy.POLICY_DEFINITION.sanitize(original); } - private void getCleanHTMLFromBatikBug(String original, Policy policy) { - cr = null; - try { - String rgbCleanedOriginal = cleanHtml(original); - AntiSamy as = new AntiSamy(); - cr = as.scan(rgbCleanedOriginal, policy); - } catch (ScanException e) { - log.error("XSS Filter scan error", e); - printOriginStackTrace(); - } catch (PolicyException e) { - log.error("XSS Filter policy error", e); - printOriginStackTrace(); - } catch (IllegalStateException e) { - log.error("XSS Filter policy dramatic Batik error", e); - printOriginStackTrace(); + public boolean errors(String original) { + if (original == null) { + return false; } + ChangeListener listener = new ChangeListener(); + OpenOLATPolicy.POLICY_DEFINITION.sanitize(original, listener, this); + return listener.getErrors() > 0; } - - private String cleanHtml(String original) { - try { - HTMLCleanerHandler handler = new HTMLCleanerHandler(); - HtmlParser parser = new HtmlParser(XmlViolationPolicy.ALTER_INFOSET); - parser.setContentHandler(handler); - parser.parse(new InputSource(new StringReader(original))); - return handler.toString(); - } catch (SAXException | IOException e) { - log.error("", e); - return ""; - } - } - - public int getNumOfErrors() { - if (cr != null) { - return cr.getNumberOfErrors(); - } - return -1; - } - - /** - * get Errors/Messages from filter. - * This have not to be "errors", its whatR has been filtered and gets reported. - * @return - */ - public String getOrPrintErrorMessages(){ - String errors = ""; - if (cr!=null){ - if (cr.getNumberOfErrors()!=0) { - errors = "OWASP-Errors: " + cr.getErrorMessages(); - if (jUnitDebug) System.out.println(errors); - } - } - return errors; - } - - public enum Variant { - tinyMce, - wiki - - } - - /** - * The handler will remove style attributes if it detects a RGB value - * to prevent: https://issues.apache.org/jira/browse/BATIK-1149<br> - * This is a bug in Batik which doesn't understand rgb values in percent. - * - * Initial date: 16 avr. 2019<br> - * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com - * - */ - private static class HTMLCleanerHandler extends DefaultHandler { - - private final StringBuilder output = new StringBuilder(4096); - - @Override - public void startElement(String uri, String localName, String qName, Attributes attributes) { - output.append("<").append(localName); - int numOfAttributes = attributes.getLength(); - for(int i=0; i<numOfAttributes; i++) { - String attrName = attributes.getLocalName(i); - String attrValue = attributes.getValue(i); - if(attrValue.contains("rgb")) { - continue; - } - - output.append(' ').append(attrName).append("="); - boolean useSingle = attrValue.indexOf('"') >= 0; - if(useSingle) { - output.append('\''); - } else { - output.append('"'); - } - output.append(attrValue); - if(useSingle) { - output.append('\''); - } else { - output.append('"'); - } - } - output.append(">"); + + private static class ChangeListener implements HtmlChangeListener<OWASPAntiSamyXSSFilter> { + + private int errors = 0; + + public int getErrors() { + return errors; + } + + @Override + public void discardedTag(OWASPAntiSamyXSSFilter context, String elementName) { + errors++; } @Override - public void characters(char[] ch, int start, int length) throws SAXException { - if(output != null) { - output.append(ch, start, length); - } + public void discardedAttributes(OWASPAntiSamyXSSFilter context, String tagName, String... attributeNames) { + errors++; } - - @Override - public void endElement(String uri, String localName, String qName) { - output.append("</").append(localName).append(">"); - } - - @Override - public String toString() { - return output.toString(); - } - } + } } diff --git a/src/main/java/org/olat/core/util/filter/impl/OpenOLATPolicy.java b/src/main/java/org/olat/core/util/filter/impl/OpenOLATPolicy.java new file mode 100644 index 00000000000..4a12bd7087f --- /dev/null +++ b/src/main/java/org/olat/core/util/filter/impl/OpenOLATPolicy.java @@ -0,0 +1,303 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.util.filter.impl; + +import java.util.regex.Pattern; + +import org.owasp.html.HtmlPolicyBuilder; +import org.owasp.html.PolicyFactory; + +import com.google.common.base.Predicate; + +/** + * + * Initial date: 22 mai 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class OpenOLATPolicy { + + private static final Pattern PARAGRAPH = Pattern.compile("([\\p{L}\\p{N},'\\.\\s\\-_\\(\\)]|&[0-9]{2};)*"); + //private static final Pattern POSITIVELENGTH = Pattern.compile("((\\+)?0|(\\+)?([0-9]+(.[0-9]+)?)(em|ex|px|in|cm|mm|pt|pc))"); + private static final Pattern COLORNAME = Pattern.compile("(aqua|black|blue|fuchsia|gray|grey|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)"); + private static final Pattern OFFSITEURL = Pattern.compile("(\\s)*((ht)tp(s?)://|mailto:)[\\p{L}\\p{N}]+[\\p{L}\\p{N}\\p{Zs}\\.\\#@\\$%\\+&;:\\-_~,\\?=/!\\(\\)]*(\\s)*"); + //private static final Pattern RELATIVE_SIZE = Pattern.compile("(larger|smaller)"); + //private static final Pattern SYSTEMCOLOR = Pattern.compile("(activeborder|activecaption|appworkspace|background|buttonface|buttonhighlight|buttonshadow|buttontext|captiontext|graytext|highlight|highlighttext|inactiveborder|inactivecaption|inactivecaptiontext|infobackground|infotext|menu|menutext|scrollbar|threeddarkshadow|threedface|threedhighlight|threedlightshadow|threedshadow|window|windowframe|windowtext)"); + private static final Pattern HTMLCLASS = Pattern.compile("[a-zA-Z0-9\\s,-_]+"); + //private static final Pattern LENGTH = Pattern.compile("((-|\\+)?0|(-|\\+)?([0-9]+(.[0-9]+)?)(em|ex|px|in|cm|mm|pt|pc))"); + //private static final Pattern ABSOLUTE_SIZE = Pattern.compile("(xx-small|x-small|small|medium|large|x-large|xx-large)"); + //private static final Pattern POSITIVEPERCENTAGE = Pattern.compile("(\\+)?([0-9]+(.[0-9]+)?)%"); + private static final Pattern ANYTHING = Pattern.compile(".*"); + private static final Pattern ONSITEURL = Pattern.compile("([\\p{L}\\p{N}\\p{Zs}/\\.\\?=&\\-~_]|ccrep:)+"); + private static final Pattern NUMBER = Pattern.compile("[0-9]+"); + private static final Pattern HTMLTITLE = Pattern.compile("[a-zA-Z0-9\\s-_',:\\[\\]!\\./\\\\\\(\\)%&;\\+#]*"); + + //private static final Pattern CSSONSITEURI = Pattern.compile("url\\(([\\p{L}\\p{N}\\\\/\\.\\?=\\#&;\\-_~]+|\\#(\\w)+)\\)"); + //private static final Pattern RGBCODE = Pattern.compile("rgb\\(([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]),([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]),([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\\)"); + //private static final Pattern PERCENTAGE = Pattern.compile("(-|\\+)?([0-9]+(.[0-9]+)?)%"); + private static final Pattern OLATINTERNALURL = Pattern.compile("javascript:parent\\.gotonode\\(\\d+\\)"); + private static final Pattern NUMBERORPERCENT = Pattern.compile("(\\d)+(%{0,1})"); + private static final Pattern COLORCODE = Pattern.compile("(#([0-9a-fA-F]{6}|[0-9a-fA-F]{3}))"); + //private static final Pattern CSSOFFSITEURI = Pattern.compile("url\\((\\s)*(http(s?)://)[\\p{L}\\p{N}]+[~\\p{L}\\p{N}\\p{Zs}\\-_\\.@#$%&;:,\\?=/\\+!]*(\\s)*\\)"); + + public static final PolicyFactory POLICY_DEFINITION = new HtmlPolicyBuilder() + .allowStyling() + .allowAttributes("id") + .matching(Pattern.compile("[a-zA-Z0-9_\\-\\:]+")).globally() + .allowAttributes("title") + .matching(HTMLTITLE).globally() + .allowAttributes("lang") + .matching(Pattern.compile("[a-zA-Z]{2,20}")).globally() + + .allowUrlProtocols("mailto", "http", "https") + .allowElements("img", "a") + // Fix::dir + .allowAttributes("charoff") + .matching(Pattern.compile("numberOrPercent")) + .onElements("tbody") + .allowAttributes("char") + .matching(Pattern.compile(".*{0,1}")) + .onElements("tbody") + .allowAttributes("valign") + .matching(false,"baseline", "bottom", "middle", "top") + .onElements("tbody") + .allowAttributes("align") + .matching(false,"center", "middle", "left", "right", "justify", "char") + .onElements("tbody") + .allowAttributes("class") + .matching(HTMLCLASS).onElements("div", "ul", "blockquote", "figcaption") + // img + .allowAttributes("border") + .matching(NUMBER).onElements("img") + .allowAttributes("src") + .matching(new Patterns(ONSITEURL, OFFSITEURL)).onElements("img") + .allowAttributes("alt") + .matching(PARAGRAPH).onElements("img") + .allowAttributes("align") + .matching(false,"center", "middle", "left", "right", "justify", "char").onElements("img") + .allowAttributes("class") + .matching(HTMLCLASS).onElements("img") + .allowAttributes("hspace") + .matching(NUMBER).onElements("img") + .allowAttributes("height") + .matching(NUMBERORPERCENT).onElements("img") + .allowAttributes("vspace") + .matching(NUMBER).onElements("img") + .allowAttributes("width") + .matching(NUMBERORPERCENT).onElements("img") + // edu-sharing + .allowAttributes("data-es_identifier") + .matching(Pattern.compile("[a-zA-Z0-9_\\-\\:]+")).onElements("img") + .allowAttributes("data-es_width") + .matching(NUMBER).onElements("img") + .allowAttributes("data-es_mediatype") + .matching(Pattern.compile("[a-zA-Z0-9_\\-\\:]+")).onElements("img") + .allowAttributes("data-es_objecturl") + .matching(Pattern.compile("[a-zA-Z0-9_\\-\\:\\/]+")).onElements("img") + .allowAttributes("data-es_show_infos") + .matching(Pattern.compile("show|hide")).onElements("img") + .allowAttributes("data-es_mimetype") + .matching(Pattern.compile("[a-zA-Z0-9_\\-\\:\\/]+")).onElements("img") + .allowAttributes("data-es_height") + .matching(NUMBER).onElements("img") + .allowAttributes("data-es_version_current") + .matching(Pattern.compile("[a-zA-Z0-9_\\-\\:\\.]+")).onElements("img") + .allowAttributes("data-es_first_edit") + .matching(Pattern.compile("true|false")).onElements("img") + .allowAttributes("data-es_version") + .matching(Pattern.compile("[a-zA-Z0-9_\\-\\:\\.]+")).onElements("img") + .allowAttributes("data-es_show_license") + .matching(Pattern.compile("show|hide")).onElements("img") + + .allowAttributes("charoff").matching(Pattern.compile("numberOrPercent")).onElements("thead") + .allowAttributes("char").matching(Pattern.compile(".*{0,1}")).onElements("thead") + .allowAttributes("valign").matching(false,"baseline", "bottom", "middle", "top").onElements("thead") + .allowAttributes("align").matching(false,"center", "middle", "left", "right", "justify", "char").onElements("thead") + .allowAttributes("class") + .matching(HTMLCLASS).onElements("h1", "h2", "h3", "h4", "h5", "h6") + .allowAttributes("class").matching(HTMLCLASS).onElements("ol") + .allowAttributes("border").matching(NUMBER).onElements("table") + .allowAttributes("summary").matching(PARAGRAPH).onElements("table") + .allowAttributes("bgcolor").matching(new Patterns(COLORNAME, COLORCODE)).onElements("table") + .allowAttributes("background").matching(ONSITEURL).onElements("table") + .allowAttributes("cellpadding").matching(NUMBER).onElements("table") + .allowAttributes("noresize").matching(false,"noresize").onElements("table") + .allowAttributes("width").matching(NUMBERORPERCENT).onElements("table") + .allowAttributes("cellspacing").matching(NUMBER).onElements("table") + .allowAttributes("rules").matching(false,"none", "rows", "cols", "groups", "all").onElements("table") + .allowAttributes("align").matching(false,"center", "middle", "left", "right", "justify", "char").onElements("table") + .allowAttributes("class").matching(HTMLCLASS).onElements("table") + .allowAttributes("height").matching(NUMBERORPERCENT).onElements("table") + // link + .allowAttributes("alt") + .matching(PARAGRAPH).onElements("a") + .allowAttributes("nohref") + .matching(false,"nohref").onElements("a") + .allowAttributes("target") + .matching(false,"_blank").onElements("a") + .allowAttributes("class") + .matching(HTMLCLASS).onElements("a") + .allowAttributes("rel") + .matching(false,"nofollow").onElements("a") + .allowAttributes("href") + .matching(new Patterns(ONSITEURL, OFFSITEURL, OLATINTERNALURL)) + .onElements("a") + .allowAttributes("onclick") + .matching(false, "o_XHRWikiEvent(this);", "o_XHRWikiEvent(this);return(false);") + .onElements("a") + // link edu-sharing + .allowAttributes("data-es_show_infos") + .matching(Pattern.compile("show|hide")).onElements("a") + .allowAttributes("data-es_identifier") + .matching(Pattern.compile("[a-zA-Z0-9_\\-\\:]+")).onElements("a") + .allowAttributes("data-es_width") + .matching(NUMBER).onElements("a") + .allowAttributes("data-es_mediatype") + .matching(Pattern.compile("[a-zA-Z0-9_\\-\\:]+")).onElements("a") + .allowAttributes("data-es_objecturl") + .matching(Pattern.compile("[a-zA-Z0-9_\\-\\:\\/]+")).onElements("a") + .allowAttributes("data-es_mimetype") + .matching(Pattern.compile("[a-zA-Z0-9_\\-\\:\\/]+")).onElements("a") + .allowAttributes("data-es_height") + .matching(NUMBER).onElements("a") + .allowAttributes("data-es_version_current") + .matching(Pattern.compile("[a-zA-Z0-9_\\-\\:\\.]+")).onElements("a") + .allowAttributes("data-es_first_edit") + .matching(Pattern.compile("true|false")).onElements("a") + .allowAttributes("data-es_version") + .matching(Pattern.compile("[a-zA-Z0-9_\\-\\:\\.]+")).onElements("a") + .allowAttributes("data-es_show_license") + .matching(Pattern.compile("show|hide")).onElements("a") + // figure + .allowAttributes("class") + .matching(HTMLCLASS) + .onElements("figure") + .allowAttributes("class") + .matching(HTMLCLASS) + .onElements("i") + .allowAttributes("align").matching(false,"center", "middle", "left", "right", "justify", "char").onElements("p") + .allowAttributes("charoff").matching(Pattern.compile("numberOrPercent")).onElements("tfoot") + .allowAttributes("char").matching(Pattern.compile(".*{0,1}")).onElements("tfoot") + .allowAttributes("valign").matching(false,"baseline", "bottom", "middle", "top").onElements("tfoot") + .allowAttributes("align").matching(false,"center", "middle", "left", "right", "justify", "char").onElements("tfoot") + .allowAttributes("headers").matching(Pattern.compile("[a-zA-Z0-9\\s*]*")).onElements("td") + .allowAttributes("nowrap").matching(ANYTHING).onElements("td") + .allowAttributes("valign").matching(false,"baseline", "bottom", "middle", "top").onElements("td") + .allowAttributes("axis").matching(Pattern.compile("[a-zA-Z0-9\\s*,]*")).onElements("td") + .allowAttributes("align").matching(false,"center", "middle", "left", "right", "justify", "char").onElements("td") + .allowAttributes("colspan").matching(NUMBER).onElements("td") + .allowAttributes("bgcolor").matching(new Patterns(COLORNAME, COLORCODE)).onElements("td") + .allowAttributes("charoff").matching(Pattern.compile("numberOrPercent")).onElements("td") + .allowAttributes("background").matching(ONSITEURL).onElements("td") + .allowAttributes("scope").matching(false,"row", "col", "rowgroup", "colgroup").onElements("td") + .allowAttributes("rowspan").matching(NUMBER).onElements("td") + .allowAttributes("width").matching(NUMBERORPERCENT).onElements("td") + .allowAttributes("char").matching(Pattern.compile(".*{0,1}")).onElements("td") + .allowAttributes("abbrev").matching(PARAGRAPH).onElements("td") + .allowAttributes("height").matching(NUMBERORPERCENT).onElements("td") + .allowAttributes("headers").matching(Pattern.compile("[a-zA-Z0-9\\s*]*")).onElements("th") + .allowAttributes("nowrap").matching(ANYTHING).onElements("th") + .allowAttributes("valign").matching(false,"baseline", "bottom", "middle", "top").onElements("th") + .allowAttributes("axis").matching(Pattern.compile("[a-zA-Z0-9\\s*,]*")).onElements("th") + .allowAttributes("align").matching(false,"center", "middle", "left", "right", "justify", "char").onElements("th") + .allowAttributes("colspan").matching(NUMBER).onElements("th") + .allowAttributes("bgcolor").matching(new Patterns(COLORNAME, COLORCODE)).onElements("th") + .allowAttributes("charoff").matching(Pattern.compile("numberOrPercent")).onElements("th") + .allowAttributes("scope").matching(false,"row", "col", "rowgroup", "colgroup").onElements("th") + .allowAttributes("rowspan").matching(NUMBER).onElements("th") + .allowAttributes("width").matching(NUMBERORPERCENT).onElements("th") + .allowAttributes("char").matching(Pattern.compile(".*{0,1}")).onElements("th") + .allowAttributes("abbrev").matching(PARAGRAPH).onElements("th") + .allowAttributes("height").matching(NUMBERORPERCENT).onElements("th") + .allowAttributes("charoff").matching(Pattern.compile("numberOrPercent")).onElements("tr") + .allowAttributes("background").matching(ONSITEURL).onElements("tr") + .allowAttributes("width").matching(NUMBERORPERCENT).onElements("tr") + .allowAttributes("char").matching(Pattern.compile(".*{0,1}")).onElements("tr") + .allowAttributes("valign").matching(false,"baseline", "bottom", "middle", "top").onElements("tr") + .allowAttributes("align").matching(false,"center", "middle", "left", "right", "justify", "char").onElements("tr") + .allowAttributes("class").matching(HTMLCLASS).onElements("tr") + .allowAttributes("height").matching(NUMBERORPERCENT).onElements("tr") + .allowAttributes("class") + .matching(HTMLCLASS).onElements("span") + + .allowElements("dd","tbody","dl","caption","hr","div","dt","ul","init","blockquote","pre","em","figcaption","sub", + "strong","img","thead","h1","h2","h3","h4","h5","h6","sup","ol","table","b","figure","strike","i","p", + "tfoot","td","s","th","u","li","tr","span") + + .allowElements("hr") + .allowWithoutAttributes("hr") + .allowElements("a") + .allowWithoutAttributes("a") + .allowElements("img") + .allowWithoutAttributes("img") + .allowElements("object") + .allowWithoutAttributes("object") + .allowElements("applet") + .allowWithoutAttributes("applet") + .allowElements("param") + .allowWithoutAttributes("param") + .allowElements("meta") + .allowWithoutAttributes("meta") + .allowElements("embed") + .allowWithoutAttributes("embed") + .allowElements("basefont") + .allowWithoutAttributes("basefont") + .allowElements("col") + .allowWithoutAttributes("col") + .allowElements("span") + .allowWithoutAttributes("span") + .allowElements("center") + .allowWithoutAttributes("center") + .toFactory(); + + + private static class Patterns implements Predicate<String> { + + private final Pattern a; + private final Pattern b; + private final Pattern c; + + public Patterns(Pattern a, Pattern b) { + this(a, b, null); + } + + public Patterns(Pattern a, Pattern b, Pattern c) { + this.a = a; + this.b = b; + this.c = c; + } + + @Override + public boolean apply(String s) { + return a.matcher(s).matches() + || b.matcher(s).matches() + || c == null || c.matcher(s).matches(); + } + + // Needed for Java8 compat with later Guava that extends + // java.util.function.Predicate. + // For some reason the default test method implementation that calls + // through to apply is not assumed here. + @SuppressWarnings("unused") + public boolean test(String s) { + return apply(s); + } + } +} diff --git a/src/main/java/org/olat/core/util/filter/impl/_resources/antisamy-tinymce.xml b/src/main/java/org/olat/core/util/filter/impl/_resources/antisamy-tinymce.xml deleted file mode 100644 index a40d6161bb1..00000000000 --- a/src/main/java/org/olat/core/util/filter/impl/_resources/antisamy-tinymce.xml +++ /dev/null @@ -1,1393 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!-- - TinyMCE policy download from trunk adapted for OLAT - Version found at 30.07.2009, Adaption made by frentix GmbH ---> -<anti-samy-rules xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="antisamy.xsd"> - - <directives> - <directive name="omitXmlDeclaration" value="true" /> - <directive name="omitDoctypeDeclaration" value="true" /> - <directive name="maxInputSize" value="1000000" /> - <directive name="embedStyleSheets" value="false" /> - <directive name="useXHTML" value="true" /> - <directive name="formatOutput" value="false" /> - <directive name="entityEncodeIntlChars" value="true" /> - <directive name="preserveSpace" value="true" /> - </directives> - - <common-regexps> - <regexp name="anything" value=".*" /> - <!-- - From W3C: - This attribute assigns a class name or set of class names to an - element. Any number of elements may be assigned the same class - name or names. Multiple class names must be separated by white - space characters. - --> - <regexp name="htmlTitle" - value="[a-zA-Z0-9\s-_',:\[\]!\./\\\(\)%&;\+#]*" /> - <regexp name="htmlClass" value="[a-zA-Z0-9\s,-_]+" /> - - <!-- force non-empty with a '+' at the end instead of '*' - --> - <regexp name="olatInternalURL" - value="javascript:parent\.gotonode\(\d+\)" /> - <regexp name="onsiteURL" - value="([\p{L}\p{N}\p{Zs}/\.\?=&\-~_]|ccrep:)+" /> -<!-- value="([\p{L}\p{N}\p{Zs}/\.\?=&\-~_])+" /> --> - - <regexp name="offsiteURL" - value="(\s)*((ht)tp(s?)://|mailto:)[\p{L}\p{N}]+[\p{L}\p{N}\p{Zs}\.\#@\$%\+&;:\-_~,\?=/!\(\)]*(\s)*" /> - - <!-- - <regexp name="offsiteURL" - value="(\s)*(http(s?)://|mailto:)[A-Za-z0-9]+[~a-zA-Z0-9-_\.@#$%&;:,\?=/\+!]*(\s)*" /> - --> - <!-- This is for resources referenced from CSS (such as background images and other imported stylesheets) --> - <regexp name="cssOnsiteUri" value="url\(([\p{L}\p{N}\\/\.\?=\#&;\-_~]+|\#(\w)+)\)"/> - <regexp name="cssOffsiteUri" value="url\((\s)*(http(s?)://)[\p{L}\p{N}]+[~\p{L}\p{N}\p{Zs}\-_\.@#$%&;:,\?=/\+!]*(\s)*\)"/> - - <regexp name="paragraph" - value="([\p{L}\p{N},'\.\s\-_\(\)]|&[0-9]{2};)*" /> - - <regexp name="numberOrPercent" value="(\d)+(%{0,1})" /> - <regexp name="number" value="[0-9]+" /> - <regexp name="length" - value="((-|\+)?0|(-|\+)?([0-9]+(.[0-9]+)?)(em|ex|px|in|cm|mm|pt|pc))" /> - <regexp name="positiveLength" value="((\+)?0|(\+)?([0-9]+(.[0-9]+)?)(em|ex|px|in|cm|mm|pt|pc))"/> - <regexp name="percentage" value="(-|\+)?([0-9]+(.[0-9]+)?)%" /> - <regexp name="positivePercentage" value="(\+)?([0-9]+(.[0-9]+)?)%"/> - <regexp name="absolute-size" value="(xx-small|x-small|small|medium|large|x-large|xx-large)"/> - <regexp name="relative-size" value="(larger|smaller)"/> - - <!-- The 16 colors defined by the HTML Spec (also used by the CSS Spec) --> - <regexp name="colorName" - value="(aqua|black|blue|fuchsia|gray|grey|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)" /> - <!-- HTML/CSS Spec allows 3 or 6 digit hex to specify color --> - <regexp name="colorCode" - value="(#([0-9a-fA-F]{6}|[0-9a-fA-F]{3}))" /> - <!-- Used for CSS Color specifications (complex regexp expresses integer values of 0-255) --> - <regexp name="rgbCode" - value="rgb\(([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]),([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]),([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\)" /> - <!-- CSS2 Allowed System Color Values --> - <regexp name="systemColor" - value="(activeborder|activecaption|appworkspace|background|buttonface|buttonhighlight|buttonshadow|buttontext|captiontext|graytext|highlight|highlighttext|inactiveborder|inactivecaption|inactivecaptiontext|infobackground|infotext|menu|menutext|scrollbar|threeddarkshadow|threedface|threedhighlight|threedlightshadow|threedshadow|window|windowframe|windowtext)" /> - - - </common-regexps> - - <!-- - Tag.name = a, b, div, body, etc. - Tag.action = filter: remove tags, but keep content, validate: keep content as long as it passes rules, remove: remove tag and contents - Attribute.name = id, class, href, align, width, etc. - Attribute.onInvalid = what to do when the attribute is invalid, e.g., remove the tag (removeTag), remove the attribute (removeAttribute), filter the tag (filterTag) - Attribute.description = What rules in English you want to tell the users they can have for this attribute. Include helpful things so they'll be able to tune their HTML - --> - - <!-- - Some attributes are common to all (or most) HTML tags. There aren't many that qualify for this. You have to make sure there's no - collisions between any of these attribute names with attribute names of other tags that are for different purposes. - --> - - <common-attributes> - <attribute name="id" description="The 'id' of any HTML attribute should not contain anything besides letters and numbers"> - <regexp-list> - <regexp value="[a-zA-Z0-9_\-\:]+"/> - </regexp-list> - </attribute> - - <attribute name="class" - description="The 'class' of any HTML attribute is usually a single word, but it can also be a list of class names separated by spaces"> - <regexp-list> - <regexp name="htmlClass" /> - </regexp-list> - </attribute> - - <attribute name="lang" - description="The 'lang' attribute tells the browser what language the element's attribute values and content are written in"> - <regexp-list> - <regexp value="[a-zA-Z]{2,20}" /> - </regexp-list> - </attribute> - - <attribute name="title" - description="The 'title' attribute provides text that shows up in a 'tooltip' when a user hovers their mouse over the element"> - <regexp-list> - <regexp name="htmlTitle" /> - </regexp-list> - </attribute> - - <attribute name="href" onInvalid="filterTag"> - - <regexp-list> - <regexp name="onsiteURL" /> - <regexp name="offsiteURL" /> - <regexp name="olatInternalURL" /> - <!-- - --> - </regexp-list> - </attribute> - - <attribute name="align" - description="The 'align' attribute of an HTML element is a direction word, like 'left', 'right' or 'center'"> - - <literal-list> - <literal value="center" /> - <literal value="left" /> - <literal value="right" /> - <literal value="justify" /> - <literal value="char" /> - </literal-list> - </attribute> - <attribute name="style" - description="The 'style' attribute provides the ability for users to change many attributes of the tag's contents using a strict syntax" /> - - <attribute name="alt" - description="The 'alt' attribute provides alternative text to users when its visual representation is not available"> - <regexp-list> - <regexp name="paragraph" /> - </regexp-list> - </attribute> - - <!-- Common positioning attributes --> - - <attribute name="width"> - <regexp-list> - <regexp name="numberOrPercent" /> - </regexp-list> - </attribute> - - <attribute name="height"> - <regexp-list> - <regexp name="numberOrPercent" /> - </regexp-list> - </attribute> - - <attribute name="align" - description="The 'align' attribute of an HTML element is a direction word, like 'left', 'right' or 'center'"> - <literal-list> - <literal value="center" /> - <literal value="middle" /> - <literal value="left" /> - <literal value="right" /> - <literal value="justify" /> - <literal value="char" /> - </literal-list> - </attribute> - - <attribute name="valign" - description="The 'valign' attribute of an HTML attribute is a direction word, like 'baseline','bottom','middle' or 'top'"> - <literal-list> - <literal value="baseline" /> - <literal value="bottom" /> - <literal value="middle" /> - <literal value="top" /> - </literal-list> - </attribute> - - <attribute name="border"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <attribute name="dir" - description="The 'dir' attribute of an HTML attribute assigns a reading direction, like 'ltr' or 'rtl' "> - <literal-list> - <literal value="ltr" /> - <literal value="rtl" /> - </literal-list> - </attribute> - - <!-- Table attributes --> - <attribute name="rules" description="The 'rules' attribute of a table specifies where to show rules inside table. "> - <literal-list> - <literal value="none" /> - <literal value="rows" /> - <literal value="cols" /> - <literal value="groups" /> - <literal value="all" /> - </literal-list> - </attribute> - - <attribute name="summary" description="The 'summary' attribute of a table holds an abstract of table content mainly for screen readers. "> - <regexp-list> - <regexp name="paragraph" /> - </regexp-list> - </attribute> - - <attribute name="border"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <attribute name="cellpadding"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <attribute name="cellspacing"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <attribute name="colspan"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <attribute name="rowspan"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <attribute name="background"> - <regexp-list> - <regexp name="onsiteURL" /> - </regexp-list> - </attribute> - - <attribute name="bgcolor"> - <regexp-list> - <regexp name="colorName" /> - <regexp name="colorCode" /> - </regexp-list> - </attribute> - - <attribute name="abbrev"> - <regexp-list> - <regexp name="paragraph" /> - </regexp-list> - </attribute> - - <attribute name="headers" - description="The 'headers' attribute is a space-separated list of cell IDs"> - <regexp-list> - <regexp value="[a-zA-Z0-9\s*]*" /> - </regexp-list> - </attribute> - - <attribute name="charoff"> - <regexp-list> - <regexp value="numberOrPercent" /> - </regexp-list> - </attribute> - - <attribute name="char"> - <regexp-list> - <regexp value=".*{0,1}" /> - </regexp-list> - </attribute> - - <attribute name="axis" - description="The 'headers' attribute is a comma-separated list of related header cells"> - <regexp-list> - <regexp value="[a-zA-Z0-9\s*,]*" /> - </regexp-list> - </attribute> - - <attribute name="nowrap" - description="The 'nowrap' attribute tells the browser not to wrap text that goes over one line"> - <regexp-list> - <regexp name="anything" /> - <!-- <regexp value="(nowrap){0,1}"/> --> - </regexp-list> - </attribute> - - <attribute name="scope" - description="The 'scope' attribute defines what's covered by the header cells"> - <literal-list> - <literal value="row" /> - <literal value="col" /> - <literal value="rowgroup" /> - <literal value="colgroup" /> - </literal-list> - </attribute> - - <!-- edu-sharing data attributes --> - <attribute name="data-es_identifier"> - <regexp-list> - <regexp value="[a-zA-Z0-9_\-\:]+"/> - </regexp-list> - </attribute> - <attribute name="data-es_objecturl"> - <regexp-list> - <regexp value="[a-zA-Z0-9_\-\:\/]+"/> - </regexp-list> - </attribute> - <attribute name="data-es_version"> - <regexp-list> - <regexp value="[a-zA-Z0-9_\-\:\.]+"/> - </regexp-list> - </attribute> - <attribute name="data-es_version_current"> - <regexp-list> - <regexp value="[a-zA-Z0-9_\-\:\.]+"/> - </regexp-list> - </attribute> - <attribute name="data-es_mimetype"> - <regexp-list> - <regexp value="[a-zA-Z0-9_\-\:\/]+"/> - </regexp-list> - </attribute> - <attribute name="data-es_mediatype"> - <regexp-list> - <regexp value="[a-zA-Z0-9_\-\:]+"/> - </regexp-list> - </attribute> - <attribute name="data-es_width"> - <regexp-list> - <regexp value="[0-9]+"/> - </regexp-list> - </attribute> - <attribute name="data-es_height"> - <regexp-list> - <regexp value="[0-9]+"/> - </regexp-list> - </attribute> - <attribute name="data-es_show_license"> - <regexp-list> - <regexp value="show|hide"/> - </regexp-list> - </attribute> - <attribute name="data-es_show_infos"> - <regexp-list> - <regexp value="show|hide"/> - </regexp-list> - </attribute> - <attribute name="data-es_first_edit"> - <regexp-list> - <regexp value="true|false"/> - </regexp-list> - </attribute> - - </common-attributes> - - <!-- - This requires normal updates as browsers continue to diverge from the W3C and each other. As long as the browser wars continue - this is going to continue. I'm not sure war is the right word for what's going on. Doesn't somebody have to win a war after - a while? - - - --> - - <global-tag-attributes> - <attribute name="id" /> - <attribute name="title" /> - <attribute name="lang" /> - <attribute name="style" /> - <attribute name="dir" /> - </global-tag-attributes> - - <tags-to-encode> - <tag>g</tag> - <tag>grin</tag> - </tags-to-encode> - - - - - - - - - - - <tag-rules> - <tag name="h1" action="validate" > - <attribute name="class" /> - </tag> - <tag name="h2" action="validate" > - <attribute name="class" /> - </tag> - <tag name="h3" action="validate" > - <attribute name="class" /> - </tag> - <tag name="h4" action="validate" > - <attribute name="class" /> - </tag> - <tag name="h5" action="validate" > - <attribute name="class" /> - </tag> - <tag name="h6" action="validate" > - <attribute name="class" /> - </tag> - - <!-- Remove --> - - <tag name="script" action="remove" /> - <tag name="noscript" action="remove" /> - <tag name="iframe" action="remove" /> - <tag name="frameset" action="remove" /> - <tag name="frame" action="remove" /> - <tag name="noframes" action="remove" /> - <tag name="head" action="remove" /> - <tag name="title" action="remove" /> - <tag name="base" action="remove" /> - <tag name="style" action="remove" /> - <tag name="link" action="remove" /> - <tag name="input" action="remove" /> - <tag name="textarea" action="remove" /> - - <!-- Truncate --> - <tag name="br" action="truncate" /> - - <!-- Validate --> - <tag name="hr" action="validate"/> - - <tag name="p" action="validate"> - <attribute name="align" /> - </tag> - <tag name="div" action="validate" > - <attribute name="class" /> - </tag> - <tag name="span" action="validate"> - <attribute name="class" /> - </tag> - <!-- necessary for font-awesome icons --> - <tag name="i" action="validate" > - <attribute name="class" /> - </tag> - - <tag name="b" action="validate" /> - <tag name="strong" action="validate" /> - <tag name="s" action="validate" /> - <tag name="strike" action="validate" /> - <tag name="u" action="validate" /> - <tag name="em" action="validate" /> - <tag name="blockquote" action="validate" > - <attribute name="class" /> - </tag> - <tag name="pre" action="validate" /> - <tag name="tt" action="truncate" /> - - <tag name="a" action="validate"> - <attribute name="class" /> - <attribute name="href" onInvalid="filterTag" /> - <attribute name="alt" /> - <attribute name="target"> - <literal-list> - <literal value="_blank" /> - </literal-list> - </attribute> - <attribute name="nohref"> - <literal-list> - <literal value="nohref" /> - <literal value="" /> - </literal-list> - </attribute> - <attribute name="rel"> - <literal-list> - <literal value="nofollow" /> - </literal-list> - </attribute> - - <!-- edu-sharing data attributes --> - <attribute name="data-es_identifier" /> - <attribute name="data-es_objecturl" /> - <attribute name="data-es_version" /> - <attribute name="data-es_version_current" /> - <attribute name="data-es_mimetype" /> - <attribute name="data-es_mediatype" /> - <attribute name="data-es_width" /> - <attribute name="data-es_height" /> - <attribute name="data-es_show_license" /> - <attribute name="data-es_show_infos" /> - <attribute name="data-es_first_edit" /> - </tag> - - <!-- List tags - --> - <tag name="ul" action="validate" > - <attribute name="class" /> - </tag> - <tag name="ol" action="validate" > - <attribute name="class" /> - </tag> - <tag name="li" action="validate" /> - <tag name="dl" action="validate" /> - <tag name="dt" action="validate" /> - <tag name="dd" action="validate" /> - - <!-- Image & image related tags --> - <tag name="figure" action="validate" > - <attribute name="class" /> - </tag> - <tag name="figcaption" action="validate" > - <attribute name="class" /> - </tag> - - <tag name="img" action="validate"> - <attribute name="src" onInvalid="removeTag"> - <regexp-list> - <regexp name="onsiteURL" /> - <regexp name="offsiteURL" /> - </regexp-list> - </attribute> - <attribute name="class" /> - <attribute name="alt" /> - <attribute name="height" /> - <attribute name="width" /> - <attribute name="border" /> - <attribute name="align" /> - - <attribute name="hspace"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <attribute name="vspace"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <!-- edu-sharing data attributes --> - <attribute name="data-es_identifier" /> - <attribute name="data-es_objecturl" /> - <attribute name="data-es_version" /> - <attribute name="data-es_version_current" /> - <attribute name="data-es_mimetype" /> - <attribute name="data-es_mediatype" /> - <attribute name="data-es_width" /> - <attribute name="data-es_height" /> - <attribute name="data-es_show_license" /> - <attribute name="data-es_show_infos" /> - <attribute name="data-es_first_edit" /> - </tag> - - - <tag name="sub" action="validate" /> - <tag name="sup" action="validate" /> - <tag name="caption" action="validate" /> - - - <!-- Table tags (tbody, thead, tfoot)--> - - <tag name="thead" action="validate"> - <attribute name="align" /> - <attribute name="char" /> - <attribute name="charoff" /> - <attribute name="valign" /> - </tag> - - <tag name="tbody" action="validate"> - <attribute name="align" /> - <attribute name="char" /> - <attribute name="charoff" /> - <attribute name="valign" /> - </tag> - - <tag name="tfoot" action="validate"> - <attribute name="align" /> - <attribute name="char" /> - <attribute name="charoff" /> - <attribute name="valign" /> - </tag> - - <tag name="table" action="validate"> - <attribute name="class" /> - <attribute name="height" /> - <attribute name="width" /> - <attribute name="border" /> - <attribute name="bgcolor" /> - <attribute name="cellpadding" /> - <attribute name="cellspacing" /> - <attribute name="background" /> - <attribute name="align" /> - <attribute name="rules" /> - <attribute name="summary" /> - <attribute name="noresize"> - <literal-list> - <literal value="noresize" /> - <literal value="" /> - </literal-list> - </attribute> - </tag> - - <tag name="td" action="validate"> - <attribute name="background" /> - <attribute name="bgcolor" /> - <attribute name="abbrev" /> - <attribute name="axis" /> - <attribute name="headers" /> - <attribute name="scope" /> - <attribute name="nowrap" /> - <attribute name="height" /> - <attribute name="width" /> - <attribute name="align" /> - <attribute name="char" /> - <attribute name="charoff" /> - <attribute name="valign" /> - <attribute name="colspan" /> - <attribute name="rowspan" /> - </tag> - - <tag name="th" action="validate"> - <attribute name="abbrev" /> - <attribute name="axis" /> - <attribute name="headers" /> - <attribute name="scope" /> - <attribute name="nowrap" /> - <attribute name="bgcolor" /> - <attribute name="height" /> - <attribute name="width" /> - <attribute name="align" /> - <attribute name="char" /> - <attribute name="charoff" /> - <attribute name="valign" /> - <attribute name="colspan" /> - <attribute name="rowspan" /> - </tag> - - <tag name="tr" action="validate"> - <attribute name="class" /> - <attribute name="height" /> - <attribute name="width" /> - <attribute name="align" /> - <attribute name="valign" /> - <attribute name="char" /> - <attribute name="charoff" /> - <attribute name="background" /> - </tag> - - <tag name="init" action="validate"> - - </tag> - - </tag-rules> - - - - - - - - <css-rules> - - <property name="height" default="auto" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="auto" /> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="length" /> - <regexp name="percentage" /> - </regexp-list> - </property> - <property name="width" default="auto" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="auto" /> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="length" /> - <regexp name="percentage" /> - </regexp-list> - </property> - - <property name="float" default="none" - description=""> - - <category-list> - <category value="visual" /> - </category-list> - - <literal-list> - <literal value="left" /> - <literal value="right" /> - <literal value="none" /> - <literal value="inherit" /> - </literal-list> - </property> - - <property name="text-decoration" default="none" - description=""> - - <category-list> - <category value="visual" /> - </category-list> - - <literal-list> - <literal value="underline" /> - <literal value="overline" /> - <literal value="line-through" /> - </literal-list> - </property> - - <property name="text-align" - description="This property describes how inline content of a block is aligned."> - <category-list> - <category value="visual" /> - </category-list> - <!-- For safety, ignoring string alignment which can be used to line table cells on characters --> - <literal-list> - <literal value="left" /> - <literal value="right" /> - <literal value="center" /> - <literal value="justify" /> - <literal value="inherit" /> - </literal-list> - </property> - - <property name="vertical-align" default="baseline" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="baseline"/> - <literal value="sub"/> - <literal value="super"/> - <literal value="top"/> - <literal value="text-top"/> - <literal value="middle"/> - <literal value="bottom"/> - <literal value="text-bottom"/> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="percentage"/> - <regexp name="length"/> - </regexp-list> - </property> - - <property name="font-family" - description="This property specifies a prioritized list of font family names and/or generic family names."> - <category-list> - <category value="visual" /> - </category-list> - <!-- allowing only generic font families --> - <literal-list> - <literal value="serif" /> - <literal value="courier" /> - <literal value="courier new" /> - <literal value="arial" /> - <literal value="lucida console" /> - <literal value="sans-serif" /> - <literal value="cursive" /> - <literal value="verdana" /> - <literal value="fantasy" /> - <literal value="monospace" /> - </literal-list> - <!-- FIXME:RH should be removed, after fix of http://code.google.com/p/owaspantisamy/issues/detail?id=49 --> - <regexp-list> - <regexp value="[\w,\-'" ]+"/> - </regexp-list> - </property> - <property name="background" description="The 'background' property is a shorthand property for setting the individual background properties (i.e., 'background-color', 'background-image', 'background-repeat', 'background-attachment' and 'background-position') at the same place in the style sheet."> - <literal-list> - <literal value="inherit"/> - </literal-list> - <shorthand-list> - <shorthand name="background-color"/> - <shorthand name="background-image"/> - <shorthand name="background-repeat"/> - <shorthand name="background-position"/> - </shorthand-list> - </property> - <property name="background-color" - description="This property sets the background color of an element, either a <color> value or the keyword 'transparent', to make the underlying colors shine through."> - <literal-list> - <literal value="transparent" /> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="colorName" /> - <regexp name="colorCode" /> - <regexp name="rgbCode" /> - <regexp name="systemColor" /> - </regexp-list> - </property> - <property name="background-image" description="This property sets the background image of an element."> - <literal-list> - <literal value="none"/> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="cssOffsiteUri"/> - <regexp name="cssOnsiteUri"/> - </regexp-list> - </property> - - <property name="background-position" description="If a background image has been specified, this property specifies its initial position."> - <literal-list> - <literal value="top"/> - <literal value="center"/> - <literal value="bottom"/> - <literal value="left"/> - <literal value="center"/> - <literal value="right"/> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="percentage"/> - <regexp name="length"/> - </regexp-list> - </property> - - <property name="background-repeat" description="If a background image is specified, this property specifies whether the image is repeated (tiled), and how."> - <literal-list> - <literal value="repeat"/> - <literal value="repeat-x"/> - <literal value="repeat-y"/> - <literal value="no-repeat"/> - <literal value="inherit"/> - </literal-list> - </property> - <property name="color" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="colorName"/> - <regexp name="colorCode"/> - <regexp name="rgbCode"/> - <regexp name="systemColor"/> - </regexp-list> - </property> - <property name="font-size" default="medium" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="absolute-size"/> - <regexp name="relative-size"/> - <regexp name="length"/> - <regexp name="percentage"/> - </regexp-list> - </property> - - <property name="border-color" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="transparent"/> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="colorName"/> - <regexp name="colorCode"/> - <regexp name="rgbCode"/> - <regexp name="systemColor"/> - </regexp-list> - </property> - <property name="border-top-color" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="colorName"/> - <regexp name="colorCode"/> - <regexp name="rgbCode"/> - <regexp name="systemColor"/> - </regexp-list> - </property> - <property name="border-right-color" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="colorName"/> - <regexp name="colorCode"/> - <regexp name="rgbCode"/> - <regexp name="systemColor"/> - </regexp-list> - </property> - <property name="border-bottom-color" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="colorName"/> - <regexp name="colorCode"/> - <regexp name="rgbCode"/> - <regexp name="systemColor"/> - </regexp-list> - </property> - <property name="border-left-color" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="colorName"/> - <regexp name="colorCode"/> - <regexp name="rgbCode"/> - <regexp name="systemColor"/> - </regexp-list> - </property> - - - <!-- begin medium properties --> - <property name="border-style" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - <literal value="none" /> - <literal value="hidden" /> - <literal value="dotted" /> - <literal value="dashed" /> - <literal value="solid" /> - <literal value="double" /> - <literal value="groove" /> - <literal value="ridge" /> - <literal value="inset" /> - <literal value="outset" /> - </literal-list> - </property> - <property name="border-top-style" default="none" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - </property> - <property name="border-right-style" default="none" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="border-bottom-style" default="none" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="border-left-style" default="none" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="border-top-width" default="medium" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-width" /> - </shorthand-list> - </property> - <property name="border-right-width" default="medium" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-width" /> - </shorthand-list> - </property> - <property name="border-bottom-width" default="medium" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-width" /> - </shorthand-list> - </property> - <property name="border-left-width" default="medium" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-width" /> - </shorthand-list> - </property> - <property name="border-width" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - <literal value="thin" /> - <literal value="medium" /> - <literal value="thick" /> - </literal-list> - <regexp-list> - <regexp name="length" /> - </regexp-list> - </property> - <property name="margin" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - <literal value="auto" /> - </literal-list> - <regexp-list> - <regexp name="positiveLength" /> - <regexp name="positivePercentage" /> - </regexp-list> - </property> - <property name="margin-top" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="margin" /> - </shorthand-list> - </property> - <property name="margin-right" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="margin" /> - </shorthand-list> - </property> - <property name="margin-bottom" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="margin" /> - </shorthand-list> - </property> - <property name="margin-left" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="margin" /> - </shorthand-list> - </property> - <property name="outline-style" default="none" description=""> - <category-list> - <category value="visual" /> - <category value="interactive" /> - </category-list> - - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="outline-width" default="medium" - description=""> - <category-list> - <category value="visual" /> - <category value="interactive" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-width" /> - </shorthand-list> - </property> - <property name="padding" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="length" /> - <regexp name="percentage" /> - </regexp-list> - </property> - <property name="padding-top" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="padding" /> - </shorthand-list> - </property> - <property name="padding-right" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="padding" /> - </shorthand-list> - </property> - <property name="padding-bottom" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="padding" /> - </shorthand-list> - </property> - <property name="padding-left" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="padding" /> - </shorthand-list> - </property> - <!-- end medium properties --> - - <!-- begin hard properties --> - <property name="border" description=""> - <category-list> - <category value="visual" /> - </category-list> - - <literal-list> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="colorName" /> - <regexp name="colorCode" /> - <regexp name="rgbCode" /> - <regexp name="systemColor" /> - </regexp-list> - <shorthand-list> - <shorthand name="border-width" /> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="border-top" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="colorName" /> - <regexp name="colorCode" /> - <regexp name="rgbCode" /> - <regexp name="systemColor" /> - </regexp-list> - <shorthand-list> - <shorthand name="border-top-width" /> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="border-right" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="colorName" /> - <regexp name="colorCode" /> - <regexp name="rgbCode" /> - <regexp name="systemColor" /> - </regexp-list> - <shorthand-list> - <shorthand name="border-top-width" /> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="border-bottom" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="colorName" /> - <regexp name="colorCode" /> - <regexp name="rgbCode" /> - <regexp name="systemColor" /> - </regexp-list> - <shorthand-list> - <shorthand name="border-top-width" /> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="border-left" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="colorName" /> - <regexp name="colorCode" /> - <regexp name="rgbCode" /> - <regexp name="systemColor" /> - </regexp-list> - <shorthand-list> - <shorthand name="border-top-width" /> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="cue" description=""> - <category-list> - <category value="aural" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="cue-before" /> - <shorthand name="cue-after" /> - </shorthand-list> - </property> - <property name="list-style" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="list-style-type" /> - <shorthand name="list-style-position" /> - <shorthand name="list-style-image" /> - </shorthand-list> - </property> - <property name="marks" default="none" description=""> - <category-list> - <category value="visual" /> - <category value="paged" /> - </category-list> - <literal-list> - <literal value="crop" /> - <literal value="cross" /> - <literal value="none" /> - <literal value="inherit" /> - </literal-list> - </property> - <property name="outline" description=""> - <category-list> - <category value="visual" /> - <category value="interactive" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="outline-color" /> - <shorthand name="outline-style" /> - <shorthand name="outline-width" /> - </shorthand-list> - </property> - <property name="pause" description=""> - <category-list> - <category value="aural" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="time" /> - <regexp name="percentage" /> - </regexp-list> - </property> - <property name="text-decoration" default="none" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="none" /> - <literal value="underline" /> - <literal value="overline" /> - <literal value="line-through" /> - <literal value="blink" /> - <literal value="inherit" /> - </literal-list> - </property> - <!-- end hard properties --> - - </css-rules> -</anti-samy-rules> \ No newline at end of file diff --git a/src/main/java/org/olat/core/util/filter/impl/_resources/antisamy-wiki.xml b/src/main/java/org/olat/core/util/filter/impl/_resources/antisamy-wiki.xml deleted file mode 100644 index 03fcb66d2ba..00000000000 --- a/src/main/java/org/olat/core/util/filter/impl/_resources/antisamy-wiki.xml +++ /dev/null @@ -1,1321 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!-- - TinyMCE policy download from trunk adapted for OLAT - Version found at 30.07.2009, Adaption made by frentix GmbH ---> - -<anti-samy-rules xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="antisamy.xsd"> - - <directives> - <directive name="omitXmlDeclaration" value="true" /> - <directive name="omitDoctypeDeclaration" value="true" /> - <directive name="maxInputSize" value="1000000" /> - <directive name="embedStyleSheets" value="false" /> - <directive name="useXHTML" value="true" /> - <directive name="formatOutput" value="false" /> - <directive name="entityEncodeIntlChars" value="true" /> - <directive name="preserveSpace" value="true" /> - </directives> - - <common-regexps> - <regexp name="anything" value=".*" /> - <!-- - From W3C: - This attribute assigns a class name or set of class names to an - element. Any number of elements may be assigned the same class - name or names. Multiple class names must be separated by white - space characters. - --> - <regexp name="htmlTitle" - value="[a-zA-Z0-9\s-_',:\[\]!\./\\\(\)%&;\+#]*" /> - <regexp name="htmlClass" value="[a-zA-Z0-9\s,-_]+" /> - - <!-- force non-empty with a '+' at the end instead of '*' - --> - <regexp name="olatInternalURL" - value="javascript:parent\.gotonode\(\d+\)" /> - <regexp name="onsiteURL" - value="([\p{L}\p{N}\p{Zs}/\.\?=&\-~_#])+" /> - - <regexp name="offsiteURL" - value="(\s)*((ht)tp(s?)://|mailto:)[\p{L}\p{N}]+[\p{L}\p{N}\p{Zs}\.\#@\$%\+&;:\-_~,\?=/!\(\)]*(\s)*" /> - <!-- - <regexp name="offsiteURL" - value="(\s)*(http(s?)://|mailto:)[A-Za-z0-9]+[~a-zA-Z0-9-_\.@#$%&;:,\?=/\+!]*(\s)*" /> - --> - <!-- This is for resources referenced from CSS (such as background images and other imported stylesheets) --> - <regexp name="cssOnsiteUri" value="url\(([\p{L}\p{N}\\/\.\?=\#&;\-_~]+|\#(\w)+)\)"/> - <regexp name="cssOffsiteUri" value="url\((\s)*(http(s?)://)[\p{L}\p{N}]+[~\p{L}\p{N}\p{Zs}\-_\.@#$%&;:,\?=/\+!]*(\s)*\)"/> - - <regexp name="paragraph" - value="([\p{L}\p{N},'\.\s\-_\(\)]|&[0-9]{2};)*" /> - - <regexp name="numberOrPercent" value="(\d)+(%{0,1})" /> - <regexp name="number" value="[0-9]+" /> - <regexp name="length" - value="((-|\+)?0|(-|\+)?([0-9]+(.[0-9]+)?)(em|ex|px|in|cm|mm|pt|pc))" /> - <regexp name="positiveLength" value="((\+)?0|(\+)?([0-9]+(.[0-9]+)?)(em|ex|px|in|cm|mm|pt|pc))"/> - <regexp name="percentage" value="(-|\+)?([0-9]+(.[0-9]+)?)%" /> - <regexp name="positivePercentage" value="(\+)?([0-9]+(.[0-9]+)?)%"/> - <regexp name="absolute-size" value="(xx-small|x-small|small|medium|large|x-large|xx-large)"/> - <regexp name="relative-size" value="(larger|smaller)"/> - - <!-- The 16 colors defined by the HTML Spec (also used by the CSS Spec) --> - <regexp name="colorName" - value="(aqua|black|blue|fuchsia|gray|grey|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)" /> - <!-- HTML/CSS Spec allows 3 or 6 digit hex to specify color --> - <regexp name="colorCode" - value="(#([0-9a-fA-F]{6}|[0-9a-fA-F]{3}))" /> - <!-- Used for CSS Color specifications (complex regexp expresses integer values of 0-255) --> - <regexp name="rgbCode" - value="rgb\(([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]),([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]),([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\)" /> - <!-- CSS2 Allowed System Color Values --> - <regexp name="systemColor" - value="(activeborder|activecaption|appworkspace|background|buttonface|buttonhighlight|buttonshadow|buttontext|captiontext|graytext|highlight|highlighttext|inactiveborder|inactivecaption|inactivecaptiontext|infobackground|infotext|menu|menutext|scrollbar|threeddarkshadow|threedface|threedhighlight|threedlightshadow|threedshadow|window|windowframe|windowtext)" /> - - - </common-regexps> - - <!-- - Tag.name = a, b, div, body, etc. - Tag.action = filter: remove tags, but keep content, validate: keep content as long as it passes rules, remove: remove tag and contents - Attribute.name = id, class, href, align, width, etc. - Attribute.onInvalid = what to do when the attribute is invalid, e.g., remove the tag (removeTag), remove the attribute (removeAttribute), filter the tag (filterTag) - Attribute.description = What rules in English you want to tell the users they can have for this attribute. Include helpful things so they'll be able to tune their HTML - --> - - <!-- - Some attributes are common to all (or most) HTML tags. There aren't many that qualify for this. You have to make sure there's no - collisions between any of these attribute names with attribute names of other tags that are for different purposes. - --> - - <common-attributes> - <attribute name="id" description="The 'id' of any HTML attribute should not contain anything besides letters and numbers"> - <regexp-list> - <regexp value="[a-zA-Z0-9_\-\:]+"/> - </regexp-list> - </attribute> - - <attribute name="class" - description="The 'class' of any HTML attribute is usually a single word, but it can also be a list of class names separated by spaces"> - <regexp-list> - <regexp name="htmlClass" /> - </regexp-list> - </attribute> - - <attribute name="lang" - description="The 'lang' attribute tells the browser what language the element's attribute values and content are written in"> - <regexp-list> - <regexp value="[a-zA-Z]{2,20}" /> - </regexp-list> - </attribute> - - <attribute name="title" - description="The 'title' attribute provides text that shows up in a 'tooltip' when a user hovers their mouse over the element"> - <regexp-list> - <regexp name="htmlTitle" /> - </regexp-list> - </attribute> - - <attribute name="href" onInvalid="filterTag"> - - <regexp-list> - <regexp name="onsiteURL" /> - <regexp name="offsiteURL" /> - <regexp name="olatInternalURL" /> - <!-- - --> - </regexp-list> - </attribute> - - <attribute name="align" - description="The 'align' attribute of an HTML element is a direction word, like 'left', 'right' or 'center'"> - - <literal-list> - <literal value="center" /> - <literal value="left" /> - <literal value="right" /> - <literal value="justify" /> - <literal value="char" /> - </literal-list> - </attribute> - <attribute name="style" - description="The 'style' attribute provides the ability for users to change many attributes of the tag's contents using a strict syntax" /> - - <attribute name="alt" - description="The 'alt' attribute provides alternative text to users when its visual representation is not available"> - <regexp-list> - <regexp name="paragraph" /> - </regexp-list> - </attribute> - - <!-- Common positioning attributes --> - - <attribute name="width"> - <regexp-list> - <regexp name="numberOrPercent" /> - </regexp-list> - </attribute> - - <attribute name="height"> - <regexp-list> - <regexp name="numberOrPercent" /> - </regexp-list> - </attribute> - - <attribute name="align" - description="The 'align' attribute of an HTML element is a direction word, like 'left', 'right' or 'center'"> - <literal-list> - <literal value="center" /> - <literal value="middle" /> - <literal value="left" /> - <literal value="right" /> - <literal value="justify" /> - <literal value="char" /> - </literal-list> - </attribute> - - <attribute name="valign" - description="The 'valign' attribute of an HTML attribute is a direction word, like 'baseline','bottom','middle' or 'top'"> - <literal-list> - <literal value="baseline" /> - <literal value="bottom" /> - <literal value="middle" /> - <literal value="top" /> - </literal-list> - </attribute> - - <attribute name="border"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <attribute name="dir" - description="The 'dir' attribute of an HTML attribute assigns a reading direction, like 'ltr' or 'rtl' "> - <literal-list> - <literal value="ltr" /> - <literal value="rtl" /> - </literal-list> - </attribute> - - <!-- Table attributes --> - <attribute name="rules" description="The 'rules' attribute of a table specifies where to show rules inside table. "> - <literal-list> - <literal value="none" /> - <literal value="rows" /> - <literal value="cols" /> - <literal value="groups" /> - <literal value="all" /> - </literal-list> - </attribute> - - <attribute name="summary" description="The 'summary' attribute of a table holds an abstract of table content mainly for screen readers. "> - <regexp-list> - <regexp name="paragraph" /> - </regexp-list> - </attribute> - - <attribute name="border"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <attribute name="cellpadding"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <attribute name="cellspacing"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <attribute name="colspan"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <attribute name="rowspan"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <attribute name="background"> - <regexp-list> - <regexp name="onsiteURL" /> - </regexp-list> - </attribute> - - <attribute name="bgcolor"> - <regexp-list> - <regexp name="colorName" /> - <regexp name="colorCode" /> - </regexp-list> - </attribute> - - <attribute name="abbrev"> - <regexp-list> - <regexp name="paragraph" /> - </regexp-list> - </attribute> - - <attribute name="headers" - description="The 'headers' attribute is a space-separated list of cell IDs"> - <regexp-list> - <regexp value="[a-zA-Z0-9\s*]*" /> - </regexp-list> - </attribute> - - <attribute name="charoff"> - <regexp-list> - <regexp value="numberOrPercent" /> - </regexp-list> - </attribute> - - <attribute name="char"> - <regexp-list> - <regexp value=".*{0,1}" /> - </regexp-list> - </attribute> - - <attribute name="axis" - description="The 'headers' attribute is a comma-separated list of related header cells"> - <regexp-list> - <regexp value="[a-zA-Z0-9\s*,]*" /> - </regexp-list> - </attribute> - - <attribute name="nowrap" - description="The 'nowrap' attribute tells the browser not to wrap text that goes over one line"> - <regexp-list> - <regexp name="anything" /> - <!-- <regexp value="(nowrap){0,1}"/> --> - </regexp-list> - </attribute> - - <attribute name="scope" - description="The 'scope' attribute defines what's covered by the header cells"> - <literal-list> - <literal value="row" /> - <literal value="col" /> - <literal value="rowgroup" /> - <literal value="colgroup" /> - </literal-list> - </attribute> - - </common-attributes> - - <!-- - This requires normal updates as browsers continue to diverge from the W3C and each other. As long as the browser wars continue - this is going to continue. I'm not sure war is the right word for what's going on. Doesn't somebody have to win a war after - a while? - - - --> - - <global-tag-attributes> - <attribute name="id" /> - <attribute name="title" /> - <attribute name="lang" /> - <attribute name="style" /> - <attribute name="dir" /> - </global-tag-attributes> - - <tags-to-encode> - <tag>g</tag> - <tag>grin</tag> - </tags-to-encode> - - - - - - - - - - - <tag-rules> - <tag name="h1" action="validate" > - <attribute name="class" /> - </tag> - <tag name="h2" action="validate" > - <attribute name="class" /> - </tag> - <tag name="h3" action="validate" > - <attribute name="class" /> - </tag> - <tag name="h4" action="validate" > - <attribute name="class" /> - </tag> - <tag name="h5" action="validate" > - <attribute name="class" /> - </tag> - <tag name="h6" action="validate" > - <attribute name="class" /> - </tag> - - <!-- Remove --> - - <tag name="script" action="remove" /> - <tag name="noscript" action="remove" /> - <tag name="iframe" action="remove" /> - <tag name="frameset" action="remove" /> - <tag name="frame" action="remove" /> - <tag name="noframes" action="remove" /> - <tag name="head" action="remove" /> - <tag name="title" action="remove" /> - <tag name="base" action="remove" /> - <tag name="style" action="remove" /> - <tag name="link" action="remove" /> - <tag name="input" action="remove" /> - <tag name="textarea" action="remove" /> - - <!-- Truncate --> - <tag name="br" action="truncate" /> - - <!-- Validate --> - <tag name="hr" action="validate"/> - - <tag name="p" action="validate"> - <attribute name="align" /> - </tag> - <tag name="div" action="validate" > - <attribute name="class" /> - </tag> - <tag name="span" action="validate"> - <attribute name="class" /> - </tag> - <!-- necessary for font-awesome icons --> - <tag name="i" action="validate" > - <attribute name="class" /> - </tag> - - <tag name="b" action="validate" /> - <tag name="strong" action="validate" /> - <tag name="s" action="validate" /> - <tag name="strike" action="validate" /> - <tag name="u" action="validate" /> - <tag name="em" action="validate" /> - <tag name="blockquote" action="validate" > - <attribute name="class" /> - </tag> - <tag name="pre" action="validate" /> - <tag name="center" action="validate" /> - <tag name="tt" action="truncate" /> - - <tag name="a" action="validate"> - <attribute name="class" /> - <attribute name="href" onInvalid="filterTag" /> - <attribute name="alt" /> - <attribute name="name"> - <regexp-list> - <regexp value="[a-zA-Z0-9_\-\:]+"/> - </regexp-list> - </attribute> - <attribute name="onclick"> - <literal-list> - <literal value="o_XHRWikiEvent(this);" /> - <literal value="o_XHRWikiEvent(this);return(false);" /> - </literal-list> - </attribute> - <attribute name="target"> - <literal-list> - <literal value="_blank" /> - </literal-list> - </attribute> - <attribute name="nohref"> - <literal-list> - <literal value="nohref" /> - <literal value="" /> - </literal-list> - </attribute> - <attribute name="rel"> - <literal-list> - <literal value="nofollow" /> - </literal-list> - </attribute> - </tag> - - <!-- List tags - --> - <tag name="ul" action="validate" > - <attribute name="class" /> - </tag> - <tag name="ol" action="validate" > - <attribute name="class" /> - </tag> - <tag name="li" action="validate" /> - <tag name="dl" action="validate" /> - <tag name="dt" action="validate" /> - <tag name="dd" action="validate" /> - - <!-- Image & image related tags --> - <tag name="figure" action="validate" > - <attribute name="class" /> - </tag> - <tag name="figcaption" action="validate" > - <attribute name="class" /> - </tag> - - <tag name="img" action="validate"> - <attribute name="src" onInvalid="removeTag"> - <regexp-list> - <regexp name="onsiteURL" /> - <regexp name="offsiteURL" /> - </regexp-list> - </attribute> - <attribute name="class" /> - <attribute name="alt" /> - <attribute name="height" /> - <attribute name="width" /> - <attribute name="border" /> - <attribute name="align" /> - - <attribute name="hspace"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - - <attribute name="vspace"> - <regexp-list> - <regexp name="number" /> - </regexp-list> - </attribute> - </tag> - - - <tag name="sub" action="validate" /> - <tag name="sup" action="validate" /> - <tag name="caption" action="validate" /> - - - <!-- Table tags (tbody, thead, tfoot)--> - - <tag name="thead" action="validate"> - <attribute name="align" /> - <attribute name="char" /> - <attribute name="charoff" /> - <attribute name="valign" /> - </tag> - - <tag name="tbody" action="validate"> - <attribute name="align" /> - <attribute name="char" /> - <attribute name="charoff" /> - <attribute name="valign" /> - </tag> - - <tag name="tfoot" action="validate"> - <attribute name="align" /> - <attribute name="char" /> - <attribute name="charoff" /> - <attribute name="valign" /> - </tag> - - <tag name="table" action="validate"> - <attribute name="class" /> - <attribute name="height" /> - <attribute name="width" /> - <attribute name="border" /> - <attribute name="bgcolor" /> - <attribute name="cellpadding" /> - <attribute name="cellspacing" /> - <attribute name="background" /> - <attribute name="align" /> - <attribute name="rules" /> - <attribute name="summary" /> - <attribute name="noresize"> - <literal-list> - <literal value="noresize" /> - <literal value="" /> - </literal-list> - </attribute> - </tag> - - <tag name="td" action="validate"> - <attribute name="background" /> - <attribute name="bgcolor" /> - <attribute name="abbrev" /> - <attribute name="axis" /> - <attribute name="headers" /> - <attribute name="scope" /> - <attribute name="nowrap" /> - <attribute name="height" /> - <attribute name="width" /> - <attribute name="align" /> - <attribute name="char" /> - <attribute name="charoff" /> - <attribute name="valign" /> - <attribute name="colspan" /> - <attribute name="rowspan" /> - </tag> - - <tag name="th" action="validate"> - <attribute name="abbrev" /> - <attribute name="axis" /> - <attribute name="headers" /> - <attribute name="scope" /> - <attribute name="nowrap" /> - <attribute name="bgcolor" /> - <attribute name="height" /> - <attribute name="width" /> - <attribute name="align" /> - <attribute name="char" /> - <attribute name="charoff" /> - <attribute name="valign" /> - <attribute name="colspan" /> - <attribute name="rowspan" /> - </tag> - - <tag name="tr" action="validate"> - <attribute name="class" /> - <attribute name="height" /> - <attribute name="width" /> - <attribute name="align" /> - <attribute name="valign" /> - <attribute name="char" /> - <attribute name="charoff" /> - <attribute name="background" /> - </tag> - - <tag name="init" action="validate"> - - </tag> - - </tag-rules> - - - - - - - - <css-rules> - - <property name="height" default="auto" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="auto" /> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="length" /> - <regexp name="percentage" /> - </regexp-list> - </property> - <property name="width" default="auto" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="auto" /> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="length" /> - <regexp name="percentage" /> - </regexp-list> - </property> - - <property name="float" default="none" - description=""> - - <category-list> - <category value="visual" /> - </category-list> - - <literal-list> - <literal value="left" /> - <literal value="right" /> - <literal value="none" /> - <literal value="inherit" /> - </literal-list> - </property> - - <property name="text-decoration" default="none" - description=""> - - <category-list> - <category value="visual" /> - </category-list> - - <literal-list> - <literal value="underline" /> - <literal value="overline" /> - <literal value="line-through" /> - </literal-list> - </property> - - <property name="text-align" - description="This property describes how inline content of a block is aligned."> - <category-list> - <category value="visual" /> - </category-list> - <!-- For safety, ignoring string alignment which can be used to line table cells on characters --> - <literal-list> - <literal value="left" /> - <literal value="right" /> - <literal value="center" /> - <literal value="justify" /> - <literal value="inherit" /> - </literal-list> - </property> - - <property name="vertical-align" default="baseline" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="baseline"/> - <literal value="sub"/> - <literal value="super"/> - <literal value="top"/> - <literal value="text-top"/> - <literal value="middle"/> - <literal value="bottom"/> - <literal value="text-bottom"/> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="percentage"/> - <regexp name="length"/> - </regexp-list> - </property> - - <property name="font-family" - description="This property specifies a prioritized list of font family names and/or generic family names."> - <category-list> - <category value="visual" /> - </category-list> - <!-- allowing only generic font families --> - <literal-list> - <literal value="serif" /> - <literal value="courier" /> - <literal value="courier new" /> - <literal value="arial" /> - <literal value="lucida console" /> - <literal value="sans-serif" /> - <literal value="cursive" /> - <literal value="verdana" /> - <literal value="fantasy" /> - <literal value="monospace" /> - </literal-list> - <!-- FIXME:RH should be removed, after fix of http://code.google.com/p/owaspantisamy/issues/detail?id=49 --> - <regexp-list> - <regexp value="[\w,\-'" ]+"/> - </regexp-list> - </property> - <property name="background" description="The 'background' property is a shorthand property for setting the individual background properties (i.e., 'background-color', 'background-image', 'background-repeat', 'background-attachment' and 'background-position') at the same place in the style sheet."> - <literal-list> - <literal value="inherit"/> - </literal-list> - <shorthand-list> - <shorthand name="background-color"/> - <shorthand name="background-image"/> - <shorthand name="background-repeat"/> - <shorthand name="background-position"/> - </shorthand-list> - </property> - <property name="background-color" - description="This property sets the background color of an element, either a <color> value or the keyword 'transparent', to make the underlying colors shine through."> - <literal-list> - <literal value="transparent" /> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="colorName" /> - <regexp name="colorCode" /> - <regexp name="rgbCode" /> - <regexp name="systemColor" /> - </regexp-list> - </property> - <property name="background-image" description="This property sets the background image of an element."> - <literal-list> - <literal value="none"/> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="cssOffsiteUri"/> - <regexp name="cssOnsiteUri"/> - </regexp-list> - </property> - - <property name="background-position" description="If a background image has been specified, this property specifies its initial position."> - <literal-list> - <literal value="top"/> - <literal value="center"/> - <literal value="bottom"/> - <literal value="left"/> - <literal value="center"/> - <literal value="right"/> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="percentage"/> - <regexp name="length"/> - </regexp-list> - </property> - - <property name="background-repeat" description="If a background image is specified, this property specifies whether the image is repeated (tiled), and how."> - <literal-list> - <literal value="repeat"/> - <literal value="repeat-x"/> - <literal value="repeat-y"/> - <literal value="no-repeat"/> - <literal value="inherit"/> - </literal-list> - </property> - <property name="color" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="colorName"/> - <regexp name="colorCode"/> - <regexp name="rgbCode"/> - <regexp name="systemColor"/> - </regexp-list> - </property> - <property name="font-size" default="medium" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="absolute-size"/> - <regexp name="relative-size"/> - <regexp name="length"/> - <regexp name="percentage"/> - </regexp-list> - </property> - - <property name="border-color" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="transparent"/> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="colorName"/> - <regexp name="colorCode"/> - <regexp name="rgbCode"/> - <regexp name="systemColor"/> - </regexp-list> - </property> - <property name="border-top-color" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="colorName"/> - <regexp name="colorCode"/> - <regexp name="rgbCode"/> - <regexp name="systemColor"/> - </regexp-list> - </property> - <property name="border-right-color" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="colorName"/> - <regexp name="colorCode"/> - <regexp name="rgbCode"/> - <regexp name="systemColor"/> - </regexp-list> - </property> - <property name="border-bottom-color" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="colorName"/> - <regexp name="colorCode"/> - <regexp name="rgbCode"/> - <regexp name="systemColor"/> - </regexp-list> - </property> - <property name="border-left-color" description=""> - <category-list> - <category value="visual"/> - </category-list> - <literal-list> - <literal value="inherit"/> - </literal-list> - <regexp-list> - <regexp name="colorName"/> - <regexp name="colorCode"/> - <regexp name="rgbCode"/> - <regexp name="systemColor"/> - </regexp-list> - </property> - - - <!-- begin medium properties --> - <property name="border-style" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - <literal value="none" /> - <literal value="hidden" /> - <literal value="dotted" /> - <literal value="dashed" /> - <literal value="solid" /> - <literal value="double" /> - <literal value="groove" /> - <literal value="ridge" /> - <literal value="inset" /> - <literal value="outset" /> - </literal-list> - </property> - <property name="border-top-style" default="none" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - </property> - <property name="border-right-style" default="none" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="border-bottom-style" default="none" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="border-left-style" default="none" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="border-top-width" default="medium" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-width" /> - </shorthand-list> - </property> - <property name="border-right-width" default="medium" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-width" /> - </shorthand-list> - </property> - <property name="border-bottom-width" default="medium" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-width" /> - </shorthand-list> - </property> - <property name="border-left-width" default="medium" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-width" /> - </shorthand-list> - </property> - <property name="border-width" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - <literal value="thin" /> - <literal value="medium" /> - <literal value="thick" /> - </literal-list> - <regexp-list> - <regexp name="length" /> - </regexp-list> - </property> - <property name="margin" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - <literal value="auto" /> - </literal-list> - <regexp-list> - <regexp name="positiveLength" /> - <regexp name="positivePercentage" /> - </regexp-list> - </property> - <property name="margin-top" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="margin" /> - </shorthand-list> - </property> - <property name="margin-right" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="margin" /> - </shorthand-list> - </property> - <property name="margin-bottom" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="margin" /> - </shorthand-list> - </property> - <property name="margin-left" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="margin" /> - </shorthand-list> - </property> - <property name="outline-style" default="none" description=""> - <category-list> - <category value="visual" /> - <category value="interactive" /> - </category-list> - - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="outline-width" default="medium" - description=""> - <category-list> - <category value="visual" /> - <category value="interactive" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="border-width" /> - </shorthand-list> - </property> - <property name="padding" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="length" /> - <regexp name="percentage" /> - </regexp-list> - </property> - <property name="padding-top" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="padding" /> - </shorthand-list> - </property> - <property name="padding-right" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="padding" /> - </shorthand-list> - </property> - <property name="padding-bottom" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="padding" /> - </shorthand-list> - </property> - <property name="padding-left" default="0" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="padding" /> - </shorthand-list> - </property> - <!-- end medium properties --> - - <!-- begin hard properties --> - <property name="border" description=""> - <category-list> - <category value="visual" /> - </category-list> - - <literal-list> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="colorName" /> - <regexp name="colorCode" /> - <regexp name="rgbCode" /> - <regexp name="systemColor" /> - </regexp-list> - <shorthand-list> - <shorthand name="border-width" /> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="border-top" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="colorName" /> - <regexp name="colorCode" /> - <regexp name="rgbCode" /> - <regexp name="systemColor" /> - </regexp-list> - <shorthand-list> - <shorthand name="border-top-width" /> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="border-right" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="colorName" /> - <regexp name="colorCode" /> - <regexp name="rgbCode" /> - <regexp name="systemColor" /> - </regexp-list> - <shorthand-list> - <shorthand name="border-top-width" /> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="border-bottom" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="colorName" /> - <regexp name="colorCode" /> - <regexp name="rgbCode" /> - <regexp name="systemColor" /> - </regexp-list> - <shorthand-list> - <shorthand name="border-top-width" /> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="border-left" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="colorName" /> - <regexp name="colorCode" /> - <regexp name="rgbCode" /> - <regexp name="systemColor" /> - </regexp-list> - <shorthand-list> - <shorthand name="border-top-width" /> - <shorthand name="border-style" /> - </shorthand-list> - </property> - <property name="cue" description=""> - <category-list> - <category value="aural" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="cue-before" /> - <shorthand name="cue-after" /> - </shorthand-list> - </property> - <property name="list-style" description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="list-style-type" /> - <shorthand name="list-style-position" /> - <shorthand name="list-style-image" /> - </shorthand-list> - </property> - <property name="marks" default="none" description=""> - <category-list> - <category value="visual" /> - <category value="paged" /> - </category-list> - <literal-list> - <literal value="crop" /> - <literal value="cross" /> - <literal value="none" /> - <literal value="inherit" /> - </literal-list> - </property> - <property name="outline" description=""> - <category-list> - <category value="visual" /> - <category value="interactive" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <shorthand-list> - <shorthand name="outline-color" /> - <shorthand name="outline-style" /> - <shorthand name="outline-width" /> - </shorthand-list> - </property> - <property name="pause" description=""> - <category-list> - <category value="aural" /> - </category-list> - <literal-list> - <literal value="inherit" /> - </literal-list> - <regexp-list> - <regexp name="time" /> - <regexp name="percentage" /> - </regexp-list> - </property> - <property name="text-decoration" default="none" - description=""> - <category-list> - <category value="visual" /> - </category-list> - <literal-list> - <literal value="none" /> - <literal value="underline" /> - <literal value="overline" /> - <literal value="line-through" /> - <literal value="blink" /> - <literal value="inherit" /> - </literal-list> - </property> - <!-- end hard properties --> - - </css-rules> -</anti-samy-rules> \ No newline at end of file diff --git a/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType1.java b/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType1.java index 97ebb2a43bc..876e889895f 100644 --- a/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType1.java +++ b/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType1.java @@ -112,8 +112,7 @@ public class QTIExportFormatterCSVType1 extends QTIExportFormatter { // CELFI#107 String question = item.getQuestionText(); - //question = FilterFactory.getHtmlTagsFilter().filter(question); - question = FilterFactory.getXSSFilter(-1).filter(question); + question = FilterFactory.getXSSFilter().filter(question); question = FilterFactory.getHtmlTagsFilter().filter(question); if (question.length() > cut) { @@ -358,7 +357,7 @@ public class QTIExportFormatterCSVType1 extends QTIExportFormatter { sb.append(sep + sep + sep + sep); String question = element.getQuestionText(); if (tagless) { - question = FilterFactory.getXSSFilter(-1).filter(question); + question = FilterFactory.getXSSFilter().filter(question); question = FilterFactory.getHtmlTagsFilter().filter(question); } question = StringHelper.unescapeHtml(question); diff --git a/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType3.java b/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType3.java index 5c347a9073c..e45dd4a72aa 100644 --- a/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType3.java +++ b/src/main/java/org/olat/ims/qti/export/QTIExportFormatterCSVType3.java @@ -106,7 +106,7 @@ public class QTIExportFormatterCSVType3 extends QTIExportFormatter { // CELFI#107 String question = item.getQuestionText(); - question = FilterFactory.getXSSFilter(-1).filter(question); + question = FilterFactory.getXSSFilter().filter(question); question = FilterFactory.getHtmlTagsFilter().filter(question); if (question.length() > cut) { @@ -268,7 +268,7 @@ public class QTIExportFormatterCSVType3 extends QTIExportFormatter { sb.append(sep + sep + sep + sep); String question = element.getQuestionText(); if (tagless) { - question = FilterFactory.getXSSFilter(-1).filter(question); + question = FilterFactory.getXSSFilter().filter(question); question = FilterFactory.getHtmlTagsFilter().filter(question); } question = StringHelper.unescapeHtml(question); diff --git a/src/main/java/org/olat/ims/qti21/model/xml/Onyx38ToQtiWorksHandler.java b/src/main/java/org/olat/ims/qti21/model/xml/Onyx38ToQtiWorksHandler.java index 0ebeda205e6..7690a82eaf9 100644 --- a/src/main/java/org/olat/ims/qti21/model/xml/Onyx38ToQtiWorksHandler.java +++ b/src/main/java/org/olat/ims/qti21/model/xml/Onyx38ToQtiWorksHandler.java @@ -268,10 +268,21 @@ public class Onyx38ToQtiWorksHandler extends DefaultHandler2 { if(!envelopP && isCharacterRelevant(ch, start, length)) { xtw.writeStartElement("p"); int diff = trimStart(ch, start, length); - start += diff; - length -= diff; - envelopP = true; + if(diff > 0) { + start += diff; + length -= diff; + envelopP = true; + } + + if(start < 0) { + start = 0; + } + if(length > ch.length - start) { + length = ch.length - start; + } } + + xtw.writeCharacters(ch, start, length); } else if(rubricBlock) { rubricCharacterBuffer.append(ch, start, length); @@ -288,7 +299,7 @@ public class Onyx38ToQtiWorksHandler extends DefaultHandler2 { for(int i=start; i<end; i++) { char ch = chArray[i]; if(ch != '\n' && ch != '\r' && ch != '\t' && ch != ' ') { - return start - i; + return start + i; } } return 0; diff --git a/src/main/java/org/olat/ims/qti21/repository/handlers/CopyAndConvertVisitor.java b/src/main/java/org/olat/ims/qti21/repository/handlers/CopyAndConvertVisitor.java index d2b881a2112..1371933981b 100644 --- a/src/main/java/org/olat/ims/qti21/repository/handlers/CopyAndConvertVisitor.java +++ b/src/main/java/org/olat/ims/qti21/repository/handlers/CopyAndConvertVisitor.java @@ -26,7 +26,7 @@ import java.io.InputStream; import java.io.Writer; import java.net.URI; import java.net.URISyntaxException; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; @@ -198,7 +198,7 @@ class CopyAndConvertVisitor extends SimpleFileVisitor<Path> { private boolean convertXmlFile(Path inputFile, Path outputFile, InputType type, HandlerProvider provider) { File tmpFile = new File(WebappHelper.getTmpDir(), UUID.randomUUID() + ".xml"); try(InputStream in = Files.newInputStream(inputFile); - Writer out = Files.newBufferedWriter(tmpFile.toPath(), Charset.forName("UTF-8"))) { + Writer out = Files.newBufferedWriter(tmpFile.toPath(), StandardCharsets.UTF_8)) { XMLOutputFactory xof = XMLOutputFactory.newInstance(); XMLStreamWriter xtw = xof.createXMLStreamWriter(out); diff --git a/src/main/java/org/olat/modules/webFeed/FeedViewHelper.java b/src/main/java/org/olat/modules/webFeed/FeedViewHelper.java index 9d83dd70d3b..f3b18512155 100644 --- a/src/main/java/org/olat/modules/webFeed/FeedViewHelper.java +++ b/src/main/java/org/olat/modules/webFeed/FeedViewHelper.java @@ -367,7 +367,7 @@ public class FeedViewHelper { if (item.getFeed().isExternal()) { // Apply xss filter for security reasons. Only necessary for external // feeds (e.g. to not let them execute JS code in our OLAT environment) - Filter xssFilter = FilterFactory.getXSSFilter(description.length() + 1); + Filter xssFilter = FilterFactory.getXSSFilter(); itemDescription = xssFilter.filter(description); } else { // Add relative media base to media elements to display internal media @@ -399,7 +399,7 @@ public class FeedViewHelper { if (item.getFeed().isExternal()) { // Apply xss filter for security reasons. Only necessary for external // feeds (e.g. to not let them execute JS code in our OLAT environment) - Filter xssFilter = FilterFactory.getXSSFilter(content.length() + 1); + Filter xssFilter = FilterFactory.getXSSFilter(); itemContent = xssFilter.filter(content); } else { // Add relative media base to media elements to display internal media diff --git a/src/main/java/org/olat/modules/wiki/WikiArticleSearchForm.java b/src/main/java/org/olat/modules/wiki/WikiArticleSearchForm.java index da50a2f7cf3..c33cf6d74b3 100644 --- a/src/main/java/org/olat/modules/wiki/WikiArticleSearchForm.java +++ b/src/main/java/org/olat/modules/wiki/WikiArticleSearchForm.java @@ -77,24 +77,23 @@ public class WikiArticleSearchForm extends FormBasicController { @Override protected boolean validateFormLogic(UserRequest ureq) { - boolean allOk = true; + boolean allOk = super.validateFormLogic(ureq); String val = searchQuery.getValue(); searchQuery.clearError(); if(!StringHelper.containsNonWhitespace(val)) { searchQuery.setErrorKey("form.legende.mandatory", null); - allOk = false; + allOk &= false; } else if(StringHelper.xssScanForErrors(val)) { searchQuery.setErrorKey("form.legende.mandatory", null); searchQuery.setValue(""); - allOk = false; + allOk &= false; } - return allOk & super.validateFormLogic(ureq); + return allOk; } public String getQuery() { - String query = searchQuery.getValue(); - return query; + return searchQuery.getValue(); } } \ No newline at end of file diff --git a/src/main/java/org/olat/modules/wiki/gui/components/wikiToHtml/WikiMarkupRenderer.java b/src/main/java/org/olat/modules/wiki/gui/components/wikiToHtml/WikiMarkupRenderer.java index 38779fa7d6d..8d1da905367 100644 --- a/src/main/java/org/olat/modules/wiki/gui/components/wikiToHtml/WikiMarkupRenderer.java +++ b/src/main/java/org/olat/modules/wiki/gui/components/wikiToHtml/WikiMarkupRenderer.java @@ -108,7 +108,7 @@ public class WikiMarkupRenderer extends DefaultComponentRenderer { boolean xssScan = CoreSpringFactory.getImpl(WikiModule.class).isXSScanEnabled(); if(xssScan) { - content = FilterFactory.getXSSFilterForWiki(-1).filter(content); + content = FilterFactory.getXSSFilter().filter(content); } sb.append(Formatter.formatLatexFormulas(content)); } diff --git a/src/test/java/org/olat/core/util/filter/impl/XSSFilterParamTest.java b/src/test/java/org/olat/core/util/filter/impl/XSSFilterParamTest.java index 522203454d5..4c50a1c5a69 100644 --- a/src/test/java/org/olat/core/util/filter/impl/XSSFilterParamTest.java +++ b/src/test/java/org/olat/core/util/filter/impl/XSSFilterParamTest.java @@ -27,7 +27,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; -import org.olat.core.util.filter.Filter; +import org.owasp.html.PolicyFactory; /** * Description:<br> @@ -44,56 +44,54 @@ public class XSSFilterParamTest { @Parameters public static Collection<Object[]> data() { return Arrays.asList(new Object[][] { - { null, null }, { "", "" }, { "hello", "hello" }, - { "°+\"*ç%&/()=?`", "°+"*ç%&/()=?`" }, + { "<a href=\"mailto:foo@frentix.com\">bar</a>", "<a href=\"mailto:foo@frentix.com\">bar</a>" }, + { "°+\"*ç%&/()=?`", "°+"*ç%&/()=?`" }, { "Du & ich", "Du & ich" }, { "Du & ich", "Du & ich" }, - { "Du @ ich", "Du @ ich" }, { "1<2", "1<2" }, { "2>1", "2>1" }, - { " "," " }, + { " ","\u00A0" },// was // test_balancing_tags { "<b>hello", "<b>hello</b>" }, { "<b>hello", "<b>hello</b>" }, - { "hello<b>", "hello" }, + { "hello<b>", "hello<b></b>" },// was skipped <b> // 10 { "hello</b>", "hello" }, - { "hello<b/>", "hello" }, + { "hello<b/>", "hello<b></b>" },// was skipped <b> // 12 { "<b><b><b>hello", "<b><b><b>hello</b></b></b>" }, - { "</b><b>", "" }, + { "</b><b>", "<b></b>" }, // was skipped { "<b><i>hello</b>", "<b><i>hello</i></b>" }, { "<b><i><em>hello</em></b>", "<b><i><em>hello</em></i></b>" }, // test_end_slashes() - { "<img>", "<img />" }, + { "<img src='test.html' />", "<img src=\"test.html\" />" }, { "<img/>", "<img />" }, - { "<b/></b>", "" }, +/* 20 */ { "<b/></b>", "<b></b>" }, // was empty // test_balancing_angle_brackets() { "<img src=\"foo\"", "<img src=\"foo\" />" }, { "b>", "b>" }, { "<img src=\"foo\"/", "<img src=\"foo\" />" }, { ">", ">" }, - //FIXME: what to do? it should work if in another tag! - // { "foo<b", "foo<b" }, - // { "<span>foo<b</span>", "<span>foo<b</span>" }, - // { "b>foo", "b>foo" }, - // { "><b", "><b" }, - // { "><f", "><f" }, - { "b><", "b><" }, - { "><b>", ">" }, + { "foo<b", "foo<b></b>" }, + { "<span>foo<b</span>", "<span>foo<b></b></span>" }, + { "b>foo", "b>foo" }, + { "><b", "><b></b>" }, + { "><f", ">" }, +/* 30 */ { "b><", "b><" }, + { "><b>", "><b></b>" }, // test_attributes() { "<img src=foo>", "<img src=\"foo\" />" }, { "<img asrc=foo>", "<img />" }, - { "<span title=\"bli\" > </span>", "<span title=\"bli\"> </span>" }, - { "<img src=test test>", "<img src=\"test\" />" }, - { "<img src=\"blibla\" alt=\"blubb\">", "<img alt=\"blubb\" src=\"blibla\" />" }, + { "<span title=\"bli\" > </span>", "<span title=\"bli\">\u00A0</span>" }, + { "<img src=test test>", "<img src=\"test%20test\" />" }, + { "<img src=\"blibla\" alt=\"blubb\">", "<img src=\"blibla\" alt=\"blubb\" />" }, //alt cannot contain < , title will allow it for jsMath { "<img src=\"blibla\" alt=\"a>b\">", "<img src=\"blibla\" />" }, // test_disallow_script_tags() { "script", "script" }, { "<script>", "" }, // { "<script", "<script" }, - { "<script", "" }, +/* 40 */ { "<script", "" }, { "<script/>", "" }, { "</script>", "" }, { "<script woo=yay>", "" }, @@ -103,91 +101,92 @@ public class XSSFilterParamTest { { "<script<script>>", "" }, { "<<script>script<script>>", "<" }, { "<<script><script>>", "<" }, - { "<<script>script>>", "<" }, +/* 50 */ { "<<script>script>>", "<" }, { "<<script<script>>", "<" }, // test_protocols() { "<a href=\"http://foo\">bar</a>", "<a href=\"http://foo\">bar</a>" }, // we don't allow ftp. - //FIXME: is this ok? (strip link) - // { "<a href=\"ftp://foo\">bar</a>", "<a href=\"#foo\">bar</a>" }, - { "<a href=\"ftp://foo\">bar</a>", "bar" }, + { "<a href=\"ftp://foo\">bar</a>", "<a>bar</a>" }, + { "<a href=\"ftp://foo\">bar</a>", "<a>bar</a>" }, { "<a href=\"mailto:foo\">bar</a>", "<a href=\"mailto:foo\">bar</a>" }, - { "<a href=\"mailto:foo@frentix.com\">bar</a>", "<a href=\"mailto:foo@frentix.com\">bar</a>" }, - { "<a href=\"javascript:foo\">bar</a>", "bar" }, - { "<a href=\"java script:foo\">bar</a>", "bar" }, - { "<a href=\"java\tscript:foo\">bar</a>", "bar" }, - { "<a href=\"java\nscript:foo\">bar</a>", "bar" }, - { "<a href=\"java" + String.valueOf((char) 1) + "script:foo\">bar</a>", "bar" }, - { "<a href=\"jscript:foo\">bar</a>", "bar" }, - { "<a href=\"vbscript:foo\">bar</a>", "bar" }, - { "<a href=\"view-source:foo\">bar</a>", "bar" }, - { "<a href=\"view-source@foo\">bar</a>", "bar" }, + { "<a href=\"javascript:foo\">bar</a>", "<a>bar</a>" }, + { "<a href=\"java script:foo\">bar</a>", "<a>bar</a>" }, + { "<a href=\"java\tscript:foo\">bar</a>", "<a>bar</a>" }, + { "<a href=\"java\nscript:foo\">bar</a>", "<a>bar</a>" }, +/* 60 */ { "<a href=\"java" + String.valueOf((char) 1) + "script:foo\">bar</a>", "<a>bar</a>" }, + { "<a href=\"jscript:foo\">bar</a>", "<a>bar</a>" }, + { "<a href=\"vbscript:foo\">bar</a>", "<a>bar</a>" }, + { "<a href=\"view-source:foo\">bar</a>", "<a>bar</a>" }, // test_link() { - { "<a href=\"blibla.html\" alt=\"blub\" target=\"_blank\">new window link</A>", "<a alt=\"blub\" href=\"blibla.html\" target=\"_blank\">new window link</a>" }, + { "<a href=\"blibla.html\" alt=\"blub\" target=\"_blank\">new window link</A>", "<a href=\"blibla.html\" alt=\"blub\" target=\"_blank\" rel=\"noopener noreferrer\">new window link</a>" }, // test_link_htmlEntities() { { "<a href=\"http://www.schreinersicht.ch/artikel/Mehr_als_nur_S&gen--496\">new window link</a>", "<a href=\"http://www.schreinersicht.ch/artikel/Mehr_als_nur_S&gen--496\">new window link</a>" }, - { "<a href=\"http://www.schreinersicht.ch/artikel/Mehr_als_nur_Sägen--496\">new window link</a>", "<a href=\"http://www.schreinersicht.ch/artikel/Mehr_als_nur_Sägen--496\">new window link</a>" }, - { "<a href=\"http://www.schreinersicht.ch/artikel/Mehr_als_nur_Ságen--496\">new window link</a>", "<a href=\"http://www.schreinersicht.ch/artikel/Mehr_als_nur_Ságen--496\">new window link</a>" }, + { "<a href=\"http://www.schreinersicht.ch/artikel/Mehr_als_nur_Sägen--496\">new window link</a>", "<a href=\"http://www.schreinersicht.ch/artikel/Mehr_als_nur_S\u00E4gen--496\">new window link</a>" }, + { "<a href=\"http://www.schreinersicht.ch/artikel/Mehr_als_nur_Sàgen--496\">new window link</a>", "<a href=\"http://www.schreinersicht.ch/artikel/Mehr_als_nur_S\u00E0gen--496\">new window link</a>" }, //escape unkown entity { "<a href=\"http://www.schreinersicht.ch/artikel/Mehr_als_nur_S&xss;gen--496\">new window link</a>", "<a href=\"http://www.schreinersicht.ch/artikel/Mehr_als_nur_S&xss;gen--496\">new window link</a>" }, //check if escaped result is allowed { "<a href=\"http://www.schreinersicht.ch/artikel/Mehr_als_nur_S&xss;gen--496\">new window link</a>", "<a href=\"http://www.schreinersicht.ch/artikel/Mehr_als_nur_S&xss;gen--496\">new window link</a>" }, // test_link_complexer(){ - { "<a class=\"o_icon_link_extern\" target=\"_blank\" href=\"http://www.frentix.com\" onclick=\"javascript:alert('hallo');\" title=\"a good link\">a complicated link</a>", - "<a class=\"o_icon_link_extern\" href=\"http://www.frentix.com\" target=\"_blank\" title=\"a good link\">a complicated link</a>" }, +/* 70 */ { "<a class=\"o_icon_link_extern\" target=\"_blank\" href=\"http://www.frentix.com\" onclick=\"javascript:alert('hallo');\" title=\"a good link\">a complicated link</a>", + "<a class=\"o_icon_link_extern\" target=\"_blank\" href=\"http://www.frentix.com\" title=\"a good link\" rel=\"noopener noreferrer\">a complicated link</a>" }, // test_self_closing_tags() { { "<img src=\"a\">", "<img src=\"a\" />" }, { "<img src=\"a\">foo</img>", "<img src=\"a\" />foo" }, { "</img>", "" }, // test_comments() { "<!-- a<b --->", "" }, - { "<!-- a<b -->don't remove me<!-- hello world -->", "don't remove me" }, + { "<!-- a<b -->don't remove me<!-- hello world -->", "don't remove me" }, { "<!-- a<b \n <!-- hello world \n -->", "" }, { "<!--comments1--> visible text <!--comments2-->", " visible text " }, // test_tiny_paragraph() { "<span>bliblablu</span>", "<span>bliblablu</span>" }, - { "<p style=\"text-align: right;\">right orientation</p>", "<p style=\"text-align: right;\">right orientation</p>" }, - { "<h1>Big font</h1>", "<h1>Big font</h1>" }, + { "<p style=\"text-align: right;\">right orientation</p>", "<p style=\"text-align:right\">right orientation</p>" }, +/* 80 */ { "<h1>Big font</h1>", "<h1>Big font</h1>" }, { "<h7>small font</h7>", "small font" }, - { "<span style=\"font-family: wingdings;\">invalid font</span>", "<span style=\"font-family: wingdings;\">invalid font</span>" }, - { "<span style=\"font-family: serif;\">invalid font</span>", "<span style=\"font-family: serif;\">invalid font</span>" }, - //FIXME:RH: to allow multiple fonts (as output from tiny) - //committed as bug: http://code.google.com/p/owaspantisamy/issues/detail?id=49 - // { "<span style=\"font-family: serif, arial;\">preformated</span>", "<span style=\"font-family: courier new , courier;\">preformated</span>" }, + { "<span style=\"font-family: wingdings;\">Wingdings font</span>", "<span style=\"font-family:'wingdings'\">Wingdings font</span>" }, + { "<span style=\"font-family: serif;\">Serif font</span>", "<span style=\"font-family:serif\">Serif font</span>" }, + { "<span style=\"font-family: serif, arial;\">preformated</span>", "<span style=\"font-family:serif , 'arial'\">preformated</span>" }, { "<span class=\"schoen\">irgendwas</span>", "<span class=\"schoen\">irgendwas</span>" }, // test_style_rgb(){ - { "<p style=\"background-color: rgb(0%,0,0);\">background</p>", "<p>background</p>" }, - { "<p style=\"background-color: rgba(100%,0,0);\">background</p>", "<p style=\"\">background</p>" }, - { "<p style=\"background-color: rgb(100,50,50);\">background</p>", "<p style=\"background-color: rgb(100,50,50);\">background</p>" }, + { "<p style=\"background-color: rgb(0%,0,0);\">background</p>", "<p style=\"background-color:rgb( 0% , 0 , 0 )\">background</p>" }, + { "<p style=\"background-color: rgba(100%,0,0);\">background</p>", "<p style=\"background-color:rgba( 100% , 0 , 0 )\">background</p>" }, + { "<p style=\"background-color: rgb(100,50,50);\">background</p>", "<p style=\"background-color:rgb( 100 , 50 , 50 )\">background</p>" }, // test_tiny_lists(){ //lists (output without \n as policy has formatOutput = false - { "<ul>\n<li>a list: adsf</li>\n<li>adsf</li>\n<li>adsfas</li>\n</ul>", "<ul>\n<li>a list: adsf</li>\n<li>adsf</li>\n<li>adsfas</li>\n</ul>" }, - { "<ol style=\"font-size: 20pt;\">\n<li>numbered list</li>\n<li>adf</li>\n<li>asdfa</li>\n</ol>", "<ol style=\"font-size: 20.0pt;\">\n<li>numbered list</li>\n<li>adf</li>\n<li>asdfa</li>\n</ol>" }, + { "<ul>\n<li>a list: adsf</li>\n<li>adsf</li>\n<li>adsfas</li>\n</ul>", "<ul><li>a list: adsf</li><li>adsf</li><li>adsfas</li></ul>" }, +/* 90 */ { "<ol style=\"font-size: 20pt;\">\n<li>numbered list</li>\n<li>adf</li>\n<li>asdfa</li>\n</ol>", "<ol style=\"font-size:20pt\"><li>numbered list</li><li>adf</li><li>asdfa</li></ol>" }, // test_tiny_tables() //tables - { "<table border=\"1\" style=\"width: 268px; height: 81px;\" class=\"table\">\n<caption>bliblablue</caption>\n<tbody>\n<tr>\n<td>\n<p>adsfadsf</p>\n</td>\n<td>asdf</td>\n</tr>\n<tr>\n<td>asf</td>\n<td>\n<p>asdf</p>\n</td>\n</tr>\n</tbody>\n</table>", "<table border=\"1\" class=\"table\" style=\"width: 268.0px;height: 81.0px;\">\n<caption>bliblablue</caption>\n<tbody>\n<tr>\n<td>\n<p>adsfadsf</p>\n</td>\n<td>asdf</td>\n</tr>\n<tr>\n<td>asf</td>\n<td>\n<p>asdf</p>\n</td>\n</tr>\n</tbody>\n</table>" }, - { "<tr style=\"background-color: rgb(46, 147, 209);\">\n<td style=\"border: 1px solid rgb(240, 68, 14);\">asf</td>\n<td>\n<p>asdf</p>\n</td>\n</tr>","\nasf\n\n<p>asdf</p>\n" }, + { "<table border=\"1\" style=\"width: 268px; height: 81px;\" class=\"table\">\n<caption>bliblablue</caption>\n<tbody>\n<tr>\n<td>\n<p>adsfadsf</p>\n</td>\n<td>asdf</td>\n</tr>\n<tr>\n<td>asf</td>\n<td>\n<p>asdf</p>\n</td>\n</tr>\n</tbody>\n</table>", + "<table border=\"1\" style=\"width:268px;height:81px\" class=\"table\"><caption>bliblablue</caption><tbody><tr><td>\n<p>adsfadsf</p>\n</td><td>asdf</td></tr><tr><td>asf</td><td>\n<p>asdf</p>\n</td></tr></tbody></table>" }, + { "<tr style=\"background-color: rgb(46, 147, 209);\">\n<td style=\"border: 1px solid rgb(240, 68, 14);\">asf</td>\n<td>\n<p>asdf</p>\n</td>\n</tr>", + "<table><tbody><tr style=\"background-color:rgb( 46 , 147 , 209 )\"><td style=\"border:1px solid rgb( 240 , 68 , 14 )\">asf</td><td>\n<p>asdf</p>\n</td></tr></tbody></table>" }, // test_tiny_singleElements(){ //sup/sub { "<p><sup>super</sup>script <sub>sub</sub>script</p>", "<p><sup>super</sup>script <sub>sub</sub>script</p>" }, // test_tiny_jsmath(){ - - { "<span title=\"a%20%3C%20b%20%3E%20c%20%3C%20/b%20%3E\"> </span>","<span title=\"a%20%3C%20b%20%3E%20c%20%3C%20/b%20%3E\"> </span>" }, + { "<span title=\"a%20%3C%20b%20%3E%20c%20%3C%20/b%20%3E\"> </span>","<span title=\"a%20%3C%20b%20%3E%20c%20%3C%20/b%20%3E\">\u00A0</span>" }, // should be saved with entities not with < etc... - // { "<span title=\"a>b\"> </span>", "<span title=\"a>b\"> </span>" }, + //{ "<span title=\"a>b\"> </span>", "<span title=\"a>b\"> </span>" }, // test_font_awesome() { // for now i tags must have at least a space to not b removed { "<i class=\"o_icon o_icon_dev\"> </i> ", "<i class=\"o_icon o_icon_dev\"> </i> " }, // test_figure() { // for now i tags must have at least a space to not b removed { "<figure class=\"image\"><img src=\"bla.png\" /><figcaption>gugs</figcaption></figure>", "<figure class=\"image\"><img src=\"bla.png\" /><figcaption>gugs</figcaption></figure>" }, - // test_big_tiny_output - { "<br>", "<br />" } + // more + { "<script>alert('hello');<//script>", "<script>alert('hello');<//script>" }, + { "Stéphane Rossé", "Stéphane Rossé" }, + { "<a href=\"http://localhost/win?test=go&go=test\">Test</a>", + "<a href=\"http://localhost/win?test=go&go=test\">Test</a>" }, +/* 100 */ { "<img src=\"/olat/edusharing/preview?objectUrl=ccrep://OpenOLAT/d5130470-14b4-4ad4-88b7-dfb3ebe943da&version=1.0\" data-es_identifier=\"2083dbe64f00b07232b11608ec0842fc\" data-es_objecturl=\"ccrep://OpenOLAT/d5130470-14b4-4ad4-88b7-dfb3ebe943da\" data-es_version=\"1.0\" data-es_version_current=\"1.0\" data-es_mediatype='i23' data-es_mimetype=\"image/png\" data-es_width=\"1000\" data-es_height=\"446\" data-es_first_edit=\"false\" class=\"edusharing\" alt=\"Bildschirmfoto 2018-11-07 um 16.09.49.png\" title=\"Bildschirmfoto 2018-11-07 um 16.09.49.png\" width=\"1000\" height=\"446\">", + "<img src=\"/olat/edusharing/preview?objectUrl=ccrep://OpenOLAT/d5130470-14b4-4ad4-88b7-dfb3ebe943da&version=1.0\" data-es_identifier=\"2083dbe64f00b07232b11608ec0842fc\" data-es_objecturl=\"ccrep://OpenOLAT/d5130470-14b4-4ad4-88b7-dfb3ebe943da\" data-es_version=\"1.0\" data-es_version_current=\"1.0\" data-es_mediatype=\"i23\" data-es_mimetype=\"image/png\" data-es_width=\"1000\" data-es_height=\"446\" data-es_first_edit=\"false\" class=\"edusharing\" alt=\"Bildschirmfoto 2018-11-07 um 16.09.49.png\" title=\"Bildschirmfoto 2018-11-07 um 16.09.49.png\" width=\"1000\" height=\"446\" />" + }, + { null, "" } // be tolerant }); } - - private Filter vFilter = new OWASPAntiSamyXSSFilter(-1, true); private String input; private String output; @@ -198,15 +197,9 @@ public class XSSFilterParamTest { } @Test - public void filter() { - String filterRes = vFilter.filter(input); - if (filterRes == output || filterRes.equals(output)){ - System.out.println("------------------------------------------------"); - } else { - System.out.println("---------------- E R R O R ---------------------"); - } - System.out.println(" Expected: " + output); - System.out.println("************************************************\n\n"); - Assert.assertEquals(output, filterRes); - } + public void filter() throws Exception { + PolicyFactory policy = OpenOLATPolicy.POLICY_DEFINITION; + String sanitized = policy.sanitize(input); + Assert.assertEquals(output, sanitized); + } } diff --git a/src/test/java/org/olat/core/util/filter/impl/XSSFilterTest.java b/src/test/java/org/olat/core/util/filter/impl/XSSFilterTest.java deleted file mode 100644 index 94b11dd3314..00000000000 --- a/src/test/java/org/olat/core/util/filter/impl/XSSFilterTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.core.util.filter.impl; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Assert; -import org.junit.Test; -import org.olat.core.util.filter.Filter; -import org.olat.core.util.filter.impl.OWASPAntiSamyXSSFilter.Variant; - -/** - * Description:<br> - * This test case tests special cases of the cross site scripting filter - * - * <P> - * Initial Date: 14.07.2009 <br> - * @author gnaegi - * @author Roman Haag, roman.haag@frentix.com - */ -public class XSSFilterTest { - - - private void t(String input, String result, Filter f) { - String filterRes = f.filter(input); - if (filterRes == result || filterRes.equals(result)){ - System.out.println("------------------------------------------------"); - } else { - System.out.println("---------------- E R R O R ---------------------"); - } - System.out.println(" Expected: " + result); - System.out.println("************************************************\n\n"); - Assert.assertEquals(result, filterRes); - } - - @Test - public void test_edusharing() { - String html = "<img src=\"/olat/edusharing/preview?objectUrl=ccrep://OpenOLAT/d5130470-14b4-4ad4-88b7-dfb3ebe943da&version=1.0\" data-es_identifier=\"2083dbe64f00b07232b11608ec0842fc\" data-es_objecturl=\"ccrep://OpenOLAT/d5130470-14b4-4ad4-88b7-dfb3ebe943da\" data-es_version=\"1.0\" data-es_version_current=\"1.0\" data-es_mediatype='i23' data-es_mimetype=\"image/png\" data-es_width=\"1000\" data-es_height=\"446\" data-es_first_edit=\"false\" class=\"edusharing\" alt=\"Bildschirmfoto 2018-11-07 um 16.09.49.png\" title=\"Bildschirmfoto 2018-11-07 um 16.09.49.png\" width=\"1000\" height=\"446\">"; - - // t() did not work, because antisamy changed the order of the attributes - Filter vFilter = new OWASPAntiSamyXSSFilter(-1, true); - String filtered = vFilter.filter(html); - assertThat(filtered).contains("src"); - assertThat(filtered).contains("width"); - assertThat(filtered).contains("height"); - assertThat(filtered).contains("es_identifier"); - assertThat(filtered).contains("es_objecturl"); - assertThat(filtered).contains("es_version"); - assertThat(filtered).contains("es_mimetype"); - assertThat(filtered).contains("es_mediatype"); - assertThat(filtered).contains("es_width"); - assertThat(filtered).contains("es_height"); - } - - @Test - public void test_rawText() { - OWASPAntiSamyXSSFilter intlFilter = new OWASPAntiSamyXSSFilter(-1, false, Variant.tinyMce, true); - t("Stéphane Rossé", "Stéphane Rossé", intlFilter); - } - - @Test - public void test_rawTextAttaqu() { - OWASPAntiSamyXSSFilter intlFilter = new OWASPAntiSamyXSSFilter(-1, false, Variant.tinyMce, true); - t("<script>alert('hello');<//script>", "<script>alert('hello');<//script>", intlFilter); - } - -} diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java index c7b09caa2b7..46b1977093a 100644 --- a/src/test/java/org/olat/test/AllTestsJunit4.java +++ b/src/test/java/org/olat/test/AllTestsJunit4.java @@ -52,7 +52,6 @@ import org.junit.runners.Suite; org.olat.core.commons.chiefcontrollers.ChiefControllerMessageEventTest.class, org.olat.core.util.vfs.VFSTest.class, org.olat.core.util.vfs.VFSManagerTest.class, - org.olat.core.util.filter.impl.XSSFilterTest.class, org.olat.core.util.filter.impl.XSSFilterParamTest.class, org.olat.core.util.filter.impl.AddBaseURLToMediaRelativeURLFilterTest.class, org.olat.core.util.filter.impl.SimpleHTMLTagsFilterTest.class, -- GitLab