You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2014/06/23 16:54:51 UTC

svn commit: r1604828 - in /sling/trunk: bundles/scripting/jsp-taglib/ bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/ bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/helpers/ bundles/sc...

Author: dklco
Date: Mon Jun 23 14:54:51 2014
New Revision: 1604828

URL: http://svn.apache.org/r1604828
Log:
Adding basic HTML encoding as per SLING-3665

Added:
    sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/EncodeTag.java
    sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/helpers/
    sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/helpers/XSSSupport.java
    sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/ESAPI.properties
    sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/validation.properties
    sling/trunk/bundles/scripting/jsp-taglib/src/test/java/org/apache/sling/scripting/jsp/taglib/TestEncodeTag.java
Modified:
    sling/trunk/bundles/scripting/jsp-taglib/pom.xml
    sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/SlingFunctions.java
    sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/META-INF/sling.tld
    sling/trunk/bundles/scripting/jsp-taglib/src/test/java/org/apache/sling/scripting/jsp/taglib/TestSlingFunctions.java
    sling/trunk/launchpad/builder/src/main/bundles/list.xml
    sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/scripting/SlingJSPTaglibTest.java
    sling/trunk/launchpad/integration-tests/src/main/resources/integration-test/taglib-test.jsp

Modified: sling/trunk/bundles/scripting/jsp-taglib/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp-taglib/pom.xml?rev=1604828&r1=1604827&r2=1604828&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/jsp-taglib/pom.xml (original)
+++ sling/trunk/bundles/scripting/jsp-taglib/pom.xml Mon Jun 23 14:54:51 2014
@@ -1,128 +1,149 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.sling</groupId>
-        <artifactId>sling</artifactId>
-        <version>19</version>
-        <relativePath>../../../parent/pom.xml</relativePath>
-    </parent>
-
-    <artifactId>org.apache.sling.scripting.jsp.taglib</artifactId>
-    <version>2.2.1-SNAPSHOT</version>
-    <packaging>bundle</packaging>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+	license agreements. See the NOTICE file distributed with this work for additional 
+	information regarding copyright ownership. The ASF licenses this file to 
+	you under the Apache License, Version 2.0 (the "License"); you may not use 
+	this file except in compliance with the License. You may obtain a copy of 
+	the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
+	by applicable law or agreed to in writing, software distributed under the 
+	License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
+	OF ANY KIND, either express or implied. See the License for the specific 
+	language governing permissions and limitations under the License. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.apache.sling</groupId>
+		<artifactId>sling</artifactId>
+		<version>19</version>
+		<relativePath>../../../parent/pom.xml</relativePath>
+	</parent>
+
+	<artifactId>org.apache.sling.scripting.jsp.taglib</artifactId>
+	<version>2.2.1-SNAPSHOT</version>
+	<packaging>bundle</packaging>
 
-    <name>Apache Sling JSP Tag Library</name>
-    <description>
+	<name>Apache Sling JSP Tag Library</name>
+	<description>
         Core Tag Library for Apache Sling JSP support
     </description>
-
-    <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/scripting/jsp-taglib</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/scripting/jsp-taglib</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp-taglib</url>
-    </scm>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <extensions>true</extensions>
-                <configuration>
-                    <instructions>
-                        <Export-Package>
-                            org.apache.sling.scripting.jsp.taglib.*;version=2.2.0
-                        </Export-Package>
-                        <Import-Package>
-                            javax.jcr;resolution:=optional,
-                            javax.servlet.jsp.*;version=2.0,
-                            *
-                        </Import-Package>
-                    </instructions>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-    <dependencies>
-        <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>jsp-api</artifactId>
-            <version>2.0</version>
-            <!-- using compile scope to help IDEs -->
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.api</artifactId>
-            <version>2.1.0</version>
-            <!-- using compile scope to help IDEs -->
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.scripting.jsp</artifactId>
-            <version>2.0.8</version>
-            <!-- using compile scope to help IDEs -->
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.core</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.compendium</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-            <!-- using compile scope to help IDEs -->
-            <scope>compile</scope>
-        </dependency>
-	
-        <!-- Testing Dependencies -->
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.jmock</groupId>
-            <artifactId>jmock-junit4</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-simple</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.commons.testing</artifactId>
-            <version>2.0.12</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
+    
+	<scm>
+		<connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/scripting/jsp-taglib</connection>
+		<developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/scripting/jsp-taglib</developerConnection>
+		<url>http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp-taglib</url>
+	</scm>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-bundle-plugin</artifactId>
+				<extensions>true</extensions>
+				<configuration>
+					<instructions>
+						<Export-Package>
+							org.apache.sling.scripting.jsp.taglib.*;version=2.2.0
+						</Export-Package>
+						<Import-Package>
+							javax.jcr;resolution:=optional,
+							javax.servlet.jsp.*;version=2.0,
+                            !bsh.*,
+                            !nu.xom.*,
+                            !org.apache.commons.beanutils.*,
+                            !org.apache.commons.configuration.*,
+                            !org.owasp.validator.html.*,
+                            !org.apache.log4j.*,
+							*
+						</Import-Package>
+						<Embed-Dependency>esapi;inline=true</Embed-Dependency>
+					</instructions>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<configuration>
+					<systemPropertyVariables>
+                        <org.owasp.esapi.resources>${project.basedir}/src/main/resources</org.owasp.esapi.resources>
+					</systemPropertyVariables>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>servlet-api</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>jsp-api</artifactId>
+			<version>2.0</version>
+			<!-- using compile scope to help IDEs -->
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.sling</groupId>
+			<artifactId>org.apache.sling.api</artifactId>
+			<version>2.1.0</version>
+			<!-- using compile scope to help IDEs -->
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.sling</groupId>
+			<artifactId>org.apache.sling.scripting.jsp</artifactId>
+			<version>2.0.8</version>
+			<!-- using compile scope to help IDEs -->
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.core</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.compendium</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+			<!-- using compile scope to help IDEs -->
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>commons-lang</groupId>
+			<artifactId>commons-lang</artifactId>
+			<version>2.4</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.owasp.esapi</groupId>
+			<artifactId>esapi</artifactId>
+			<version>2.1.0</version>
+			<scope>compile</scope>
+		</dependency>
+
+		<!-- Testing Dependencies -->
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.jmock</groupId>
+			<artifactId>jmock-junit4</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-simple</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.sling</groupId>
+			<artifactId>org.apache.sling.commons.testing</artifactId>
+			<version>2.0.12</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
 </project>

Added: sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/EncodeTag.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/EncodeTag.java?rev=1604828&view=auto
==============================================================================
--- sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/EncodeTag.java (added)
+++ sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/EncodeTag.java Mon Jun 23 14:54:51 2014
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.scripting.jsp.taglib;
+
+import java.io.IOException;
+
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.BodyTagSupport;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.sling.scripting.jsp.taglib.helpers.XSSSupport;
+import org.apache.sling.scripting.jsp.taglib.helpers.XSSSupport.ENCODING_MODE;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tag for writing properly XSS encoded text to the response using the OWASP
+ * ESAPI for supporting a number of encoding modes.
+ */
+public class EncodeTag extends BodyTagSupport {
+
+	private static final long serialVersionUID = 5673936481350419997L;
+
+	private static final Logger log = LoggerFactory.getLogger(EncodeTag.class);
+	private String value;
+	private String defaultValue;
+	private ENCODING_MODE mode;
+	private boolean readBody = false;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.jsp.tagext.TagSupport#doEndTag()
+	 */
+	@Override
+	public int doEndTag() throws JspException {
+		log.trace("doEndTag");
+
+		if (readBody) {
+			if (bodyContent != null && bodyContent.getString() != null) {
+				String encoded = XSSSupport.encode(bodyContent.getString(),
+						mode);
+				write(encoded);
+			}
+		}
+		return EVAL_PAGE;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.jsp.tagext.BodyTagSupport#doStartTag()
+	 */
+	@Override
+	public int doStartTag() throws JspException {
+		int res = SKIP_BODY;
+		String unencoded = value;
+		if (unencoded == null) {
+			unencoded = defaultValue;
+		}
+
+		if (unencoded != null) {
+			String encoded = XSSSupport.encode(unencoded, mode);
+			write(encoded);
+		} else {
+			readBody = true;
+			res = EVAL_BODY_BUFFERED;
+		}
+		return res;
+	}
+
+	/**
+	 * @return the default value
+	 */
+	public String getDefault() {
+		return defaultValue;
+	}
+
+	/**
+	 * @return the mode
+	 */
+	public String getMode() {
+		return mode.toString();
+	}
+
+	/**
+	 * @return the value
+	 */
+	public String getValue() {
+		return value;
+	}
+
+	/**
+	 * @param defaultValue
+	 *            the default value to set
+	 */
+	public void setDefault(String defaultValue) {
+		this.defaultValue = defaultValue;
+	}
+
+	/**
+	 * @param mode
+	 *            the mode to set
+	 */
+	public void setMode(String mode) {
+		this.mode = XSSSupport.getEncodingMode(mode);
+	}
+
+	/**
+	 * @param value
+	 *            the value to set
+	 */
+	public void setValue(String value) {
+		this.value = value;
+	}
+
+	/**
+	 * Writes the encoded text to the response.
+	 * 
+	 * @param encoded
+	 *            the encoded text to write to the page
+	 * @throws JspException
+	 */
+	private void write(String encoded) throws JspException {
+		if (!StringUtils.isEmpty(encoded)) {
+			try {
+				pageContext.getOut().write(encoded);
+			} catch (IOException e) {
+				log.error("Exception writing escaped content to page", e);
+				throw new JspException(
+						"Exception writing escaped content to page", e);
+			}
+		}
+	}
+}

Modified: sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/SlingFunctions.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/SlingFunctions.java?rev=1604828&r1=1604827&r2=1604828&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/SlingFunctions.java (original)
+++ sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/SlingFunctions.java Mon Jun 23 14:54:51 2014
@@ -22,6 +22,7 @@ import org.apache.sling.api.adapter.Adap
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.scripting.jsp.taglib.helpers.XSSSupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -65,6 +66,19 @@ public class SlingFunctions {
 	}
 
 	/**
+	 * Loads the Class for the name from the current thread's classload.
+	 * 
+	 * @param className
+	 *            The name of the class to load
+	 * @return the class
+	 * @throws ClassNotFoundException
+	 *             a class with the specified name could not be found
+	 */
+	public static String escape(String value, String mode) {
+		return XSSSupport.encode(value, XSSSupport.getEncodingMode(mode));
+	}
+
+	/**
 	 * Searches for resources using the given query formulated in the given
 	 * language.
 	 * 
@@ -170,7 +184,6 @@ public class SlingFunctions {
 		return resource != null ? resource.listChildren().hasNext() : false;
 	}
 
-
 	/**
 	 * Method for allowing the invocation of the Sling Resource listChildren
 	 * method.
@@ -207,4 +220,5 @@ public class SlingFunctions {
 		return Thread.currentThread().getContextClassLoader()
 				.loadClass(className);
 	}
+
 }
\ No newline at end of file

Added: sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/helpers/XSSSupport.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/helpers/XSSSupport.java?rev=1604828&view=auto
==============================================================================
--- sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/helpers/XSSSupport.java (added)
+++ sling/trunk/bundles/scripting/jsp-taglib/src/main/java/org/apache/sling/scripting/jsp/taglib/helpers/XSSSupport.java Mon Jun 23 14:54:51 2014
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.scripting.jsp.taglib.helpers;
+
+import org.apache.commons.lang.StringUtils;
+import org.owasp.esapi.ESAPI;
+
+/**
+ * Support for basic XSS protection as provided by the OWASP ESAPI's escape
+ * methods.
+ */
+public class XSSSupport {
+
+	/**
+	 * The encoding modes supported by this tag.
+	 */
+	public static enum ENCODING_MODE {
+		/**
+		 * Encodes the content as HTML
+		 */
+		HTML, HTML_ATTR, XML, XML_ATTR, JS
+	}
+
+	/**
+	 * Encodes the unencoded string using the specified mode. This will be
+	 * deferred to the corresponding OWASP ESAPI encoding method.
+	 * 
+	 * @param unencoded
+	 *            the unencoded string
+	 * @param mode
+	 *            the mode with which to encode the string
+	 * @return the encoded string
+	 */
+	public static String encode(String unencoded, ENCODING_MODE mode) {
+
+		String encoded = null;
+		switch (mode) {
+		case HTML:
+			encoded = ESAPI.encoder().encodeForHTML(unencoded);
+			break;
+		case HTML_ATTR:
+			encoded = ESAPI.encoder().encodeForHTMLAttribute(unencoded);
+			break;
+		case XML:
+			encoded = ESAPI.encoder().encodeForXML(unencoded);
+			break;
+		case XML_ATTR:
+			encoded = ESAPI.encoder().encodeForXMLAttribute(unencoded);
+			break;
+		case JS:
+			encoded = ESAPI.encoder().encodeForJavaScript(unencoded);
+			break;
+		default:
+			break;
+		}
+		return encoded;
+	}
+
+	/**
+	 * Retrieves the encoding mode associated with the specified string. Will
+	 * throw an IllegalArgumentException if the mode string is not a valid mode
+	 * and will throw a NullPointerException if the mode string is null.
+	 * 
+	 * @param modeStr
+	 *            the mode string
+	 * @return the encoding mode
+	 */
+	public static ENCODING_MODE getEncodingMode(String modeStr) {
+		return ENCODING_MODE.valueOf(StringUtils.upperCase(modeStr));
+	}
+}

Added: sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/ESAPI.properties
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/ESAPI.properties?rev=1604828&view=auto
==============================================================================
--- sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/ESAPI.properties (added)
+++ sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/ESAPI.properties Mon Jun 23 14:54:51 2014
@@ -0,0 +1,452 @@
+#
+# OWASP Enterprise Security API (ESAPI) Properties file -- PRODUCTION Version
+# 
+# This file is part of the Open Web Application Security Project (OWASP)
+# Enterprise Security API (ESAPI) project. For details, please see
+# http://www.owasp.org/index.php/ESAPI.
+#
+# Copyright (c) 2008,2009 - The OWASP Foundation
+#
+# DISCUSS: This may cause a major backwards compatibility issue, etc. but
+#		   from a name space perspective, we probably should have prefaced
+#		   all the property names with ESAPI or at least OWASP. Otherwise
+#		   there could be problems is someone loads this properties file into
+#		   the System properties.  We could also put this file into the
+#		   esapi.jar file (perhaps as a ResourceBundle) and then allow an external
+#		   ESAPI properties be defined that would overwrite these defaults.
+#		   That keeps the application's properties relatively simple as usually
+#		   they will only want to override a few properties. If looks like we
+#		   already support multiple override levels of this in the
+#		   DefaultSecurityConfiguration class, but I'm suggesting placing the
+#		   defaults in the esapi.jar itself. That way, if the jar is signed,
+#		   we could detect if those properties had been tampered with. (The
+#		   code to check the jar signatures is pretty simple... maybe 70-90 LOC,
+#		   but off course there is an execution penalty (similar to the way
+#		   that the separate sunjce.jar used to be when a class from it was
+#		   first loaded). Thoughts?
+###############################################################################
+#
+# WARNING: Operating system protection should be used to lock down the .esapi
+# resources directory and all the files inside and all the directories all the
+# way up to the root directory of the file system.  Note that if you are using
+# file-based implementations, that some files may need to be read-write as they
+# get updated dynamically.
+#
+# Before using, be sure to update the MasterKey and MasterSalt as described below.
+# N.B.: If you had stored data that you have previously encrypted with ESAPI 1.4,
+#		you *must* FIRST decrypt it using ESAPI 1.4 and then (if so desired)
+#		re-encrypt it with ESAPI 2.0. If you fail to do this, you will NOT be
+#		able to decrypt your data with ESAPI 2.0.
+#
+#		YOU HAVE BEEN WARNED!!! More details are in the ESAPI 2.0 Release Notes.
+#
+#===========================================================================
+# ESAPI Configuration
+#
+# If true, then print all the ESAPI properties set here when they are loaded.
+# If false, they are not printed. Useful to reduce output when running JUnit tests.
+# If you need to troubleshoot a properties related problem, turning this on may help.
+# This is 'false' in the src/test/resources/.esapi version. It is 'true' by
+# default for reasons of backward compatibility with earlier ESAPI versions.
+ESAPI.printProperties=true
+
+# ESAPI is designed to be easily extensible. You can use the reference implementation
+# or implement your own providers to take advantage of your enterprise's security
+# infrastructure. The functions in ESAPI are referenced using the ESAPI locator, like:
+#
+#    String ciphertext =
+#		ESAPI.encryptor().encrypt("Secret message");   // Deprecated in 2.0
+#    CipherText cipherText =
+#		ESAPI.encryptor().encrypt(new PlainText("Secret message")); // Preferred
+#
+# Below you can specify the classname for the provider that you wish to use in your
+# application. The only requirement is that it implement the appropriate ESAPI interface.
+# This allows you to switch security implementations in the future without rewriting the
+# entire application.
+#
+# ExperimentalAccessController requires ESAPI-AccessControlPolicy.xml in .esapi directory
+ESAPI.AccessControl=org.owasp.esapi.reference.DefaultAccessController
+# FileBasedAuthenticator requires users.txt file in .esapi directory
+ESAPI.Authenticator=org.owasp.esapi.reference.FileBasedAuthenticator
+ESAPI.Encoder=org.owasp.esapi.reference.DefaultEncoder
+ESAPI.Encryptor=org.owasp.esapi.reference.crypto.JavaEncryptor
+
+ESAPI.Executor=org.owasp.esapi.reference.DefaultExecutor
+ESAPI.HTTPUtilities=org.owasp.esapi.reference.DefaultHTTPUtilities
+ESAPI.IntrusionDetector=org.owasp.esapi.reference.DefaultIntrusionDetector
+# Log4JFactory Requires log4j.xml or log4j.properties in classpath - http://www.laliluna.de/log4j-tutorial.html
+#ESAPI.Logger=org.owasp.esapi.reference.Log4JLogFactory
+ESAPI.Logger=org.owasp.esapi.reference.JavaLogFactory
+ESAPI.Randomizer=org.owasp.esapi.reference.DefaultRandomizer
+ESAPI.Validator=org.owasp.esapi.reference.DefaultValidator
+
+#===========================================================================
+# ESAPI Authenticator
+#
+Authenticator.AllowedLoginAttempts=3
+Authenticator.MaxOldPasswordHashes=13
+Authenticator.UsernameParameterName=username
+Authenticator.PasswordParameterName=password
+# RememberTokenDuration (in days)
+Authenticator.RememberTokenDuration=14
+# Session Timeouts (in minutes)
+Authenticator.IdleTimeoutDuration=20
+Authenticator.AbsoluteTimeoutDuration=120
+
+#===========================================================================
+# ESAPI Encoder
+#
+# ESAPI canonicalizes input before validation to prevent bypassing filters with encoded attacks.
+# Failure to canonicalize input is a very common mistake when implementing validation schemes.
+# Canonicalization is automatic when using the ESAPI Validator, but you can also use the
+# following code to canonicalize data.
+#
+#      ESAPI.Encoder().canonicalize( "%22hello world&#x22;" );
+#  
+# Multiple encoding is when a single encoding format is applied multiple times. Allowing
+# multiple encoding is strongly discouraged.
+Encoder.AllowMultipleEncoding=false
+
+# Mixed encoding is when multiple different encoding formats are applied, or when 
+# multiple formats are nested. Allowing multiple encoding is strongly discouraged.
+Encoder.AllowMixedEncoding=false
+
+# The default list of codecs to apply when canonicalizing untrusted data. The list should include the codecs
+# for all downstream interpreters or decoders. For example, if the data is likely to end up in a URL, HTML, or
+# inside JavaScript, then the list of codecs below is appropriate. The order of the list is not terribly important.
+Encoder.DefaultCodecList=HTMLEntityCodec,XMLEntityCodec,PercentCodec,JavaScriptCodec
+
+
+#===========================================================================
+# ESAPI Encryption
+#
+# The ESAPI Encryptor provides basic cryptographic functions with a simplified API.
+# To get started, generate a new key using java -classpath esapi.jar org.owasp.esapi.reference.crypto.JavaEncryptor
+# There is not currently any support for key rotation, so be careful when changing your key and salt as it
+# will invalidate all signed, encrypted, and hashed data.
+#
+# WARNING: Not all combinations of algorithms and key lengths are supported.
+# If you choose to use a key length greater than 128, you MUST download the
+# unlimited strength policy files and install in the lib directory of your JRE/JDK.
+# See http://java.sun.com/javase/downloads/index.jsp for more information.
+#
+# Backward compatibility with ESAPI Java 1.4 is supported by the two deprecated API
+# methods, Encryptor.encrypt(String) and Encryptor.decrypt(String). However, whenever
+# possible, these methods should be avoided as they use ECB cipher mode, which in almost
+# all circumstances a poor choice because of it's weakness. CBC cipher mode is the default
+# for the new Encryptor encrypt / decrypt methods for ESAPI Java 2.0.  In general, you
+# should only use this compatibility setting if you have persistent data encrypted with
+# version 1.4 and even then, you should ONLY set this compatibility mode UNTIL
+# you have decrypted all of your old encrypted data and then re-encrypted it with
+# ESAPI 2.0 using CBC mode. If you have some reason to mix the deprecated 1.4 mode
+# with the new 2.0 methods, make sure that you use the same cipher algorithm for both
+# (256-bit AES was the default for 1.4; 128-bit is the default for 2.0; see below for
+# more details.) Otherwise, you will have to use the new 2.0 encrypt / decrypt methods
+# where you can specify a SecretKey. (Note that if you are using the 256-bit AES,
+# that requires downloading the special jurisdiction policy files mentioned above.)
+#
+#		***** IMPORTANT: Do NOT forget to replace these with your own values! *****
+# To calculate these values, you can run:
+#		java -classpath esapi.jar org.owasp.esapi.reference.crypto.JavaEncryptor
+#
+#Encryptor.MasterKey=
+#Encryptor.MasterSalt=
+
+# Provides the default JCE provider that ESAPI will "prefer" for its symmetric
+# encryption and hashing. (That is it will look to this provider first, but it
+# will defer to other providers if the requested algorithm is not implemented
+# by this provider.) If left unset, ESAPI will just use your Java VM's current
+# preferred JCE provider, which is generally set in the file
+# "$JAVA_HOME/jre/lib/security/java.security".
+#
+# The main intent of this is to allow ESAPI symmetric encryption to be
+# used with a FIPS 140-2 compliant crypto-module. For details, see the section
+# "Using ESAPI Symmetric Encryption with FIPS 140-2 Cryptographic Modules" in
+# the ESAPI 2.0 Symmetric Encryption User Guide, at:
+# http://owasp-esapi-java.googlecode.com/svn/trunk/documentation/esapi4java-core-2.0-symmetric-crypto-user-guide.html
+# However, this property also allows you to easily use an alternate JCE provider
+# such as "Bouncy Castle" without having to make changes to "java.security".
+# See Javadoc for SecurityProviderLoader for further details. If you wish to use
+# a provider that is not known to SecurityProviderLoader, you may specify the
+# fully-qualified class name of the JCE provider class that implements
+# java.security.Provider. If the name contains a '.', this is interpreted as
+# a fully-qualified class name that implements java.security.Provider.
+#
+# NOTE: Setting this property has the side-effect of changing it in your application
+#       as well, so if you are using JCE in your application directly rather than
+#       through ESAPI (you wouldn't do that, would you? ;-), it will change the
+#       preferred JCE provider there as well.
+#
+# Default: Keeps the JCE provider set to whatever JVM sets it to.
+Encryptor.PreferredJCEProvider=
+
+# AES is the most widely used and strongest encryption algorithm. This
+# should agree with your Encryptor.CipherTransformation property.
+# By default, ESAPI Java 1.4 uses "PBEWithMD5AndDES" and which is
+# very weak. It is essentially a password-based encryption key, hashed
+# with MD5 around 1K times and then encrypted with the weak DES algorithm
+# (56-bits) using ECB mode and an unspecified padding (it is
+# JCE provider specific, but most likely "NoPadding"). However, 2.0 uses
+# "AES/CBC/PKCSPadding". If you want to change these, change them here.
+# Warning: This property does not control the default reference implementation for
+#		   ESAPI 2.0 using JavaEncryptor. Also, this property will be dropped
+#		   in the future.
+# @deprecated
+Encryptor.EncryptionAlgorithm=AES
+#		For ESAPI Java 2.0 - New encrypt / decrypt methods use this.
+Encryptor.CipherTransformation=AES/CBC/PKCS5Padding
+
+# Applies to ESAPI 2.0 and later only!
+# Comma-separated list of cipher modes that provide *BOTH*
+# confidentiality *AND* message authenticity. (NIST refers to such cipher
+# modes as "combined modes" so that's what we shall call them.) If any of these
+# cipher modes are used then no MAC is calculated and stored
+# in the CipherText upon encryption. Likewise, if one of these
+# cipher modes is used with decryption, no attempt will be made
+# to validate the MAC contained in the CipherText object regardless
+# of whether it contains one or not. Since the expectation is that
+# these cipher modes support support message authenticity already,
+# injecting a MAC in the CipherText object would be at best redundant.
+#
+# Note that as of JDK 1.5, the SunJCE provider does not support *any*
+# of these cipher modes. Of these listed, only GCM and CCM are currently
+# NIST approved. YMMV for other JCE providers. E.g., Bouncy Castle supports
+# GCM and CCM with "NoPadding" mode, but not with "PKCS5Padding" or other
+# padding modes.
+Encryptor.cipher_modes.combined_modes=GCM,CCM,IAPM,EAX,OCB,CWC
+
+# Applies to ESAPI 2.0 and later only!
+# Additional cipher modes allowed for ESAPI 2.0 encryption. These
+# cipher modes are in _addition_ to those specified by the property
+# 'Encryptor.cipher_modes.combined_modes'.
+# Note: We will add support for streaming modes like CFB & OFB once
+# we add support for 'specified' to the property 'Encryptor.ChooseIVMethod'
+# (probably in ESAPI 2.1).
+# DISCUSS: Better name?
+Encryptor.cipher_modes.additional_allowed=CBC
+
+# 128-bit is almost always sufficient and appears to be more resistant to
+# related key attacks than is 256-bit AES. Use '_' to use default key size
+# for cipher algorithms (where it makes sense because the algorithm supports
+# a variable key size). Key length must agree to what's provided as the
+# cipher transformation, otherwise this will be ignored after logging a
+# warning.
+#
+# NOTE: This is what applies BOTH ESAPI 1.4 and 2.0. See warning above about mixing!
+Encryptor.EncryptionKeyLength=128
+
+# Because 2.0 uses CBC mode by default, it requires an initialization vector (IV).
+# (All cipher modes except ECB require an IV.) There are two choices: we can either
+# use a fixed IV known to both parties or allow ESAPI to choose a random IV. While
+# the IV does not need to be hidden from adversaries, it is important that the
+# adversary not be allowed to choose it. Also, random IVs are generally much more
+# secure than fixed IVs. (In fact, it is essential that feed-back cipher modes
+# such as CFB and OFB use a different IV for each encryption with a given key so
+# in such cases, random IVs are much preferred. By default, ESAPI 2.0 uses random
+# IVs. If you wish to use 'fixed' IVs, set 'Encryptor.ChooseIVMethod=fixed' and
+# uncomment the Encryptor.fixedIV.
+#
+# Valid values:		random|fixed|specified		'specified' not yet implemented; planned for 2.1
+Encryptor.ChooseIVMethod=random
+# If you choose to use a fixed IV, then you must place a fixed IV here that
+# is known to all others who are sharing your secret key. The format should
+# be a hex string that is the same length as the cipher block size for the
+# cipher algorithm that you are using. The following is an *example* for AES
+# from an AES test vector for AES-128/CBC as described in:
+# NIST Special Publication 800-38A (2001 Edition)
+# "Recommendation for Block Cipher Modes of Operation".
+# (Note that the block size for AES is 16 bytes == 128 bits.)
+#
+Encryptor.fixedIV=0x000102030405060708090a0b0c0d0e0f
+
+# Whether or not CipherText should use a message authentication code (MAC) with it.
+# This prevents an adversary from altering the IV as well as allowing a more
+# fool-proof way of determining the decryption failed because of an incorrect
+# key being supplied. This refers to the "separate" MAC calculated and stored
+# in CipherText, not part of any MAC that is calculated as a result of a
+# "combined mode" cipher mode.
+#
+# If you are using ESAPI with a FIPS 140-2 cryptographic module, you *must* also
+# set this property to false.
+Encryptor.CipherText.useMAC=true
+
+# Whether or not the PlainText object may be overwritten and then marked
+# eligible for garbage collection. If not set, this is still treated as 'true'.
+Encryptor.PlainText.overwrite=true
+
+# Do not use DES except in a legacy situations. 56-bit is way too small key size.
+#Encryptor.EncryptionKeyLength=56
+#Encryptor.EncryptionAlgorithm=DES
+
+# TripleDES is considered strong enough for most purposes.
+#	Note:	There is also a 112-bit version of DESede. Using the 168-bit version
+#			requires downloading the special jurisdiction policy from Sun.
+#Encryptor.EncryptionKeyLength=168
+#Encryptor.EncryptionAlgorithm=DESede
+
+Encryptor.HashAlgorithm=SHA-512
+Encryptor.HashIterations=1024
+Encryptor.DigitalSignatureAlgorithm=SHA1withDSA
+Encryptor.DigitalSignatureKeyLength=1024
+Encryptor.RandomAlgorithm=SHA1PRNG
+Encryptor.CharacterEncoding=UTF-8
+
+# This is the Pseudo Random Function (PRF) that ESAPI's Key Derivation Function
+# (KDF) normally uses. Note this is *only* the PRF used for ESAPI's KDF and
+# *not* what is used for ESAPI's MAC. (Currently, HmacSHA1 is always used for
+# the MAC, mostly to keep the overall size at a minimum.)
+#
+# Currently supported choices for JDK 1.5 and 1.6 are:
+#	HmacSHA1 (160 bits), HmacSHA256 (256 bits), HmacSHA384 (384 bits), and
+#	HmacSHA512 (512 bits).
+# Note that HmacMD5 is *not* supported for the PRF used by the KDF even though
+# the JDKs support it.  See the ESAPI 2.0 Symmetric Encryption User Guide
+# further details.
+Encryptor.KDF.PRF=HmacSHA256
+#===========================================================================
+# ESAPI HttpUtilties
+#
+# The HttpUtilities provide basic protections to HTTP requests and responses. Primarily these methods 
+# protect against malicious data from attackers, such as unprintable characters, escaped characters,
+# and other simple attacks. The HttpUtilities also provides utility methods for dealing with cookies,
+# headers, and CSRF tokens.
+#
+# Default file upload location (remember to escape backslashes with \\)
+HttpUtilities.UploadDir=C:\\ESAPI\\testUpload
+HttpUtilities.UploadTempDir=C:\\temp
+# Force flags on cookies, if you use HttpUtilities to set cookies
+HttpUtilities.ForceHttpOnlySession=false
+HttpUtilities.ForceSecureSession=false
+HttpUtilities.ForceHttpOnlyCookies=true
+HttpUtilities.ForceSecureCookies=true
+# Maximum size of HTTP headers
+HttpUtilities.MaxHeaderSize=4096
+# File upload configuration
+HttpUtilities.ApprovedUploadExtensions=.zip,.pdf,.doc,.docx,.ppt,.pptx,.tar,.gz,.tgz,.rar,.war,.jar,.ear,.xls,.rtf,.properties,.java,.class,.txt,.xml,.jsp,.jsf,.exe,.dll
+HttpUtilities.MaxUploadFileBytes=500000000
+# Using UTF-8 throughout your stack is highly recommended. That includes your database driver,
+# container, and any other technologies you may be using. Failure to do this may expose you
+# to Unicode transcoding injection attacks. Use of UTF-8 does not hinder internationalization.
+HttpUtilities.ResponseContentType=text/html; charset=UTF-8
+# This is the name of the cookie used to represent the HTTP session
+# Typically this will be the default "JSESSIONID" 
+HttpUtilities.HttpSessionIdName=JSESSIONID
+
+
+
+#===========================================================================
+# ESAPI Executor
+# CHECKME - Not sure what this is used for, but surely it should be made OS independent.
+Executor.WorkingDirectory=C:\\Windows\\Temp
+Executor.ApprovedExecutables=C:\\Windows\\System32\\cmd.exe,C:\\Windows\\System32\\runas.exe
+
+
+#===========================================================================
+# ESAPI Logging
+# Set the application name if these logs are combined with other applications
+Logger.ApplicationName=ExampleApplication
+# If you use an HTML log viewer that does not properly HTML escape log data, you can set LogEncodingRequired to true
+Logger.LogEncodingRequired=false
+# Determines whether ESAPI should log the application name. This might be clutter in some single-server/single-app environments.
+Logger.LogApplicationName=true
+# Determines whether ESAPI should log the server IP and port. This might be clutter in some single-server environments.
+Logger.LogServerIP=true
+# LogFileName, the name of the logging file. Provide a full directory path (e.g., C:\\ESAPI\\ESAPI_logging_file) if you
+# want to place it in a specific directory.
+Logger.LogFileName=ESAPI_logging_file
+# MaxLogFileSize, the max size (in bytes) of a single log file before it cuts over to a new one (default is 10,000,000)
+Logger.MaxLogFileSize=10000000
+
+
+#===========================================================================
+# ESAPI Intrusion Detection
+#
+# Each event has a base to which .count, .interval, and .action are added
+# The IntrusionException will fire if we receive "count" events within "interval" seconds
+# The IntrusionDetector is configurable to take the following actions: log, logout, and disable
+#  (multiple actions separated by commas are allowed e.g. event.test.actions=log,disable
+#
+# Custom Events
+# Names must start with "event." as the base
+# Use IntrusionDetector.addEvent( "test" ) in your code to trigger "event.test" here
+# You can also disable intrusion detection completely by changing
+# the following parameter to true
+#
+IntrusionDetector.Disable=false
+#
+IntrusionDetector.event.test.count=2
+IntrusionDetector.event.test.interval=10
+IntrusionDetector.event.test.actions=disable,log
+
+# Exception Events
+# All EnterpriseSecurityExceptions are registered automatically
+# Call IntrusionDetector.getInstance().addException(e) for Exceptions that do not extend EnterpriseSecurityException
+# Use the fully qualified classname of the exception as the base
+
+# any intrusion is an attack
+IntrusionDetector.org.owasp.esapi.errors.IntrusionException.count=1
+IntrusionDetector.org.owasp.esapi.errors.IntrusionException.interval=1
+IntrusionDetector.org.owasp.esapi.errors.IntrusionException.actions=log,disable,logout
+
+# for test purposes
+# CHECKME: Shouldn't there be something in the property name itself that designates
+#		   that these are for testing???
+IntrusionDetector.org.owasp.esapi.errors.IntegrityException.count=10
+IntrusionDetector.org.owasp.esapi.errors.IntegrityException.interval=5
+IntrusionDetector.org.owasp.esapi.errors.IntegrityException.actions=log,disable,logout
+
+# rapid validation errors indicate scans or attacks in progress
+# org.owasp.esapi.errors.ValidationException.count=10
+# org.owasp.esapi.errors.ValidationException.interval=10
+# org.owasp.esapi.errors.ValidationException.actions=log,logout
+
+# sessions jumping between hosts indicates session hijacking
+IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.count=2
+IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.interval=10
+IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.actions=log,logout
+
+
+#===========================================================================
+# ESAPI Validation
+#
+# The ESAPI Validator works on regular expressions with defined names. You can define names
+# either here, or you may define application specific patterns in a separate file defined below.
+# This allows enterprises to specify both organizational standards as well as application specific
+# validation rules.
+#
+Validator.ConfigurationFile=validation.properties
+
+# Validators used by ESAPI
+Validator.AccountName=^[a-zA-Z0-9]{3,20}$
+Validator.SystemCommand=^[a-zA-Z\\-\\/]{1,64}$
+Validator.RoleName=^[a-z]{1,20}$
+
+#the word TEST below should be changed to your application 
+#name - only relative URL's are supported
+Validator.Redirect=^\\/test.*$
+
+# Global HTTP Validation Rules
+# Values with Base64 encoded data (e.g. encrypted state) will need at least [a-zA-Z0-9\/+=]
+Validator.HTTPScheme=^(http|https)$
+Validator.HTTPServerName=^[a-zA-Z0-9_.\\-]*$
+Validator.HTTPParameterName=^[a-zA-Z0-9_]{1,32}$
+Validator.HTTPParameterValue=^[a-zA-Z0-9.\\-\\/+=@_ ]*$
+Validator.HTTPCookieName=^[a-zA-Z0-9\\-_]{1,32}$
+Validator.HTTPCookieValue=^[a-zA-Z0-9\\-\\/+=_ ]*$
+Validator.HTTPHeaderName=^[a-zA-Z0-9\\-_]{1,32}$
+Validator.HTTPHeaderValue=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$
+Validator.HTTPContextPath=^\\/?[a-zA-Z0-9.\\-\\/_]*$
+Validator.HTTPServletPath=^[a-zA-Z0-9.\\-\\/_]*$
+Validator.HTTPPath=^[a-zA-Z0-9.\\-_]*$
+Validator.HTTPQueryString=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ %]*$
+Validator.HTTPURI=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$
+Validator.HTTPURL=^.*$
+Validator.HTTPJSESSIONID=^[A-Z0-9]{10,30}$
+
+# Validation of file related input
+Validator.FileName=^[a-zA-Z0-9!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$
+Validator.DirectoryName=^[a-zA-Z0-9:/\\\\!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$
+
+# Validation of dates. Controls whether or not 'lenient' dates are accepted.
+# See DataFormat.setLenient(boolean flag) for further details.
+Validator.AcceptLenientDates=false
\ No newline at end of file

Modified: sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/META-INF/sling.tld
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/META-INF/sling.tld?rev=1604828&r1=1604827&r2=1604828&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/META-INF/sling.tld (original)
+++ sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/META-INF/sling.tld Mon Jun 23 14:54:51 2014
@@ -24,6 +24,12 @@
 		<function-signature>java.lang.Object adaptTo(org.apache.sling.api.adapter.Adaptable, java.lang.String)</function-signature>
 	</function>
 
+    <function>
+        <name>encode</name>
+        <function-class>org.apache.sling.scripting.jsp.taglib.SlingFunctions</function-class>
+        <function-signature>java.lang.String encode(java.lang.String, java.lang.String)</function-signature>
+    </function>
+
 	<function>
 		<name>findResources</name>
 		<function-class>org.apache.sling.scripting.jsp.taglib.SlingFunctions</function-class>
@@ -436,6 +442,44 @@
 		</attribute>
 	</tag>
 
+    <tag>
+        <description>
+            Writes properly XSS encoded text to the response using the 
+            OWASP ESAPI for supporting a number of encoding modes.
+        </description>
+        <name>encode</name>
+        <tag-class>
+            org.apache.sling.scripting.jsp.taglib.EncodeTag
+        </tag-class>
+        <body-content>JSP</body-content>
+        <attribute>
+            <description>
+                The value to encode.
+            </description>
+            <name>value</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+        <attribute>
+            <description>
+                The default value to be used if the value is either 
+                null or an empty string.
+            </description>
+            <name>default</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+        <attribute>
+            <description>
+                The mode to use for encoding.  Must be one of the 
+                valid modes found in XSSSupport.ENCODING_MODE.
+            </description>
+            <name>mode</name>
+            <required>true</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+    </tag>
+
 	<tag>
 		<description>
 			Tag for searching for resources using the given query

Added: sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/validation.properties
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/validation.properties?rev=1604828&view=auto
==============================================================================
--- sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/validation.properties (added)
+++ sling/trunk/bundles/scripting/jsp-taglib/src/main/resources/validation.properties Mon Jun 23 14:54:51 2014
@@ -0,0 +1,29 @@
+# The ESAPI validator does many security checks on input, such as canonicalization
+# and whitelist validation. Note that all of these validation rules are applied *after*
+# canonicalization. Double-encoded characters (even with different encodings involved,
+# are never allowed.
+#
+# To use:
+#
+# First set up a pattern below. You can choose any name you want, prefixed by the word
+# "Validation." For example:
+#   Validation.Email=^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$
+# 
+# Then you can validate in your code against the pattern like this:
+#     ESAPI.validator().isValidInput("User Email", input, "Email", maxLength, allowNull);
+# Where maxLength and allowNull are set for you needs, respectively.
+#
+# But note, when you use boolean variants of validation functions, you lose critical 
+# canonicalization. It is preferable to use the "get" methods (which throw exceptions) and 
+# and use the returned user input which is in canonical form. Consider the following:
+#  
+# try {
+#    someObject.setEmail(ESAPI.validator().getValidInput("User Email", input, "Email", maxLength, allowNull));
+#
+Validator.SafeString=^[.\\p{Alnum}\\p{Space}]{0,1024}$
+Validator.Email=^[A-Za-z0-9._%'-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$
+Validator.IPAddress=^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
+Validator.URL=^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\:\\'\\/\\\\\\+=&amp;%\\$#_]*)?$
+Validator.CreditCard=^(\\d{4}[- ]?){3}\\d{4}$
+Validator.SSN=^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$
+

Added: sling/trunk/bundles/scripting/jsp-taglib/src/test/java/org/apache/sling/scripting/jsp/taglib/TestEncodeTag.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp-taglib/src/test/java/org/apache/sling/scripting/jsp/taglib/TestEncodeTag.java?rev=1604828&view=auto
==============================================================================
--- sling/trunk/bundles/scripting/jsp-taglib/src/test/java/org/apache/sling/scripting/jsp/taglib/TestEncodeTag.java (added)
+++ sling/trunk/bundles/scripting/jsp-taglib/src/test/java/org/apache/sling/scripting/jsp/taglib/TestEncodeTag.java Mon Jun 23 14:54:51 2014
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.scripting.jsp.taglib;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.JspWriter;
+
+import org.apache.sling.api.resource.ValueMap;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Unit Tests for the Class EscapeTag.
+ * 
+ * @see org.apache.sling.scripting.jsp.taglib.EscapeTag
+ */
+public class TestEncodeTag {
+
+	private static final Logger log = LoggerFactory
+			.getLogger(TestEncodeTag.class);
+	private EncodeTag encodeTag;
+	private MockPageContext pageContext;
+	private StringBuilder sb;
+	private static final String VAR_KEY = "properties";
+
+	/**
+	 * Initializes the fields for this test.
+	 */
+	@SuppressWarnings("serial")
+	@Before
+	public void init() {
+		log.info("init");
+		encodeTag = new EncodeTag();
+
+		sb = new StringBuilder();
+		final JspWriter w = new JspWriter(0, false){
+			public void newLine() throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public void print(boolean paramBoolean) throws IOException {
+				sb.append(paramBoolean);
+			}
+			public void print(char paramChar) throws IOException {
+				sb.append(paramChar);
+			}
+			public void print(int paramInt) throws IOException {
+				sb.append(paramInt);
+			}
+			public void print(long paramLong) throws IOException {
+				sb.append(paramLong);
+			}
+			public void print(float paramFloat) throws IOException {
+				sb.append(paramFloat);
+			}
+			public void print(double paramDouble) throws IOException {
+				sb.append(paramDouble);
+			}
+			public void print(char[] paramArrayOfChar) throws IOException {
+				sb.append(paramArrayOfChar);
+			}
+			public void print(String paramString) throws IOException {
+				sb.append(paramString);
+			}
+			public void print(Object paramObject) throws IOException {
+				sb.append(paramObject);
+			}
+			public void println() throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public void println(boolean paramBoolean) throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public void println(char paramChar) throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public void println(int paramInt) throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public void println(long paramLong) throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public void println(float paramFloat) throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public void println(double paramDouble) throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public void println(char[] paramArrayOfChar) throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public void println(String paramString) throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public void println(Object paramObject) throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public void clear() throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public void clearBuffer() throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public void flush() throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public void close() throws IOException {
+				throw new UnsupportedOperationException();
+			}
+			public int getRemaining() {
+				throw new UnsupportedOperationException();
+			}
+			public void write(char[] cbuf, int off, int len) throws IOException {
+				sb.append(cbuf);
+			}
+			
+		};
+		pageContext = new MockPageContext(){
+			public JspWriter getOut() {
+				return w;
+			}
+		};
+		encodeTag.setPageContext(pageContext);
+		log.info("init Complete");
+	}
+
+	/**
+	 * Tests the adapt object Tag functionality.
+	 * @throws JspException 
+	 */
+	@Test
+	public void testEncode() throws JspException {
+		log.info("testAdaptObject");
+
+		log.info("Setting up tests");
+		encodeTag.setValue("&amp;Hello World!");
+		encodeTag.setMode("html");
+		encodeTag.doStartTag();
+		encodeTag.doEndTag();
+
+		log.info("Checking result");
+		assertEquals("&amp;amp&#x3b;Hello World&#x21;",sb.toString().trim());
+
+		log.info("Test successful!");
+	}
+}

Modified: sling/trunk/bundles/scripting/jsp-taglib/src/test/java/org/apache/sling/scripting/jsp/taglib/TestSlingFunctions.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/scripting/jsp-taglib/src/test/java/org/apache/sling/scripting/jsp/taglib/TestSlingFunctions.java?rev=1604828&r1=1604827&r2=1604828&view=diff
==============================================================================
--- sling/trunk/bundles/scripting/jsp-taglib/src/test/java/org/apache/sling/scripting/jsp/taglib/TestSlingFunctions.java (original)
+++ sling/trunk/bundles/scripting/jsp-taglib/src/test/java/org/apache/sling/scripting/jsp/taglib/TestSlingFunctions.java Mon Jun 23 14:54:51 2014
@@ -18,7 +18,9 @@ package org.apache.sling.scripting.jsp.t
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.util.ArrayList;
 import java.util.Date;
@@ -85,6 +87,41 @@ public class TestSlingFunctions {
 	}
 
 	@Test
+	public void testEscape() {
+		log.info("testEncode");
+
+		log.info("Testing HTML Escaping");
+		assertEquals("&amp;nbsp&#x3b;Here is some text&#x21;",
+				SlingFunctions.escape("&nbsp;Here is some text!", "HTML"));
+
+		log.info("Testing HTML Attr Escaping");
+		assertEquals(
+				"&amp;nbsp&#x3b;Here&#x20;is&#x20;some&#x20;text&#x21;&quot;",
+				SlingFunctions
+						.escape("&nbsp;Here is some text!\"", "HTML_ATTR"));
+
+		log.info("Testing invalid values");
+		try {
+			SlingFunctions.escape(null, null);
+			fail("Expected null pointer exception");
+		} catch (NullPointerException npe) {
+			log.info("Encountered expected exception");
+		}
+		try {
+			SlingFunctions.escape(null, "Invalid");
+			fail("Expected invalid argument exception");
+		} catch (IllegalArgumentException iae) {
+			log.info("Encountered expected exception");
+		}
+
+		log.info("Testing null/empty values");
+		assertNull(SlingFunctions.escape(null, "html"));
+		assertEquals("", SlingFunctions.escape("", "html"));
+
+		log.info("Tests successful!");
+	}
+
+	@Test
 	public void testGetResource() {
 		log.info("testGetResource");
 		Resource resource = SlingFunctions.getResource(resolver, TEST_PATH);
@@ -132,33 +169,37 @@ public class TestSlingFunctions {
 	}
 
 	@Test
-	public void testGetValue(){
+	public void testGetValue() {
 		log.info("testGetValue");
 		Resource resource = SlingFunctions.getResource(resolver, TEST_PATH);
 		ValueMap properties = resource.adaptTo(ValueMap.class);
-		
+
 		log.info("Testing using class coersion");
-		Date retrievedDate = SlingFunctions.getValue(properties, "date", Date.class);
-		assertEquals(date,retrievedDate);
+		Date retrievedDate = SlingFunctions.getValue(properties, "date",
+				Date.class);
+		assertEquals(date, retrievedDate);
 		assertTrue(retrievedDate instanceof Date);
-		
+
 		log.info("Testing with default value on existing key");
-		Long retrievedLong = SlingFunctions.getValue(properties, "long", new Long(-123L));
-		assertEquals(new Long(0L),retrievedLong);
+		Long retrievedLong = SlingFunctions.getValue(properties, "long",
+				new Long(-123L));
+		assertEquals(new Long(0L), retrievedLong);
 		assertTrue(retrievedLong instanceof Long);
-		
+
 		log.info("Testing with no value and class coersion");
-		Date fakeDate = SlingFunctions.getValue(properties, "date1", Date.class);
+		Date fakeDate = SlingFunctions
+				.getValue(properties, "date1", Date.class);
 		assertTrue(fakeDate == null);
-		
+
 		log.info("Testing with no value and default specified");
-		Long fakeLong = SlingFunctions.getValue(properties, "long1", new Long(-123L));
-		assertEquals(new Long(-123L),fakeLong);
+		Long fakeLong = SlingFunctions.getValue(properties, "long1", new Long(
+				-123L));
+		assertEquals(new Long(-123L), fakeLong);
 		assertTrue(fakeLong instanceof Long);
 
 		log.info("Tests successful!");
 	}
-	
+
 	@Test
 	public void testListChildResources() {
 		log.info("testListChildResources");

Modified: sling/trunk/launchpad/builder/src/main/bundles/list.xml
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/builder/src/main/bundles/list.xml?rev=1604828&r1=1604827&r2=1604828&view=diff
==============================================================================
--- sling/trunk/launchpad/builder/src/main/bundles/list.xml (original)
+++ sling/trunk/launchpad/builder/src/main/bundles/list.xml Mon Jun 23 14:54:51 2014
@@ -299,7 +299,7 @@
         <bundle>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.scripting.jsp.taglib</artifactId>
-            <version>2.2.0</version>
+            <version>2.2.1-SNAPSHOT</version>
         </bundle>
         <bundle>
             <groupId>org.apache.geronimo.bundles</groupId>

Modified: sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/scripting/SlingJSPTaglibTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/scripting/SlingJSPTaglibTest.java?rev=1604828&r1=1604827&r2=1604828&view=diff
==============================================================================
--- sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/scripting/SlingJSPTaglibTest.java (original)
+++ sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/scripting/SlingJSPTaglibTest.java Mon Jun 23 14:54:51 2014
@@ -75,6 +75,13 @@ public class SlingJSPTaglibTest extends 
 		final String content = getContent(testPage + ".html", CONTENT_TYPE_HTML);
 		log.info(content);
 		assertContains(content, "All Tests Succeeded");
+		
+		// tests for the encoding stuff
+		assertContains(content, "HTML_ENCODE:&amp;amp&#x3b;Hello World&#x21;&lt;script&gt;&lt;&#x2f;script&gt;");
+		assertContains(content, "DEFAULT:&amp;amp&#x3b;Hello World&#x21;&lt;script&gt;&lt;&#x2f;script&gt;");
+		assertContains(content, "EL_VALUE:I&#x27;m Awesome&#x21;&#x21;");
+		assertContains(content, "BODY_CONTENT:&amp;copy&#x3b;Body Content");
+		assertContains(content, "BODY_CONTENT_FALLBACK:1");
 
 		log.info("testTaglib - TEST SUCCESSFUL");
 	}

Modified: sling/trunk/launchpad/integration-tests/src/main/resources/integration-test/taglib-test.jsp
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/integration-tests/src/main/resources/integration-test/taglib-test.jsp?rev=1604828&r1=1604827&r2=1604828&view=diff
==============================================================================
--- sling/trunk/launchpad/integration-tests/src/main/resources/integration-test/taglib-test.jsp (original)
+++ sling/trunk/launchpad/integration-tests/src/main/resources/integration-test/taglib-test.jsp Mon Jun 23 14:54:51 2014
@@ -7,15 +7,29 @@ AdaptTo Tag
     Test 1: AdaptTo Tag
     result: <sling:adaptTo adaptable="${resource}" adaptTo="org.apache.sling.api.resource.ValueMap" var="props" /><c:choose><c:when test="${not empty props}">SUCCESS</c:when><c:otherwise>ERROR<c:set var="success" value="false" /></c:otherwise></c:choose>
     
-    Test 2: Test Non-Existent Class Handling
-    result: <sling:adaptTo adaptable="${resource}" adaptTo="org.apache.sling.api.resource.ValueMap2" var="props2" /><c:choose><c:when test="${empty props2}">SUCCESS</c:when><c:otherwise>ERROR<c:set var="success" value="false" /></c:otherwise></c:choose>
-    
-    Test 3: Test Null Adaptable Handling
+    Test 2: Test Null Adaptable Handling
     result: <sling:adaptTo adaptable="${res}" adaptTo="org.apache.sling.api.resource.ValueMap" var="props3" /><c:choose><c:when test="${empty props3}">SUCCESS</c:when><c:otherwise>ERROR<c:set var="success" value="false" /></c:otherwise></c:choose>
     
-    Test 4: Test Non-Adaptable Handling
+    Test 3: Test Non-Adaptable Handling
     result: <c:catch var="adaptionException"><sling:adaptTo adaptable="res" adaptTo="org.apache.sling.api.resource.ValueMap" var="props3" /></c:catch><c:choose><c:when test="${not empty adaptionException}">SUCCESS: ${adaptionException}</c:when><c:otherwise>ERROR<c:set var="success" value="false" /></c:otherwise></c:choose>
 
+Encode Tag
+    Test 1: HTML Encode
+    Result: HTML_ENCODE:<sling:encode value="&amp;Hello World!<script></script>" mode="HTML" />
+
+    Test 2: Default
+    Result: DEFAULT:<sling:encode default="&amp;Hello World!<script></script>" mode="HTML" />
+
+    Test 3: EL Value
+    <c:set var="encode_test">I'm Awesome!!</c:set>
+    Result: EL_VALUE:<sling:encode value="${encode_test}" mode="HTML" />
+    
+    Test 4: Body Content
+    Result: BODY_CONTENT:<sling:encode mode="HTML">&copy;Body Content</sling:encode>
+    
+    Test 5: Body Content Fallback
+    Result: BODY_CONTENT_FALLBACK:<sling:encode value="1" mode="HTML">2</sling:encode>
+    
 Find Resources Tag
     Test 1: Find Resources
     Result: <sling:findResources query="/jcr:root//element(*, nt:file) order by @jcr:score" language="xpath" var="foundResources" /><c:choose><c:when test="${not empty foundResources}">SUCCESS</c:when><c:otherwise>ERROR<c:set var="success" value="false" /></c:otherwise></c:choose>
@@ -68,13 +82,10 @@ AdaptTo Function
     Test 1: AdaptTo
     result: <c:set var="props4" value="${sling:adaptTo(resource,'org.apache.sling.api.resource.ValueMap')}" /><c:choose><c:when test="${not empty props4}">SUCCESS</c:when><c:otherwise>ERROR<c:set var="success" value="false" /></c:otherwise></c:choose>
     
-    Test 2: Test Non-Existent Class Handling
-    result: <c:set var="props5" value="${sling:adaptTo(resource,'org.apache.sling.api.resource.ValueMap2')}" /><c:choose><c:when test="${empty props5}">SUCCESS</c:when><c:otherwise>ERROR<c:set var="success" value="false" /></c:otherwise></c:choose>
-    
-    Test 3: Test Null Adaptable Handling
+    Test 2: Test Null Adaptable Handling
     result: <c:set var="props6" value="${sling:adaptTo(res,'org.apache.sling.api.resource.ValueMap')}" /><c:choose><c:when test="${empty props6}">SUCCESS</c:when><c:otherwise>ERROR<c:set var="success" value="false" /></c:otherwise></c:choose>
     
-    Test 4: Test Non-Adaptable Handling
+    Test 3: Test Non-Adaptable Handling
     result: <c:catch var="adaptionException2"><c:set var="props7" value="${sling:adaptTo('res','org.apache.sling.api.resource.ValueMap')}" /></c:catch><c:choose><c:when test="${not empty adaptionException2}">SUCCESS: ${adaptionException}</c:when><c:otherwise>ERROR<c:set var="success" value="false" /></c:otherwise></c:choose>
 
 Find Resources Function