Skip to content

Commit

Permalink
Add unit tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristopherSchultz committed Jan 11, 2024
1 parent 48beb65 commit b60ec71
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 0 deletions.
4 changes: 4 additions & 0 deletions java/org/apache/catalina/filters/CsrfPreventionFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ public boolean test(String t) {

return predicate.test(mimeType);
}

public Predicate<String> getPredicate() {
return predicate;
}
}

/**
Expand Down
109 changes: 109 additions & 0 deletions test/org/apache/catalina/filters/TestCsrfPreventionFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.function.Predicate;

import jakarta.servlet.http.HttpServletResponse;

Expand All @@ -28,6 +33,7 @@

import org.apache.catalina.filters.CsrfPreventionFilter.LruCache;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.tomcat.unittest.TesterServletContext;

public class TestCsrfPreventionFilter extends TomcatBaseTest {

Expand Down Expand Up @@ -92,6 +98,109 @@ public void testLruCacheSerializablePerformance() throws Exception {
}
}


@Test
public void testNoNonceBuilders() {
Assert.assertEquals(CsrfPreventionFilter.PrefixPredicate.class, CsrfPreventionFilter.createNoNoncePredicate(null, "/images/*").getClass());
Assert.assertEquals(CsrfPreventionFilter.SuffixPredicate.class, CsrfPreventionFilter.createNoNoncePredicate(null, "*.png").getClass());
Assert.assertEquals(CsrfPreventionFilter.PatternPredicate.class, CsrfPreventionFilter.createNoNoncePredicate(null, "/^(/images/.*|.*\\.png)$/").getClass());

Collection<Predicate<String>> chain = CsrfPreventionFilter.createNoNoncePredicates(null, "*.png,/js/*,*.jpg,/images/*,mime:*/png,mime:image/*");

Assert.assertEquals(6, chain.size());
Iterator<Predicate<String>> items = chain.iterator();

Assert.assertEquals(CsrfPreventionFilter.SuffixPredicate.class, items.next().getClass());
Assert.assertEquals(CsrfPreventionFilter.PrefixPredicate.class, items.next().getClass());
Assert.assertEquals(CsrfPreventionFilter.SuffixPredicate.class, items.next().getClass());
Assert.assertEquals(CsrfPreventionFilter.PrefixPredicate.class, items.next().getClass());
Predicate<String> item = items.next();
Assert.assertEquals(CsrfPreventionFilter.MimePredicate.class, item.getClass());
Assert.assertEquals(CsrfPreventionFilter.SuffixPredicate.class, ((CsrfPreventionFilter.MimePredicate)item).getPredicate().getClass());

item = items.next();
Assert.assertEquals(CsrfPreventionFilter.MimePredicate.class, item.getClass());
Assert.assertEquals(CsrfPreventionFilter.PrefixPredicate.class, ((CsrfPreventionFilter.MimePredicate)item).getPredicate().getClass());
}

@Test
public void testNoNoncePatternMatchers() {
String[] urls = { "/images/home.png" };
Predicate<String> prefix = new CsrfPreventionFilter.PrefixPredicate("/images/");
Predicate<String> suffix = new CsrfPreventionFilter.SuffixPredicate(".png");
Predicate<String> regex = new CsrfPreventionFilter.PatternPredicate("^(/images/.*|.*\\.png)$");

for(String url : urls) {
Assert.assertTrue("Prefix match fails", prefix.test(url));
Assert.assertTrue("Suffix match fails", suffix.test(url));
Assert.assertTrue("Pattern match fails", regex.test(url));
}

ArrayList<Predicate<String>> chain = new ArrayList<>();
chain.add(prefix);
chain.add(suffix);
chain.add(regex);

HttpServletResponse response = new CsrfPreventionFilter.CsrfResponseWrapper(new NonEncodingResponse(),
Constants.CSRF_NONCE_SESSION_ATTR_NAME, "TESTNONCE", chain);

// These URLs should include nonces
Assert.assertEquals("/foo?" + RESULT_NONCE, response.encodeURL("/foo"));
Assert.assertEquals("/foo/images?" + RESULT_NONCE, response.encodeURL("/foo/images"));
Assert.assertEquals("/foo/images/home.jpg?" + RESULT_NONCE, response.encodeURL("/foo/images/home.jpg"));

// These URLs should not
Assert.assertEquals("/images/home.png", response.encodeURL("/images/home.png"));
Assert.assertEquals("/images/home.jpg", response.encodeURL("/images/home.jpg"));
Assert.assertEquals("/home.png", response.encodeURL("/home.png"));
Assert.assertEquals("/home.png", response.encodeURL("/home.png"));
}

@Test
public void testNoNonceMimeMatcher() {
MimeTypeServletContext context = new MimeTypeServletContext();
Predicate<String> mime = new CsrfPreventionFilter.MimePredicate(context, new CsrfPreventionFilter.PrefixPredicate("image/"));

context.setMimeType("image/png");
Assert.assertTrue("MIME match fails", mime.test("/images/home.png"));

context.setMimeType("text/plain");
Assert.assertFalse("MIME match succeeds where it should fail", mime.test("/test.txt"));

Collection<Predicate<String>> chain = Collections.singleton(mime);
HttpServletResponse response = new CsrfPreventionFilter.CsrfResponseWrapper(new NonEncodingResponse(),
Constants.CSRF_NONCE_SESSION_ATTR_NAME, "TESTNONCE", chain);

// These URLs should include nonces
Assert.assertEquals("/foo?" + RESULT_NONCE, response.encodeURL("/foo"));
Assert.assertEquals("/foo/images?" + RESULT_NONCE, response.encodeURL("/foo/images"));
Assert.assertEquals("/foo/images/home.jpg?" + RESULT_NONCE, response.encodeURL("/foo/images/home.jpg"));
Assert.assertEquals("/images/home.png?" + RESULT_NONCE, response.encodeURL("/images/home.png"));
Assert.assertEquals("/images/home.jpg?" + RESULT_NONCE, response.encodeURL("/images/home.jpg"));
Assert.assertEquals("/home.png?" + RESULT_NONCE, response.encodeURL("/home.png"));

context.setMimeType("image/png");
// These URLs should not
Assert.assertEquals("/images/home.png", response.encodeURL("/images/home.png"));
Assert.assertEquals("/images/home.jpg", response.encodeURL("/images/home.jpg"));
Assert.assertEquals("/home.png", response.encodeURL("/home.png"));
Assert.assertEquals("/foo", response.encodeURL("/foo"));
Assert.assertEquals("/foo/home.png", response.encodeURL("/foo/home.png"));
Assert.assertEquals("/foo/images/home.jpg", response.encodeURL("/foo/images/home.jpg"));

}

private static class MimeTypeServletContext extends TesterServletContext {
private String mimeType;
public void setMimeType(String type) {
mimeType = type;
}

@Override
public String getMimeType(String url) {
return mimeType;
}
}
private static class NonEncodingResponse extends TesterHttpServletResponse {

@Override
Expand Down

0 comments on commit b60ec71

Please sign in to comment.