Add entryPoint support to the CSRF prevention filter.
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Sun, 20 Jun 2010 18:59:51 +0000 (18:59 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Sun, 20 Jun 2010 18:59:51 +0000 (18:59 +0000)
git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@956385 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/filters/Constants.java
java/org/apache/catalina/filters/CsrfPreventionFilter.java
webapps/docs/changelog.xml
webapps/docs/config/filter.xml

index 3924d4c..bf0981b 100644 (file)
@@ -36,4 +36,6 @@ public final class Constants {
     
     public static final String CSRF_NONCE_REQUEST_PARAM =
         "org.apache.catalina.filters.CSRF_NONCE";
+
+    public static final String METHOD_GET = "GET";
 }
index 8025ea0..4ccc5c0 100644 (file)
@@ -18,7 +18,9 @@
 package org.apache.catalina.filters;
 
 import java.io.IOException;
+import java.util.HashSet;
 import java.util.Random;
+import java.util.Set;
 
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
@@ -48,11 +50,30 @@ public class CsrfPreventionFilter extends FilterBase {
     
     private final Random randomSource = new Random();
 
+    private final Set<String> entryPoints = new HashSet<String>();
+
     @Override
     protected Log getLogger() {
         return log;
     }
 
+    /**
+     * Entry points are URLs that will not be tested for the presence of a valid
+     * nonce. They are used to provide a way to navigate back to a protected
+     * application after navigating away from it. Entry points will be limited
+     * to HTTP GET requests and should not trigger any security sensitive
+     * actions.
+     * 
+     * @param entryPoints   Comma separated list of URLs to be configured as
+     *                      entry points.
+     */
+    public void setEntryPoints(String entryPoints) {
+        String values[] = entryPoints.split(",");
+        for (String value : values) {
+            this.entryPoints.add(value);
+        }
+    }
+
     public void doFilter(ServletRequest request, ServletResponse response,
             FilterChain chain) throws IOException, ServletException {
 
@@ -64,14 +85,31 @@ public class CsrfPreventionFilter extends FilterBase {
             HttpServletRequest req = (HttpServletRequest) request;
             HttpServletResponse res = (HttpServletResponse) response;
 
-            String previousNonce =
-                req.getParameter(Constants.CSRF_NONCE_REQUEST_PARAM);
-            String expectedNonce = (String) req.getSession(true).getAttribute(
-                    Constants.CSRF_NONCE_SESSION_ATTR_NAME);
+            boolean skipNonceCheck = false;
             
-            if (expectedNonce != null && !expectedNonce.equals(previousNonce)) {
-                res.sendError(HttpServletResponse.SC_FORBIDDEN);
-                return;
+            if (Constants.METHOD_GET.equals(req.getMethod())) {
+                String path = req.getServletPath();
+                if (req.getPathInfo() != null) {
+                    path = path + req.getPathInfo();
+                }
+                
+                if (entryPoints.contains(path)) {
+                    skipNonceCheck = true;
+                }
+            }
+
+            if (!skipNonceCheck) {
+                String previousNonce =
+                    req.getParameter(Constants.CSRF_NONCE_REQUEST_PARAM);
+                String expectedNonce =
+                    (String) req.getSession(true).getAttribute(
+                        Constants.CSRF_NONCE_SESSION_ATTR_NAME);
+                
+                if (expectedNonce != null &&
+                        !expectedNonce.equals(previousNonce)) {
+                    res.sendError(HttpServletResponse.SC_FORBIDDEN);
+                    return;
+                }
             }
             
             String newNonce = generateNonce();
index a1e41bb..0a12880 100644 (file)
@@ -52,6 +52,9 @@
         class in an external repository should not prevent searching of the
         local repositories. (markt) 
       </fix>
+      <add>
+        Add entryPoint support to the CSRF prevention filter. (markt)
+      </add>
     </changelog>
   </subsection>
   <subsection name="Jasper">
index 76bfdc2..fed8810 100644 (file)
 
   <subsection name="Initialisation parameters">
 
-    <p>The CSRF Prevention Filter does not support any initialization
-    parameters.</p>
+    <p>The CSRF Prevention Filter supports the following initialisation
+    parameters:</p>
+
+    <attributes>
 
+      <attribute name="entryPoints" required="false">
+        <p>A comma separated list of URLs that will not be tested for the
+        presence of a valid nonce. They are used to provide a way to navigate
+        back to a protected application after having navigated away from it.
+        Entry points will be limited to HTTP GET requests and should not trigger
+        any security sensitive actions.</p>
+      </attribute>
+      
+    </attributes>
+    
   </subsection>
 
 </section>