VYPR
High severity8.8NVD Advisory· Published Sep 21, 2016· Updated May 6, 2026

CVE-2016-6801

CVE-2016-6801

Description

Cross-site request forgery (CSRF) vulnerability in the CSRF content-type check in Jackrabbit-Webdav in Apache Jackrabbit 2.4.x before 2.4.6, 2.6.x before 2.6.6, 2.8.x before 2.8.3, 2.10.x before 2.10.4, 2.12.x before 2.12.4, and 2.13.x before 2.13.3 allows remote attackers to hijack the authentication of unspecified victims for requests that create a resource via an HTTP POST request with a (1) missing or (2) crafted Content-Type header.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.jackrabbit:jackrabbit-webdavMaven
>= 2.4.0, < 2.4.62.4.6
org.apache.jackrabbit:jackrabbit-webdavMaven
>= 2.6.0, < 2.6.62.6.6
org.apache.jackrabbit:jackrabbit-webdavMaven
>= 2.8.0, < 2.8.32.8.3
org.apache.jackrabbit:jackrabbit-webdavMaven
>= 2.10.0, < 2.10.42.10.4
org.apache.jackrabbit:jackrabbit-webdavMaven
>= 2.12.0, < 2.12.42.12.4
org.apache.jackrabbit:jackrabbit-webdavMaven
>= 2.13.0, < 2.13.32.13.3

Patches

3
16f2f02fcaef

JCR-4009: fix whitespace in log messages

https://github.com/apache/jackrabbitJulian ReschkeSep 22, 2016via ghsa
1 file changed · +4 4
  • jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/util/CSRFUtil.java+4 4 modified
    @@ -102,7 +102,7 @@ public CSRFUtil(String config) {
                 } else {
                     disabled = false;
                     String[] allowed = config.split(",");
    -                allowedReferrerHosts = new HashSet<String>(allowed.length);                
    +                allowedReferrerHosts = new HashSet<String>(allowed.length);
                     for (String entry : allowed) {
                         allowedReferrerHosts.add(entry.trim());
                     }
    @@ -144,7 +144,7 @@ public boolean isValidRequest(HttpServletRequest request) {
                 // empty referrer headers are not allowed for POST + relevant
                 // content types (see JCR-3909)
                 if (refHeader == null) {
    -                log.debug("POST with content type" + ct + " blocked due to missing referer header field");
    +                log.debug("POST with content type " + ct + " blocked due to missing referer header field");
                     return false;
                 }
     
    @@ -155,12 +155,12 @@ public boolean isValidRequest(HttpServletRequest request) {
                     // names
                     boolean ok = host == null || host.equals(request.getServerName()) || allowedReferrerHosts.contains(host);
                     if (!ok) {
    -                    log.debug("POST with content type" + ct + " blocked due to referer header field being: " + refHeader);
    +                    log.debug("POST with content type " + ct + " blocked due to referer header field being: " + refHeader);
                     }
                     return ok;
                 } catch (URISyntaxException ex) {
                     // referrer malformed -> block access
    -                log.debug("POST with content type" + ct + " blocked due to malformed referer header field: " + refHeader);
    +                log.debug("POST with content type " + ct + " blocked due to malformed referer header field: " + refHeader);
                     return false;
                 }
             }
    
eae001a54aae

JCR-4009: CSRF in Jackrabbit-Webdav (CVE-2016-6801)

https://github.com/apache/jackrabbitJulian ReschkeAug 31, 2016via ghsa
5 files changed · +101 41
  • jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/PostMethod.java+1 0 modified
    @@ -47,6 +47,7 @@ class PostMethod extends DavMethodBase {
     
         public PostMethod(String uri) {
             super(uri);
    +        super.setRequestHeader("Referer", uri);
             HttpMethodParams params = getParams();
             params.setContentCharset("UTF-8");
         }
    
  • jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/DavResource.java+1 1 modified
    @@ -40,7 +40,7 @@ public interface DavResource {
         /**
          * String constant representing the WebDAV 1 and 2 method set.
          */
    -    public static final String METHODS = "OPTIONS, GET, HEAD, POST, TRACE, PROPFIND, PROPPATCH, MKCOL, COPY, PUT, DELETE, MOVE, LOCK, UNLOCK";
    +    public static final String METHODS = "OPTIONS, GET, HEAD, TRACE, PROPFIND, PROPPATCH, MKCOL, COPY, PUT, DELETE, MOVE, LOCK, UNLOCK";
     
         /**
          * Returns a comma separated list of all compliance classes the given
    
  • jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/AbstractWebdavServlet.java+1 2 modified
    @@ -596,7 +596,7 @@ protected void doPropPatch(WebdavRequest request, WebdavResponse response,
          */
         protected void doPost(WebdavRequest request, WebdavResponse response,
                               DavResource resource) throws IOException, DavException {
    -        doPut(request, response, resource);
    +        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
         }
     
         /**
    @@ -1384,7 +1384,6 @@ protected InputContext getInputContext(DavServletRequest request, InputStream in
          * @param out
          * @return
          * @see #doPut(WebdavRequest, WebdavResponse, DavResource)
    -     * @see #doPost(WebdavRequest, WebdavResponse, DavResource)
          * @see #doMkCol(WebdavRequest, WebdavResponse, DavResource)
          */
         protected OutputContext getOutputContext(DavServletResponse response, OutputStream out) {
    
  • jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/util/CSRFUtil.java+56 16 modified
    @@ -16,18 +16,20 @@
      */
     package org.apache.jackrabbit.webdav.util;
     
    -import org.apache.jackrabbit.webdav.DavMethods;
    -import org.slf4j.Logger;
    -import org.slf4j.LoggerFactory;
    -
    -import javax.servlet.http.HttpServletRequest;
    -import java.net.MalformedURLException;
    -import java.net.URL;
    +import java.net.URI;
    +import java.net.URISyntaxException;
     import java.util.Arrays;
     import java.util.Collections;
    +import java.util.Enumeration;
     import java.util.HashSet;
    +import java.util.Locale;
     import java.util.Set;
     
    +import javax.servlet.http.HttpServletRequest;
    +
    +import org.slf4j.Logger;
    +import org.slf4j.LoggerFactory;
    +
     /**
      * <code>CSRFUtil</code>...
      */
    @@ -39,7 +41,7 @@ public class CSRFUtil {
         public static final String DISABLED = "disabled";
     
         /**
    -     * Request content types for CSRF checking, see JCR-3909
    +     * Request content types for CSRF checking, see JCR-3909, JCR-4002, and JCR-4009
          */
         public static final Set<String> CONTENT_TYPES = Collections.unmodifiableSet(new HashSet<String>(
                 Arrays.asList(
    @@ -92,6 +94,7 @@ public CSRFUtil(String config) {
             if (config == null || config.length() == 0) {
                 disabled = false;
                 allowedReferrerHosts = Collections.emptySet();
    +            log.debug("CSRF protection disabled");
             } else {
                 if (DISABLED.equalsIgnoreCase(config.trim())) {
                     disabled = true;
    @@ -104,25 +107,62 @@ public CSRFUtil(String config) {
                         allowedReferrerHosts.add(entry.trim());
                     }
                 }
    +            log.debug("CSRF protection enabled, allowed referrers: " + allowedReferrerHosts);
             }
         }
     
    -    public boolean isValidRequest(HttpServletRequest request) throws MalformedURLException {
    -        int methodCode = DavMethods.getMethodCode(request.getMethod());
    -        if (disabled || DavMethods.DAV_POST != methodCode || !CONTENT_TYPES.contains(request.getContentType())) {
    +    public boolean isValidRequest(HttpServletRequest request) {
    +
    +        if (disabled) {
    +            return true;
    +        } else if (!"POST".equals(request.getMethod())) {
    +            // protection only needed for POST
                 return true;
             } else {
    +            Enumeration<String> cts = (Enumeration<String>) request.getHeaders("Content-Type");
    +            String ct = null;
    +            if (cts != null && cts.hasMoreElements()) {
    +                String t = cts.nextElement();
    +                // prune parameters
    +                int semicolon = t.indexOf(';');
    +                if (semicolon >= 0) {
    +                    t = t.substring(0, semicolon);
    +                }
    +                ct = t.trim().toLowerCase(Locale.ENGLISH);
    +            }
    +            if (cts != null && cts.hasMoreElements()) {
    +                // reject if there are more header field instances
    +                log.debug("request blocked because there were multiple content-type header fields");
    +                return false;
    +            }
    +            if (ct != null && !CONTENT_TYPES.contains(ct)) {
    +                // type present and not in blacklist
    +                return true;
    +            }
     
                 String refHeader = request.getHeader("Referer");
    -            // empty referrer headers are not allowed for POST + relevant content types (see JCR-3909)
    +            // empty referrer headers are not allowed for POST + relevant
    +            // content types (see JCR-3909)
                 if (refHeader == null) {
    +                log.debug("POST with content type" + ct + " blocked due to missing referer header field");
                     return false;
                 }
     
    -            String host = new URL(refHeader).getHost();
    -            // test referrer-host equals server or
    -            // if it is contained in the set of explicitly allowed host names
    -            return host.equals(request.getServerName()) || allowedReferrerHosts.contains(host);
    +            try {
    +                String host = new URI(refHeader).getHost();
    +                // test referrer-host equals server or
    +                // if it is contained in the set of explicitly allowed host
    +                // names
    +                boolean ok = host == null || host.equals(request.getServerName()) || allowedReferrerHosts.contains(host);
    +                if (!ok) {
    +                    log.debug("POST with content type" + ct + " blocked due to referer header field being: " + refHeader);
    +                }
    +                return ok;
    +            } catch (URISyntaxException ex) {
    +                // referrer malformed -> block access
    +                log.debug("POST with content type" + ct + " blocked due to malformed referer header field: " + refHeader);
    +                return false;
    +            }
             }
         }
     }
    \ No newline at end of file
    
  • jackrabbit-webdav/src/test/java/org/apache/jackrabbit/webdav/util/CSRFUtilTest.java+42 22 modified
    @@ -16,17 +16,9 @@
      */
     package org.apache.jackrabbit.webdav.util;
     
    -import junit.framework.TestCase;
    -
    -import javax.servlet.RequestDispatcher;
    -import javax.servlet.ServletInputStream;
    -import javax.servlet.http.Cookie;
    -import javax.servlet.http.HttpServletRequest;
    -import javax.servlet.http.HttpSession;
     import java.io.BufferedReader;
     import java.io.IOException;
     import java.io.UnsupportedEncodingException;
    -import java.net.MalformedURLException;
     import java.security.Principal;
     import java.util.ArrayList;
     import java.util.Arrays;
    @@ -37,6 +29,15 @@
     import java.util.Locale;
     import java.util.Map;
     import java.util.Set;
    +import java.util.Vector;
    +
    +import javax.servlet.RequestDispatcher;
    +import javax.servlet.ServletInputStream;
    +import javax.servlet.http.Cookie;
    +import javax.servlet.http.HttpServletRequest;
    +import javax.servlet.http.HttpSession;
    +
    +import junit.framework.TestCase;
     
     /**
      * <code>CSRFUtilTest</code>...
    @@ -55,16 +56,20 @@ public class CSRFUtilTest extends TestCase {
             validURLs.add("http://localhost:4503/jackrabbit/server");
             validURLs.add("https://localhost:4503/jackrabbit/server");
             validURLs.add("https://localhost/jackrabbit/server");
    +        validURLs.add("//localhost/jackrabbit/server");
    +        validURLs.add("/jackrabbit/server");
     
             invalidURLs.add("http://invalidHost/test");
             invalidURLs.add("http://host1:8080/test");
             invalidURLs.add("http://user:pw@host2/test");
         }
     
    -    private static void testValid(CSRFUtil util, Collection<String> validURLs, String method, Set<String> contentTypes) throws MalformedURLException {
    +    static String[] noContentType = new String[0];
    +
    +    private static void testValid(CSRFUtil util, Collection<String> validURLs, String method, Set<String> contentTypes) {
             if (null == contentTypes) {
                 for (String url : validURLs) {
    -                assertTrue(url, util.isValidRequest(createRequest(url, method, null)));
    +                assertTrue(url, util.isValidRequest(createRequest(url, method, noContentType)));
                 }
             } else {
                 for (String contentType : contentTypes) {
    @@ -75,10 +80,10 @@ private static void testValid(CSRFUtil util, Collection<String> validURLs, Strin
             }
         }
     
    -    private static void testInvalid(CSRFUtil util, Collection<String> invalidURLs, String method, Set<String> contentTypes) throws MalformedURLException {
    +    private static void testInvalid(CSRFUtil util, Collection<String> invalidURLs, String method, Set<String> contentTypes) {
             if (null == contentTypes) {
                 for (String url : validURLs) {
    -                assertFalse(url, util.isValidRequest(createRequest(url, method, null)));
    +                assertFalse(url, util.isValidRequest(createRequest(url, method, noContentType)));
                 }
             } else {
                 for (String contentType : contentTypes) {
    @@ -89,8 +94,12 @@ private static void testInvalid(CSRFUtil util, Collection<String> invalidURLs, S
             }
         }
     
    +    private static HttpServletRequest createRequest(String url, String method, String[] contentTypes) {
    +        return new DummyRequest(url, SERVER_NAME, method, contentTypes);
    +    }
    +
         private static HttpServletRequest createRequest(String url, String method, String contentType) {
    -        return new DummyRequest(url, SERVER_NAME, method, contentType);
    +        return new DummyRequest(url, SERVER_NAME, method, new String[] { contentType });
         }
     
         public void testNullConfig() throws Exception {
    @@ -109,6 +118,10 @@ public void testNoReferrer() throws Exception {
             CSRFUtil util = new CSRFUtil("");
             testValid(util, validURLs, POST, CSRFUtil.CONTENT_TYPES);
             assertFalse("no referrer", util.isValidRequest(createRequest(null, POST, "text/plain")));
    +        assertFalse("no referrer", util.isValidRequest(createRequest(null, POST, noContentType)));
    +        assertFalse("no referrer", util.isValidRequest(createRequest(null, POST, "TEXT/PLAIN; foo=bar")));
    +        assertTrue("no referrer", util.isValidRequest(createRequest(null, POST, "application/json")));
    +        assertFalse("no referrer", util.isValidRequest(createRequest(null, POST, new String[] { "application/json", "foo/bar" })));
         }
     
         public void testDisabledConfig() throws Exception {
    @@ -155,13 +168,13 @@ private static final class DummyRequest implements HttpServletRequest {
             private final String referer;
             private final String serverName;
             private final String method;
    -        private final String contentType;
    +        private final String[] contentTypes;
     
    -        private DummyRequest(String referer, String serverName, String method, String contentType) {
    +        private DummyRequest(String referer, String serverName, String method, String[] contentTypes) {
                 this.referer = referer;
                 this.serverName = serverName;
                 this.method = method;
    -            this.contentType = contentType;
    +            this.contentTypes = contentTypes;
             }
     
             //---------------------------------------------< HttpServletRequest >---
    @@ -178,6 +191,19 @@ public String getServerName() {
                 return serverName;
             }
     
    +        public String getContentType() {
    +            return contentTypes.length == 0 ? null : contentTypes[0];
    +        }
    +
    +        @SuppressWarnings({ "rawtypes", "unchecked" })
    +        public Enumeration getHeaders(String name) {
    +            if (name != null && contentTypes.length > 0 && name.toLowerCase(Locale.ENGLISH).equals("content-type")) {
    +                return new Vector(Arrays.asList(contentTypes)).elements();
    +            } else {
    +                return null;
    +            }
    +        }
    +
             //---------------------------------------------------------< unused >---
             public String getAuthType() {
                 return null;
    @@ -188,9 +214,6 @@ public Cookie[] getCookies() {
             public long getDateHeader(String name) {
                 return 0;
             }
    -        public Enumeration getHeaders(String name) {
    -            return null;
    -        }
             public Enumeration getHeaderNames() {
                 return null;
             }
    @@ -266,9 +289,6 @@ public void setCharacterEncoding(String s) throws UnsupportedEncodingException {
             public int getContentLength() {
                 return 0;
             }
    -        public String getContentType() {
    -            return contentType;
    -        }
             public ServletInputStream getInputStream() throws IOException {
                 return null;
             }
    
ea75d7c2aeaa

JCR-4009: back out changes for JCR-4002

https://github.com/apache/jackrabbitJulian ReschkeAug 31, 2016via ghsa
5 files changed · +90 117
  • jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/server/AbstractWebdavServlet.java+2 1 modified
    @@ -596,7 +596,7 @@ protected void doPropPatch(WebdavRequest request, WebdavResponse response,
          */
         protected void doPost(WebdavRequest request, WebdavResponse response,
                               DavResource resource) throws IOException, DavException {
    -        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
    +        doPut(request, response, resource);
         }
     
         /**
    @@ -1384,6 +1384,7 @@ protected InputContext getInputContext(DavServletRequest request, InputStream in
          * @param out
          * @return
          * @see #doPut(WebdavRequest, WebdavResponse, DavResource)
    +     * @see #doPost(WebdavRequest, WebdavResponse, DavResource)
          * @see #doMkCol(WebdavRequest, WebdavResponse, DavResource)
          */
         protected OutputContext getOutputContext(DavServletResponse response, OutputStream out) {
    
  • jackrabbit-webdav/src/main/java/org/apache/jackrabbit/webdav/util/CSRFUtil.java+25 8 modified
    @@ -16,12 +16,14 @@
      */
     package org.apache.jackrabbit.webdav.util;
     
    +import org.apache.jackrabbit.webdav.DavMethods;
     import org.slf4j.Logger;
     import org.slf4j.LoggerFactory;
     
     import javax.servlet.http.HttpServletRequest;
     import java.net.MalformedURLException;
     import java.net.URL;
    +import java.util.Arrays;
     import java.util.Collections;
     import java.util.HashSet;
     import java.util.Set;
    @@ -36,6 +38,19 @@ public class CSRFUtil {
          */
         public static final String DISABLED = "disabled";
     
    +    /**
    +     * Request content types for CSRF checking, see JCR-3909
    +     */
    +    public static final Set<String> CONTENT_TYPES = Collections.unmodifiableSet(new HashSet<String>(
    +            Arrays.asList(
    +                    new String[] {
    +                            "application/x-www-form-urlencoded",
    +                            "multipart/form-data",
    +                            "text/plain"
    +                    }
    +            )
    +    ));
    +
         /**
          * logger instance
          */
    @@ -93,19 +108,21 @@ public CSRFUtil(String config) {
         }
     
         public boolean isValidRequest(HttpServletRequest request) throws MalformedURLException {
    -        if (disabled) {
    +        int methodCode = DavMethods.getMethodCode(request.getMethod());
    +        if (disabled || DavMethods.DAV_POST != methodCode || !CONTENT_TYPES.contains(request.getContentType())) {
                 return true;
             } else {
    +
                 String refHeader = request.getHeader("Referer");
    +            // empty referrer headers are not allowed for POST + relevant content types (see JCR-3909)
                 if (refHeader == null) {
    -                // empty referrer is always allowed
    -                return true;
    -            } else {
    -                String host = new URL(refHeader).getHost();
    -                // test referrer-host equelst server or
    -                // if it is contained in the set of explicitly allowed host names
    -                return host.equals(request.getServerName()) || allowedReferrerHosts.contains(host);
    +                return false;
                 }
    +
    +            String host = new URL(refHeader).getHost();
    +            // test referrer-host equals server or
    +            // if it is contained in the set of explicitly allowed host names
    +            return host.equals(request.getServerName()) || allowedReferrerHosts.contains(host);
             }
         }
     }
    \ No newline at end of file
    
  • jackrabbit-webdav/src/test/java/org/apache/jackrabbit/webdav/server/PostTest.java+0 71 removed
    @@ -1,71 +0,0 @@
    -/*
    - * 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.jackrabbit.webdav.server;
    -
    -import junit.framework.TestCase;
    -import org.apache.commons.httpclient.HttpClient;
    -import org.apache.commons.httpclient.HttpException;
    -import org.apache.commons.httpclient.UsernamePasswordCredentials;
    -import org.apache.commons.httpclient.auth.AuthScope;
    -import org.apache.commons.httpclient.methods.PostMethod;
    -
    -import java.io.IOException;
    -import java.net.URI;
    -
    -/**
    - * Test cases for the WebDAV servlet not executing the POST method (CSRF protection).
    - * <p>
    - * Required system properties:
    - * <ul>
    - * <li>webdav.test.url</li>
    - * <li>webdav.test.username</li>
    - * <li>webdav.test.password</li>
    - * </ul>
    - */
    -
    -public class PostTest extends TestCase {
    -
    -    private String root;
    -    private URI uri;
    -    private String username, password;
    -    private HttpClient client;
    -
    -    protected void setUp() throws Exception {
    -        this.uri = URI.create(System.getProperty("webdav.test.url"));
    -        this.root = this.uri.toASCIIString();
    -        if (!this.root.endsWith("/")) {
    -            this.root += "/";
    -        }
    -        this.username = System.getProperty(("webdav.test.username"), "");
    -        this.password = System.getProperty(("webdav.test.password"), "");
    -        this.client = new HttpClient();
    -        this.client.getState().setCredentials(
    -                new AuthScope(this.uri.getHost(), this.uri.getPort()),
    -                new UsernamePasswordCredentials(this.username, this.password));
    -        super.setUp();
    -    }
    -
    -    protected void tearDown() throws Exception {
    -        super.tearDown();
    -    }
    -
    -    public void testPostDenied() throws HttpException, IOException {
    -        PostMethod options = new PostMethod(this.uri.toASCIIString());
    -        int status = this.client.executeMethod(options);
    -        assertEquals(405, status);
    -    }
    -}
    
  • jackrabbit-webdav/src/test/java/org/apache/jackrabbit/webdav/server/WebdavServerTests.java+0 1 modified
    @@ -26,7 +26,6 @@ public static Test suite() {
             TestSuite suite = new TestSuite("WebDAV Server Tests");
     
             suite.addTestSuite(BindTest.class);
    -        suite.addTestSuite(PostTest.class);
             suite.addTestSuite(RFC4918DestinationHeaderTest.class);
             suite.addTestSuite(RFC4918IfHeaderTest.class);
             suite.addTestSuite(RFC4918PropfindTest.class);
    
  • jackrabbit-webdav/src/test/java/org/apache/jackrabbit/webdav/util/CSRFUtilTest.java+63 36 modified
    @@ -29,11 +29,14 @@
     import java.net.MalformedURLException;
     import java.security.Principal;
     import java.util.ArrayList;
    +import java.util.Arrays;
     import java.util.Collection;
     import java.util.Enumeration;
    +import java.util.HashSet;
     import java.util.List;
     import java.util.Locale;
     import java.util.Map;
    +import java.util.Set;
     
     /**
      * <code>CSRFUtilTest</code>...
    @@ -42,64 +45,77 @@ public class CSRFUtilTest extends TestCase {
     
         private static final String SERVER_NAME = "localhost";
     
    +    private static final String GET = "GET";
    +    private static final String POST = "POST";
    +
         private static final List<String> validURLs = new ArrayList<String>();
    +    private static final List<String> invalidURLs = new ArrayList<String>();
     
         static {
    -        validURLs.add(null);
             validURLs.add("http://localhost:4503/jackrabbit/server");
             validURLs.add("https://localhost:4503/jackrabbit/server");
             validURLs.add("https://localhost/jackrabbit/server");
    +
    +        invalidURLs.add("http://invalidHost/test");
    +        invalidURLs.add("http://host1:8080/test");
    +        invalidURLs.add("http://user:pw@host2/test");
         }
     
    -    private static void testValid(CSRFUtil util, Collection<String> validURLs) throws MalformedURLException {
    -        for (String url : validURLs) {
    -            assertTrue(url, util.isValidRequest(createRequest(url)));
    +    private static void testValid(CSRFUtil util, Collection<String> validURLs, String method, Set<String> contentTypes) throws MalformedURLException {
    +        if (null == contentTypes) {
    +            for (String url : validURLs) {
    +                assertTrue(url, util.isValidRequest(createRequest(url, method, null)));
    +            }
    +        } else {
    +            for (String contentType : contentTypes) {
    +                for (String url : validURLs) {
    +                    assertTrue(url, util.isValidRequest(createRequest(url, method, contentType)));
    +                }
    +            }
             }
         }
     
    -    private static void testInvalid(CSRFUtil util, Collection<String> invalidURLs) throws MalformedURLException {
    -        for (String url : invalidURLs) {
    -            assertFalse(url, util.isValidRequest(createRequest(url)));
    +    private static void testInvalid(CSRFUtil util, Collection<String> invalidURLs, String method, Set<String> contentTypes) throws MalformedURLException {
    +        if (null == contentTypes) {
    +            for (String url : validURLs) {
    +                assertFalse(url, util.isValidRequest(createRequest(url, method, null)));
    +            }
    +        } else {
    +            for (String contentType : contentTypes) {
    +                for (String url : invalidURLs) {
    +                    assertFalse(url, util.isValidRequest(createRequest(url, method, contentType)));
    +                }
    +            }
             }
         }
     
    -    private static HttpServletRequest createRequest(String url) {
    -        return new DummyRequest(url, SERVER_NAME);
    +    private static HttpServletRequest createRequest(String url, String method, String contentType) {
    +        return new DummyRequest(url, SERVER_NAME, method, contentType);
         }
     
         public void testNullConfig() throws Exception {
             CSRFUtil util = new CSRFUtil(null);
    -
    -        testValid(util, validURLs);
    -
    -        List<String> invalidURLs = new ArrayList<String>();
    -        invalidURLs.add("http://invalidHost/test");
    -        invalidURLs.add("http://host1:8080/test");
    -        invalidURLs.add("http://user:pw@host2/test");
    -        testInvalid(util, invalidURLs);
    +        testValid(util, validURLs, POST, CSRFUtil.CONTENT_TYPES);
    +        testInvalid(util, invalidURLs, POST, CSRFUtil.CONTENT_TYPES);
         }
     
         public void testEmptyConfig() throws Exception {
             CSRFUtil util = new CSRFUtil("");
    -        testValid(util, validURLs);
    +        testValid(util, validURLs, POST, CSRFUtil.CONTENT_TYPES);
    +        testInvalid(util, invalidURLs, POST, CSRFUtil.CONTENT_TYPES);
    +    }
     
    -        List<String> invalidURLs = new ArrayList<String>();
    -        invalidURLs.add("http://invalidHost/test");
    -        invalidURLs.add("http://host1:8080/test");
    -        invalidURLs.add("http://user:pw@host2/test");
    -        testInvalid(util, invalidURLs);
    +    public void testNoReferrer() throws Exception {
    +        CSRFUtil util = new CSRFUtil("");
    +        testValid(util, validURLs, POST, CSRFUtil.CONTENT_TYPES);
    +        assertFalse("no referrer", util.isValidRequest(createRequest(null, POST, "text/plain")));
         }
     
         public void testDisabledConfig() throws Exception {
             CSRFUtil util = new CSRFUtil(CSRFUtil.DISABLED);
    -        testValid(util, validURLs);
    -
    +        testValid(util, validURLs, POST, CSRFUtil.CONTENT_TYPES);
             // since test is disabled any other referer host must be allowed
    -        List<String> otherHosts = new ArrayList<String>();
    -        otherHosts.add("http://validHost:80/test");
    -        otherHosts.add("http://host1/test");
    -        otherHosts.add("https://user:pw@host2/test");
    -        testValid(util, otherHosts);
    +        testValid(util, invalidURLs, POST, CSRFUtil.CONTENT_TYPES);
         }
     
         public void testConfig() throws Exception {
    @@ -121,20 +137,31 @@ public void testConfig() throws Exception {
     
             for (String config : configs) {
                 CSRFUtil util = new CSRFUtil(config);
    -            testValid(util, validURLs);
    -            testValid(util, otherHosts);
    -            testInvalid(util, invalidURLs);
    +            testValid(util, validURLs, POST, CSRFUtil.CONTENT_TYPES);
    +            testValid(util, otherHosts, POST, CSRFUtil.CONTENT_TYPES);
    +            testInvalid(util, invalidURLs, POST, CSRFUtil.CONTENT_TYPES);
             }
         }
     
    +    public void testMethodsAndMediaType() throws Exception {
    +        CSRFUtil util = new CSRFUtil("");
    +        testValid(util, invalidURLs, GET, CSRFUtil.CONTENT_TYPES);
    +        testValid(util, invalidURLs, POST, new HashSet<String>(Arrays.asList(new String[] {"application/json"})));
    +        testInvalid(util, invalidURLs, POST, CSRFUtil.CONTENT_TYPES);
    +    }
    +
         private static final class DummyRequest implements HttpServletRequest {
     
             private final String referer;
             private final String serverName;
    +        private final String method;
    +        private final String contentType;
     
    -        private DummyRequest(String referer, String serverName) {
    +        private DummyRequest(String referer, String serverName, String method, String contentType) {
                 this.referer = referer;
                 this.serverName = serverName;
    +            this.method = method;
    +            this.contentType = contentType;
             }
     
             //---------------------------------------------< HttpServletRequest >---
    @@ -171,7 +198,7 @@ public int getIntHeader(String name) {
                 return 0;
             }
             public String getMethod() {
    -            return null;
    +            return method;
             }
             public String getPathInfo() {
                 return null;
    @@ -240,7 +267,7 @@ public int getContentLength() {
                 return 0;
             }
             public String getContentType() {
    -            return null;
    +            return contentType;
             }
             public ServletInputStream getInputStream() throws IOException {
                 return null;
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

10

News mentions

0

No linked articles in our index yet.