Author: taylor
Date: Mon Jun 22 23:36:06 2015
New Revision: 1686957
URL: http://svn.apache.org/r1686957
Log:
JS2-1328: backporting XSS new features from trunk
Added:
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/engine/servlet/XSSRequestWrapper.java
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/engine/servlet/XXSUrlAttackFilter.java
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/administration/PortalConfigurationConstants.java
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-portal-resources/src/main/resources/conf/jetspeed/jetspeed.properties
Added: portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/engine/servlet/XSSRequestWrapper.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/engine/servlet/XSSRequestWrapper.java?rev=1686957&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/engine/servlet/XSSRequestWrapper.java (added)
+++ portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/engine/servlet/XSSRequestWrapper.java Mon Jun 22 23:36:06 2015
@@ -0,0 +1,178 @@
+/*
+ * 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.jetspeed.engine.servlet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+public class XSSRequestWrapper extends HttpServletRequestWrapper {
+
+ private final static Logger log = LoggerFactory.getLogger(XSSRequestWrapper.class);
+
+ private static Pattern[] patterns = null;
+
+ public static synchronized void initPatterns(String[] regexes, String[] flags) {
+ if (regexes == null || regexes.length == 0) {
+ log.error("Error: Empty XSS Regex array provided from jetspeed.properties");
+ return;
+ }
+ if (flags == null || flags.length == 0) {
+ log.error("Error: Empty XSS Regex Flag array provided from jetspeed.properties");
+ return;
+ }
+ if (regexes.length != flags.length) {
+ log.error("XSS Regex and flag arrays not equal in jetspeed.properties");
+ return;
+ }
+ patterns = new Pattern[regexes.length];
+ int ix = 0;
+ for (String regex : regexes) {
+ try {
+ String[] values = flags[ix].split("\\s*\\|\\s*");
+ int orFlags = 0;
+ for (String value : values) {
+ orFlags |= Integer.parseInt(value);
+ }
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("--- adding pattern: [%s] with flags %d\n", regex, orFlags));
+ }
+ patterns[ix] = Pattern.compile(regex, orFlags);
+ }
+ catch (Exception e) {
+ log.error("Failed to compile regex: " + regex, e);
+ }
+ finally {
+ ix++;
+ }
+
+ }
+ }
+
+ private static Pattern[] hardCodedPatterns = new Pattern[]{
+ // Script fragments
+ Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),
+ // src='...'
+// Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
+// Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
+// // lonely script tags
+ Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),
+ Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
+// // eval(...)
+// Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
+// // expression(...)
+// Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
+// // javascript:...
+ Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE),
+// // vbscript:...
+ Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE),
+// // onload(...)=...
+ Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL)
+ };
+
+ public XSSRequestWrapper(HttpServletRequest servletRequest) {
+ super(servletRequest);
+ }
+
+ @Override
+ public String[] getParameterValues(String parameter) {
+ String[] values = super.getParameterValues(parameter);
+
+ if (values == null) {
+ return null;
+ }
+
+ if (values.length == 0) {
+ return values;
+ }
+
+ int count = values.length;
+ String[] encodedValues = new String[count];
+ for (int i = 0; i < count; i++) {
+ encodedValues[i] = stripXSS(values[i]);
+ }
+
+ return encodedValues;
+ }
+
+ @Override
+ public String getParameter(String parameter) {
+ String value = super.getParameter(parameter);
+ if (value == null) {
+ return value;
+ }
+ return stripXSS(value);
+ }
+
+ @Override
+ public Map<String, String[]> getParameterMap() {
+ Map<String, String[]> parameterMap = super.getParameterMap();
+ if (parameterMap == null) {
+ return parameterMap;
+ }
+ if (parameterMap.size() == 0) {
+ return parameterMap;
+ }
+ Iterator<String> parameterIterator = parameterMap.keySet().iterator();
+ Map<String, String[]> newMap = new LinkedHashMap<String, String[]>();
+ while (parameterIterator.hasNext()) {
+ String key = parameterIterator.next().toString();
+ String[] values = parameterMap.get(key);
+ if (values != null) {
+ String[] newValues = new String[values.length];
+ for (int i = 0; i < values.length; i++) {
+ newValues[i] = stripXSS(values[i]);
+ }
+ newMap.put(key, newValues);
+ }
+ }
+ return newMap;
+ }
+
+ // @Override
+// public String getHeader(String name) {
+// String value = super.getHeader(name);
+// return stripXSS(value);
+// }
+
+ private String stripXSS(String value) {
+ if (value != null) {
+
+ // Avoid null characters
+ value = value.replaceAll("\0", "");
+
+ String original = value;
+ // Remove all sections that match a pattern
+ if (patterns != null) {
+ for (Pattern scriptPattern : patterns) {
+ int length = value.length();
+ value = scriptPattern.matcher(value).replaceAll("");
+ if (value.length() != length) {
+ log.error("XSS attack post data found: " + original);
+ }
+ }
+ }
+ }
+ return value;
+ }
+}
\ No newline at end of file
Modified: portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/engine/servlet/XXSUrlAttackFilter.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/engine/servlet/XXSUrlAttackFilter.java?rev=1686957&r1=1686956&r2=1686957&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/engine/servlet/XXSUrlAttackFilter.java (original)
+++ portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/engine/servlet/XXSUrlAttackFilter.java Mon Jun 22 23:36:06 2015
@@ -16,7 +16,11 @@
*/
package org.apache.jetspeed.engine.servlet;
-import java.io.IOException;
+import org.apache.jetspeed.Jetspeed;
+import org.apache.jetspeed.administration.PortalConfiguration;
+import org.apache.jetspeed.administration.PortalConfigurationConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@@ -26,6 +30,7 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
/**
* Simple XXS Url attack protection blocking access whenever the request url contains a < or > character.
@@ -34,6 +39,12 @@ import javax.servlet.http.HttpServletRes
*/
public class XXSUrlAttackFilter implements Filter
{
+ private final static Logger log = LoggerFactory.getLogger(XXSUrlAttackFilter.class);
+
+ private PortalConfiguration portalConfiguration = null;
+ private boolean xssRequestEnabled = true;
+ private boolean xssPostEnabled = false;
+
public void init(FilterConfig config) throws ServletException
{
}
@@ -41,15 +52,35 @@ public class XXSUrlAttackFilter implemen
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException
{
+ if (portalConfiguration == null) {
+ portalConfiguration = Jetspeed.getConfiguration();
+ xssRequestEnabled = portalConfiguration.getBoolean(PortalConfigurationConstants.XSS_FILTER_REQUEST, true);
+ xssPostEnabled = portalConfiguration.getBoolean(PortalConfigurationConstants.XSS_FILTER_POST, false);
+ if (xssPostEnabled) {
+ XSSRequestWrapper.initPatterns(portalConfiguration.getStringArray(PortalConfigurationConstants.XSS_REGEX),
+ portalConfiguration.getStringArray(PortalConfigurationConstants.XSS_FLAGS));
+ }
+ }
if (request instanceof HttpServletRequest)
{
- HttpServletRequest hreq = (HttpServletRequest) request;
- if (isInvalid(hreq.getQueryString()) || isInvalid(hreq.getRequestURI()))
- {
- ((HttpServletResponse) response).sendError(HttpServletResponse.SC_BAD_REQUEST);
+ if (xssRequestEnabled) {
+ HttpServletRequest hreq = (HttpServletRequest) request;
+ if (isInvalid(hreq.getQueryString())) {
+ log.error("XSS attack query string found: " + hreq.getQueryString());
+ ((HttpServletResponse) response).sendError(HttpServletResponse.SC_BAD_REQUEST);
+ }
+ if (isInvalid(hreq.getRequestURI())) {
+ log.error("XSS attack URI found: " + hreq.getRequestURI());
+ ((HttpServletResponse) response).sendError(HttpServletResponse.SC_BAD_REQUEST);
+ }
}
}
- chain.doFilter(request, response);
+ if (xssPostEnabled) {
+ chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
+ }
+ else {
+ chain.doFilter(request, response);
+ }
}
private boolean isInvalid(String value)
Modified: portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/administration/PortalConfigurationConstants.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/administration/PortalConfigurationConstants.java?rev=1686957&r1=1686956&r2=1686957&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/administration/PortalConfigurationConstants.java (original)
+++ portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/administration/PortalConfigurationConstants.java Mon Jun 22 23:36:06 2015
@@ -17,9 +17,9 @@
package org.apache.jetspeed.administration;
/**
- * PortalConfiguration portal configuration contants
- * TODO: integrate Configuration with JMX
- *
+ * Portal Configuration constants to read only portal global settings. These constants are the keys in the portal
+ * configuration store jetspeed.properties and override.properties.
+ *
* @author <a href="mailto:[email protected]">David Sean Taylor</a>
* @version $Id: $
*/
@@ -98,4 +98,10 @@ public interface PortalConfigurationCons
/** Portlet Modes, Window States: return string arrays **/
static final String SUPPORTED_WINDOW_STATES = "supported.windowstate";
static final String SUPPORTED_PORTLET_MODES = "supported.portletmode";
+
+ /** XSS */
+ static final String XSS_FILTER_REQUEST = "xss.filter.request";
+ static final String XSS_FILTER_POST = "xss.filter.post";
+ static final String XSS_REGEX = "xss.filter.regexes";
+ static final String XSS_FLAGS = "xss.filter.flags";
}
Modified: portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-portal-resources/src/main/resources/conf/jetspeed/jetspeed.properties
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-portal-resources/src/main/resources/conf/jetspeed/jetspeed.properties?rev=1686957&r1=1686956&r2=1686957&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-portal-resources/src/main/resources/conf/jetspeed/jetspeed.properties (original)
+++ portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-portal-resources/src/main/resources/conf/jetspeed/jetspeed.properties Mon Jun 22 23:36:06 2015
@@ -412,3 +412,27 @@ jetui.style.drag.handle = .PTitle
# redirect to home space on login
jetui.redirect.home.space=true
+#-------------------------------------------------------------------------
+# XSS Filtering
+# since 2.3.0
+#-------------------------------------------------------------------------
+xss.filter.request = true
+xss.filter.post = true
+xss.filter.regexes = <script>(.*?)</script>
+xss.filter.flags = 2
+xss.filter.regexes = </script>
+xss.filter.flags = 2
+xss.filter.regexes = <script(.*?)>
+xss.filter.flags = 2 | 8 | 32
+xss.filter.regexes = javascript:
+xss.filter.flags = 2
+xss.filter.regexes = vbscript:
+xss.filter.flags = 2
+xss.filter.regexes = onload(.*?)=
+xss.filter.flags = 2 | 8 | 32
+xss.filter.regexes = eval\\((.*?)\\)
+xss.filter.flags = 2 | 8 | 32
+xss.filter.regexes = expression\\((.*?)\\)
+xss.filter.flags = 2 | 8 | 32
+
+
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.