From a070b77f28ef1a30a5e05f9c34d4a1c9c4e6084e Mon Sep 17 00:00:00 2001 From: markt Date: Mon, 21 Mar 2011 22:08:47 +0000 Subject: [PATCH] Make the CSRF nonce cache serializable to fix an issue reported on the users list. Custom serialization code could shave ~20% but the code isn't as clean. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1083987 13f79535-47bb-0310-9956-ffa450edef68 --- .../catalina/filters/CsrfPreventionFilter.java | 5 ++- .../catalina/filters/TestCsrfPreventionFilter.java | 41 ++++++++++++++++++++++ webapps/docs/changelog.xml | 4 +++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/java/org/apache/catalina/filters/CsrfPreventionFilter.java b/java/org/apache/catalina/filters/CsrfPreventionFilter.java index 7151907ac..018963256 100644 --- a/java/org/apache/catalina/filters/CsrfPreventionFilter.java +++ b/java/org/apache/catalina/filters/CsrfPreventionFilter.java @@ -18,6 +18,7 @@ package org.apache.catalina.filters; import java.io.IOException; +import java.io.Serializable; import java.security.SecureRandom; import java.util.HashSet; import java.util.LinkedHashMap; @@ -287,7 +288,9 @@ public class CsrfPreventionFilter extends FilterBase { } } - private static class LruCache { + protected static class LruCache implements Serializable { + + private static final long serialVersionUID = 1L; // Although the internal implementation uses a Map, this cache // implementation is only concerned with the keys. diff --git a/test/org/apache/catalina/filters/TestCsrfPreventionFilter.java b/test/org/apache/catalina/filters/TestCsrfPreventionFilter.java index 46ebe5a30..92f8905ef 100644 --- a/test/org/apache/catalina/filters/TestCsrfPreventionFilter.java +++ b/test/org/apache/catalina/filters/TestCsrfPreventionFilter.java @@ -17,8 +17,14 @@ package org.apache.catalina.filters; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + import javax.servlet.http.HttpServletResponse; +import org.apache.catalina.filters.CsrfPreventionFilter.LruCache; import org.apache.catalina.startup.TomcatBaseTest; public class TestCsrfPreventionFilter extends TomcatBaseTest { @@ -50,6 +56,41 @@ public class TestCsrfPreventionFilter extends TomcatBaseTest { wrapper.encodeRedirectURL("/test?a=b#c")); } + public void testLruCacheSerializable() throws Exception { + LruCache cache = new LruCache(5); + cache.add("key1"); + cache.add("key2"); + cache.add("key3"); + cache.add("key4"); + cache.add("key5"); + cache.add("key6"); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(cache); + + ByteArrayInputStream bais = + new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bais); + @SuppressWarnings("unchecked") + LruCache cache2 = (LruCache) ois.readObject(); + + cache2.add("key7"); + assertFalse(cache2.contains("key1")); + assertFalse(cache2.contains("key2")); + assertTrue(cache2.contains("key3")); + assertTrue(cache2.contains("key4")); + assertTrue(cache2.contains("key5")); + assertTrue(cache2.contains("key6")); + assertTrue(cache2.contains("key7")); + } + + public void testLruCacheSerializablePerformance() throws Exception { + for (int i = 0; i < 10000; i++) { + testLruCacheSerializable(); + } + } + private static class NonEncodingResponse extends TesterResponse { @Override diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index b51b83f1b..3dca0286d 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -77,6 +77,10 @@ 50929: When wrapping an exception, include the root cause. Patch provided by sebb. (markt) + + Make the CSRF nonce cache serializable so that it can be replicated + across a cluster and/or persisted across Tomcat restarts. (markt) + -- 2.11.0