isapir commented on code in PR #681:
URL: https://github.com/apache/tomcat/pull/681#discussion_r1435945699


##########
java/org/apache/catalina/filters/CsrfPreventionFilter.java:
##########
@@ -87,11 +104,170 @@ public void setNonceRequestParameterName(String 
parameterName) {
         this.nonceRequestParameterName = parameterName;
     }
 
+    /**
+     * Sets the flag to enforce CSRF protection or just log failures as DEBUG
+     * messages.
+     *
+     * @param enforce <code>true</code> to enforce CSRF protections or
+     *                <code>false</code> to log DEBUG messages and allow
+     *                all requests.
+     */
+    public void setEnforce(boolean enforce) {
+        this.enforce = enforce;
+    }
+
+    /**
+     * Gets the flag to enforce CSRF protection or just log failures as DEBUG
+     * messages.
+     *
+     * @return <code>true</code> if CSRF protections will be enforced or
+     *         <code>false</code> if all requests will be allowed and
+     *         failures will be logged as DEBUG messages.
+     */
+    public boolean getEnforce() {
+        return this.enforce;
+    }
+
+    /**
+     * Sets the list of URL patterns to suppress nonce-addition for.
+     *
+     * Some URLs do not need nonces added to them such as static resources.
+     * By <i>not</i> adding nonces to those URLs, HTTP caches can be more
+     * effective because the CSRF prevention filter won't generate what
+     * look like unique URLs for those commonly-reused resources.
+     *
+     * @param patterns A comma-separated list of URL patterns that will not
+     *        have nonces added to them. Patterns may begin or end with a
+     *        <code>*</code> character to denote a suffix-match or
+     *        prefix-match. Any matched URL will not have a CSRF nonce
+     *        added to it when passed through
+     *        {@link HttpServletResponse#encodeURL(String)}.
+     */
+    public void setNoNonceURLPatterns(String patterns) {
+        this.noNoncePatterns = patterns;
+
+        if (null != context) {
+            this.noNoncePredicates = createNoNoncePredicates(context, 
this.noNoncePatterns);
+        }
+    }
+
+    /**
+     * Creates a collection of matchers from a comma-separated string of 
patterns.
+     *
+     * @param patterns A comma-separated string of URL matching patterns.
+     *
+     * @return A collection of predicates representing the URL patterns.
+     */
+    protected static Collection<Predicate<String>> 
createNoNoncePredicates(ServletContext context, String patterns) {
+        if (null == patterns || 0 == patterns.trim().length()) {
+            return null;
+        }
+
+        String values[] = patterns.split(",");
+
+        ArrayList<Predicate<String>> matchers = new ArrayList<>(values.length);
+        for (String value : values) {
+            Predicate<String> p = createNoNoncePredicate(context, 
value.trim());
+
+            if (null != p) {
+                matchers.add(p);
+            }
+        }
+
+        matchers.trimToSize();
+
+        return matchers;
+    }
+
+    /**
+     * Creates a predicate that can match the specified type of pattern.
+     *
+     * @param pattern The pattern to match e.g. <code>*.foo</code> or
+     *                <code>/bar/*</code>.
+     *
+     * @return A Predicate which can match the specified pattern, or
+     *         <code>>null</code> if the pattern is null or blank.
+     */
+    protected static Predicate<String> createNoNoncePredicate(ServletContext 
context, String pattern) {
+        if (null == pattern || 0 == pattern.trim().length()) {
+            return null;
+        }
+        if (pattern.startsWith("mime:")) {
+            return new MimePredicate(context, createNoNoncePredicate(context, 
pattern.substring(5)));
+        } else if (pattern.startsWith("*")) {
+            return new SuffixPredicate(pattern.substring(1));
+        } else if (pattern.endsWith("*")) {
+            return new PrefixPredicate(pattern.substring(0, pattern.length() - 
1));
+        } else if (pattern.startsWith("/") && pattern.endsWith("/")) {
+            return new PatternPredicate(pattern.substring(1, pattern.length() 
- 1));
+        } else {
+            throw new IllegalArgumentException("Unsupported pattern: " + 
pattern);
+        }
+    }
+
+    protected static class MimePredicate implements Predicate<String> {
+        private final ServletContext context;
+        private final Predicate<String> predicate;
+
+        public MimePredicate(ServletContext context, Predicate<String> 
predicate) {
+            this.context = context;
+            this.predicate = predicate;
+        }
+
+        @Override
+        public boolean test(String t) {
+            String mimeType = context.getMimeType(t);
+
+            return predicate.test(mimeType);
+        }
+    }
+
+    protected static class PrefixPredicate implements Predicate<String> {
+        private final String prefix;
+        public PrefixPredicate(String prefix) {
+            this.prefix = prefix;
+        }
+
+        @Override
+        public boolean test(String t) {
+            return t.endsWith(this.prefix);

Review Comment:
   Good catch @michael-o :+1: 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to