You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2018/08/01 16:11:03 UTC

nifi git commit: NIFI-5442 Get X-ProxyContextPath value from request attributes rather than directly from headers. NIFI-5442 Populate request contextPath attribute during AccessResource before displaying on message-page.jsp. Refactored shared code from C

Repository: nifi
Updated Branches:
  refs/heads/master 9742dd2fa -> e62aa0252


NIFI-5442 Get X-ProxyContextPath value from request attributes rather than directly from headers.
NIFI-5442 Populate request contextPath attribute during AccessResource before displaying on message-page.jsp.
Refactored shared code from CatchAllFilter to WebUtils.
NIFI-5442 Refactored filter and context path code to shared parent filter and subclass.
NIFI-5442 Removed unnecessary initParams from nifi-web-ui web.xml.
NIFI-5442 Added explicit dispatchers to nifi-web-ui web.xml and removed unnecessary code from AccessResource.

This closes #2908


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/e62aa025
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/e62aa025
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/e62aa025

Branch: refs/heads/master
Commit: e62aa0252dfcf34dff0c3a9c51265b1d0f9dfc9f
Parents: 9742dd2
Author: Andy LoPresto <al...@apache.org>
Authored: Wed Jul 18 16:08:31 2018 -0700
Committer: Matt Gilman <ma...@gmail.com>
Committed: Wed Aug 1 12:10:14 2018 -0400

----------------------------------------------------------------------
 .../web/filter/SanitizeContextPathFilter.java   | 81 ++++++++++++++++++++
 .../java/org/apache/nifi/web/util/WebUtils.java | 25 +++++-
 .../org/apache/nifi/web/server/JettyServer.java | 70 ++++++++---------
 .../org/apache/nifi/web/api/AccessResource.java |  8 +-
 .../apache/nifi/web/filter/CatchAllFilter.java  | 52 ++++---------
 .../src/main/webapp/WEB-INF/web.xml             |  8 ++
 .../nifi-framework/nifi-web/nifi-web-ui/pom.xml |  5 ++
 .../main/webapp/WEB-INF/pages/message-page.jsp  | 17 ++--
 .../nifi-web-ui/src/main/webapp/WEB-INF/web.xml | 15 ++++
 9 files changed, 192 insertions(+), 89 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/e62aa025/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/filter/SanitizeContextPathFilter.java
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/filter/SanitizeContextPathFilter.java b/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/filter/SanitizeContextPathFilter.java
new file mode 100644
index 0000000..00b98d2
--- /dev/null
+++ b/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/filter/SanitizeContextPathFilter.java
@@ -0,0 +1,81 @@
+/*
+ * 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.nifi.web.filter;
+
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import org.apache.nifi.web.util.WebUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This filter intercepts a request and populates the {@code contextPath} attribute on the request with a sanitized value (originally) retrieved from {@code nifi.properties}.
+ */
+public class SanitizeContextPathFilter implements Filter {
+    private static final Logger logger = LoggerFactory.getLogger(SanitizeContextPathFilter.class);
+
+    private String whitelistedContextPaths = "";
+
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+        String providedWhitelist = filterConfig.getServletContext().getInitParameter("whitelistedContextPaths");
+        logger.debug("SanitizeContextPathFilter received provided whitelisted context paths from NiFi properties: " + providedWhitelist);
+        if (providedWhitelist != null) {
+            whitelistedContextPaths = providedWhitelist;
+        }
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
+        // Inject the contextPath attribute into the request
+        injectContextPathAttribute(request);
+
+        // Pass execution to the next filter in the chain
+        filterChain.doFilter(request, response);
+    }
+
+    /**
+     * Determines, sanitizes, and injects the {@code contextPath} attribute into the {@code request}. If not present, an empty string {@code ""} is injected.
+     * @param request the request
+     */
+    protected void injectContextPathAttribute(ServletRequest request) {
+        // Capture the provided context path headers and sanitize them before using in the response
+        String contextPath = WebUtils.sanitizeContextPath(request, whitelistedContextPaths, "");
+        request.setAttribute("contextPath", contextPath);
+
+        logger.debug("SanitizeContextPathFilter set contextPath: " + contextPath);
+    }
+
+    @Override
+    public void destroy() {
+    }
+
+    /**
+     * Getter for whitelistedContextPaths. Cannot be package-private because of an issue where the package is scoped per classloader.
+     *
+     * @return the whitelisted context path(s)
+     */
+    protected String getWhitelistedContextPaths() {
+        return whitelistedContextPaths;
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/e62aa025/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebUtils.java
----------------------------------------------------------------------
diff --git a/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebUtils.java b/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebUtils.java
index 21a41fd..cbf64e6 100644
--- a/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebUtils.java
+++ b/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebUtils.java
@@ -21,13 +21,12 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
-
 import javax.net.ssl.SSLContext;
+import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.ClientBuilder;
 import javax.ws.rs.core.UriBuilderException;
-
 import org.apache.commons.lang3.StringUtils;
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider;
@@ -177,6 +176,28 @@ public final class WebUtils {
     }
 
     /**
+     * Returns a "safe" context path value from the request headers to use in a proxy environment.
+     * This is used on the JSP to build the resource paths for the external resources (CSS, JS, etc.).
+     * If no headers are present specifying this value, it is an empty string.
+     *
+     * @param request the HTTP request
+     * @return the context path safe to be printed to the page
+     */
+    public static String sanitizeContextPath(ServletRequest request, String whitelistedContextPaths, String jspDisplayName) {
+        if (StringUtils.isBlank(jspDisplayName)) {
+            jspDisplayName = "JSP page";
+        }
+        String contextPath = normalizeContextPath(determineContextPath((HttpServletRequest) request));
+        try {
+            verifyContextPath(whitelistedContextPaths, contextPath);
+            return contextPath;
+        } catch (UriBuilderException e) {
+            logger.error("Error determining context path on " + jspDisplayName + ": " + e.getMessage());
+            return "";
+        }
+    }
+
+    /**
      * Determines the context path if populated in {@code X-ProxyContextPath} or {@code X-ForwardContext} headers. If not populated, returns an empty string.
      *
      * @param request the HTTP request

http://git-wip-us.apache.org/repos/asf/nifi/blob/e62aa025/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
index 2f93ec8..971353b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
@@ -18,6 +18,40 @@ package org.apache.nifi.web.server;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.stream.Collectors;
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.NiFiServer;
@@ -68,41 +102,6 @@ import org.springframework.context.ApplicationContext;
 import org.springframework.web.context.WebApplicationContext;
 import org.springframework.web.context.support.WebApplicationContextUtils;
 
-import javax.servlet.DispatcherType;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletResponse;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileFilter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.stream.Collectors;
-
 /**
  * Encapsulates the Jetty instance.
  */
@@ -317,6 +316,7 @@ public class JettyServer implements NiFiServer {
         final WebAppContext webUiContext = loadWar(webUiWar, "/nifi", frameworkClassLoader);
         webUiContext.getInitParams().put("oidc-supported", String.valueOf(props.isOidcEnabled()));
         webUiContext.getInitParams().put("knox-supported", String.valueOf(props.isKnoxSsoEnabled()));
+        webUiContext.getInitParams().put("whitelistedContextPaths", props.getWhitelistedContextPaths());
         handlers.addHandler(webUiContext);
 
         // load the web api app

http://git-wip-us.apache.org/repos/asf/nifi/blob/e62aa025/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
index 236e14e..f2dd697 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java
@@ -340,8 +340,8 @@ public class AccessResource extends ApplicationResource {
             httpServletResponse.sendRedirect(postLogoutRedirectUri);
         } else {
             URI logoutUri = UriBuilder.fromUri(endSessionEndpoint)
-                .queryParam("post_logout_redirect_uri", postLogoutRedirectUri)
-                .build();
+                    .queryParam("post_logout_redirect_uri", postLogoutRedirectUri)
+                    .build();
             httpServletResponse.sendRedirect(logoutUri.toString());
         }
     }
@@ -765,7 +765,7 @@ public class AccessResource extends ApplicationResource {
      * Gets the value of a cookie matching the specified name. If no cookie with that name exists, null is returned.
      *
      * @param cookies the cookies
-     * @param name the name of the cookie
+     * @param name    the name of the cookie
      * @return the value of the corresponding cookie, or null if the cookie does not exist
      */
     private String getCookieValue(final Cookie[] cookies, final String name) {
@@ -786,7 +786,7 @@ public class AccessResource extends ApplicationResource {
 
     private String getNiFiUri() {
         final String nifiApiUrl = generateResourceUri();
-        final String baseUrl = StringUtils.substringBeforeLast(nifiApiUrl,"/nifi-api");
+        final String baseUrl = StringUtils.substringBeforeLast(nifiApiUrl, "/nifi-api");
         return baseUrl + "/nifi";
     }
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/e62aa025/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/main/java/org/apache/nifi/web/filter/CatchAllFilter.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/main/java/org/apache/nifi/web/filter/CatchAllFilter.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/main/java/org/apache/nifi/web/filter/CatchAllFilter.java
index 71d1a2b..fa94e64 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/main/java/org/apache/nifi/web/filter/CatchAllFilter.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/main/java/org/apache/nifi/web/filter/CatchAllFilter.java
@@ -17,65 +17,45 @@
 package org.apache.nifi.web.filter;
 
 import java.io.IOException;
-import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.UriBuilderException;
-import org.apache.nifi.web.util.WebUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Filter for forward all requests to index.jsp.
+ * This filter catches all requests and explicitly forwards them to a JSP ({@code index.jsp} injected in
+ * the filter configuration. This is used to handle all errors (this module is only used for errors). It
+ * extends {@link SanitizeContextPathFilter} which sanitizes the context path and injects it as a request
+ * attribute to be used on the page for linking resources without XSS vulnerabilities.
  */
-public class CatchAllFilter implements Filter {
+public class CatchAllFilter extends SanitizeContextPathFilter {
     private static final Logger logger = LoggerFactory.getLogger(CatchAllFilter.class);
 
-    private static String whitelistedContextPaths = "";
+    private String forwardPath = "";
+    private String displayPath = "";
 
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {
-        String providedWhitelist = filterConfig.getServletContext().getInitParameter("whitelistedContextPaths");
-        logger.debug("CatchAllFilter received provided whitelisted context paths from NiFi properties: " + providedWhitelist);
-        if (providedWhitelist != null) {
-            whitelistedContextPaths = providedWhitelist;
-        }
+        // TODO: Perform path validation (against what set of rules)?
+        forwardPath = filterConfig.getInitParameter("forwardPath");
+        displayPath = filterConfig.getInitParameter("displayPath");
+
+        logger.debug("CatchAllFilter  [" + displayPath + "] received provided whitelisted context paths from NiFi properties: " + getWhitelistedContextPaths());
     }
 
     @Override
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
-        // Capture the provided context path headers and sanitize them before using in the response
-        String contextPath = getSanitizedContextPath(request);
-        request.setAttribute("contextPath", contextPath);
+        // Inject the contextPath attribute into the request
+        injectContextPathAttribute(request);
 
-        // for all requests to index.jsp
-        request.getRequestDispatcher("/index.jsp").forward(request, response);
+        // Forward all requests to index.jsp
+        request.getRequestDispatcher(forwardPath).forward(request, response);
     }
 
     @Override
     public void destroy() {
     }
-
-    /**
-     * Returns a "safe" context path value from the request headers to use in a proxy environment.
-     * This is used on the JSP to build the resource paths for the external resources (CSS, JS, etc.).
-     * If no headers are present specifying this value, it is an empty string.
-     *
-     * @param request the HTTP request
-     * @return the context path safe to be printed to the page
-     */
-    private String getSanitizedContextPath(ServletRequest request) {
-        String contextPath = WebUtils.normalizeContextPath(WebUtils.determineContextPath((HttpServletRequest) request));
-        try {
-            WebUtils.verifyContextPath(whitelistedContextPaths, contextPath);
-            return contextPath;
-        } catch (UriBuilderException e) {
-            logger.error("Error determining context path on index.jsp: " + e.getMessage());
-            return "";
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/e62aa025/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/main/webapp/WEB-INF/web.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/main/webapp/WEB-INF/web.xml
index 8921175..3fb27e3 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/main/webapp/WEB-INF/web.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/main/webapp/WEB-INF/web.xml
@@ -18,6 +18,14 @@
     <filter>
         <filter-name>catch-all-filter</filter-name>
         <filter-class>org.apache.nifi.web.filter.CatchAllFilter</filter-class>
+        <init-param>
+            <param-name>displayPath</param-name>
+            <param-value>index.jsp</param-value>
+        </init-param>
+        <init-param>
+            <param-name>forwardPath</param-name>
+            <param-value>/index.jsp</param-value>
+        </init-param>
     </filter>
     <filter-mapping>
         <filter-name>catch-all-filter</filter-name>

http://git-wip-us.apache.org/repos/asf/nifi/blob/e62aa025/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
index c713e41..abeffa7 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml
@@ -924,6 +924,11 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-web-utils</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
             <scope>provided</scope>

http://git-wip-us.apache.org/repos/asf/nifi/blob/e62aa025/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/message-page.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/message-page.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/message-page.jsp
index 1c82a62..9999ec0 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/message-page.jsp
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/message-page.jsp
@@ -17,18 +17,11 @@
 <%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
 <!DOCTYPE html>
 <html xmlns="http://www.w3.org/1999/xhtml">
-    <%
-        String contextPath = request.getHeader("X-ProxyContextPath");
-        if (contextPath == null) {
-            contextPath = request.getHeader("X-Forwarded-Context");
-        }
-        if (contextPath == null) {
-            contextPath = "";
-        }
-        if (contextPath.endsWith("/")) {
-            contextPath = contextPath.substring(0, contextPath.length() - 1);
-        }
-    %>
+<%
+    // Sanitize the contextPath to ensure it is on this server
+    // rather than getting it from the header directly
+    String contextPath = request.getAttribute("contextPath").toString();
+%>
     <head>
         <title><%= request.getAttribute("title") == null ? "" : org.apache.nifi.util.EscapeUtils.escapeHtml(request.getAttribute("title").toString()) %></title>
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

http://git-wip-us.apache.org/repos/asf/nifi/blob/e62aa025/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/web.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/web.xml
index 3a0ce25..0639dd6 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/web.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/web.xml
@@ -146,6 +146,21 @@
         <url-pattern>/logout</url-pattern>
     </filter-mapping>
 
+    <!-- catch all filter -->
+    <filter>
+        <filter-name>SanitizeContextPathFilter</filter-name>
+        <filter-class>org.apache.nifi.web.filter.SanitizeContextPathFilter</filter-class>
+    </filter>
+    <filter-mapping>
+        <filter-name>SanitizeContextPathFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+        <dispatcher>REQUEST</dispatcher>
+        <dispatcher>FORWARD</dispatcher>
+        <dispatcher>INCLUDE</dispatcher>
+        <dispatcher>ERROR</dispatcher>
+        <dispatcher>ASYNC</dispatcher>
+    </filter-mapping>
+
     <welcome-file-list>
         <welcome-file>canvas.jsp</welcome-file>
         <welcome-file>/WEB-INF/pages/canvas.jsp</welcome-file>