You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2022/02/08 15:02:37 UTC

[sling-org-apache-sling-security] branch master updated: SLING-11115 : Allow path exemptions for referrer filter (#6)

This is an automated email from the ASF dual-hosted git repository.

cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-security.git


The following commit(s) were added to refs/heads/master by this push:
     new 1ad3968  SLING-11115 : Allow path exemptions for referrer filter (#6)
1ad3968 is described below

commit 1ad3968a9b7fa9840f209379414c023537dd0851
Author: anchela <an...@adobe.com>
AuthorDate: Tue Feb 8 16:02:34 2022 +0100

    SLING-11115 : Allow path exemptions for referrer filter (#6)
    
    * SLING-11115 : Allow path exemptions for referrer filter
    
    * SLING-11115 : Allow path exemptions for referrer filter (add check for null), additional test for allow_empty option
    
    * SLING-11115 : Allow path exemptions for referrer filter (add check for null)
---
 .../apache/sling/security/impl/ReferrerFilter.java |  39 ++++++-
 .../sling/security/impl/ReferrerFilterTest.java    | 119 +++++++++++++++------
 2 files changed, 123 insertions(+), 35 deletions(-)

diff --git a/src/main/java/org/apache/sling/security/impl/ReferrerFilter.java b/src/main/java/org/apache/sling/security/impl/ReferrerFilter.java
index f1902aa..5125e57 100644
--- a/src/main/java/org/apache/sling/security/impl/ReferrerFilter.java
+++ b/src/main/java/org/apache/sling/security/impl/ReferrerFilter.java
@@ -144,6 +144,15 @@ public class ReferrerFilter implements Preprocessor {
                 description = "List of regexp for user agents not to check the referrer"
         )
         String[] exclude_agents_regexp() default {};
+
+        /**
+         * Excluded the configured paths from the referrer check
+         */
+        @AttributeDefinition(
+                name = "Exclude Paths",
+                description = "List of paths for which not to check the referrer"
+        )
+        String[] exclude_paths() default {};
     }
 
 
@@ -161,9 +170,12 @@ public class ReferrerFilter implements Preprocessor {
     /** Methods to be filtered. */
     private final String[] filterMethods;
 
-    /** Paths to be excluded */
+    /** User agents to be excluded */
     private final Pattern[] excludedRegexUserAgents;
 
+    /** Paths to be excluded */
+    private final String[] excludedPaths;
+
     /**
      * Create a default list of referrers
      */
@@ -253,6 +265,7 @@ public class ReferrerFilter implements Preprocessor {
         this.allowEmpty = config.allow_empty();
         this.allowedRegexReferrers = createRegexPatterns(config.allow_hosts_regexp());
         this.excludedRegexUserAgents = createRegexPatterns(config.exclude_agents_regexp());
+        this.excludedPaths = config.exclude_paths();
 
         final Set<String> allowUriReferrers = getDefaultAllowedReferrers();
         if (config.allow_hosts() != null) {
@@ -350,6 +363,11 @@ public class ReferrerFilter implements Preprocessor {
     }
 
     boolean isValidRequest(final HttpServletRequest request) {
+        // ignore referrer check if the request matches any of the configured excluded path.
+        if (isExcludedPath(request)) {
+            return true;
+        }
+        
         final String referrer = request.getHeader("referer");
         // check for missing/empty referrer
         if (referrer == null || referrer.trim().length() == 0) {
@@ -431,6 +449,25 @@ public class ReferrerFilter implements Preprocessor {
     }
 
     /**
+     * Returns <code>true</code> if the path info associated with the given request is contained in the configured excluded paths.
+     *
+     * @param request The request to check
+     * @return <code>true</code> if the path-info associate with the given request is contained in the configured excluded paths.
+     */
+    private boolean isExcludedPath(HttpServletRequest request) {
+        if (this.excludedPaths == null) {
+            return false;
+        }
+        String path = request.getPathInfo();
+        for (final String excludedPath : this.excludedPaths) {
+            if (excludedPath != null && excludedPath.equals(path)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    /**
      * Returns <code>true</code> if the provided user agent matches any present exclusion regexp pattern.
      *
      * @param userAgent The user agent string to check
diff --git a/src/test/java/org/apache/sling/security/impl/ReferrerFilterTest.java b/src/test/java/org/apache/sling/security/impl/ReferrerFilterTest.java
index 0eb8fc1..53b1f29 100644
--- a/src/test/java/org/apache/sling/security/impl/ReferrerFilterTest.java
+++ b/src/test/java/org/apache/sling/security/impl/ReferrerFilterTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.sling.security.impl;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -33,7 +35,16 @@ public class ReferrerFilterTest {
 
     @Before
     public void setup() {
-        ReferrerFilter.Config config = new ReferrerFilter.Config() {
+        ReferrerFilter.Config config = createConfiguration(false, new String[]{"relhost"}, 
+                new String[]{"http://([^.]*.)?abshost:80", "^app://.+"}, 
+                new String[]{"[a-zA-Z]*\\/[0-9]*\\.[0-9]*;Some-Agent\\s.*"}, 
+                new String[] {null, "/test_path"});
+        filter = new ReferrerFilter(config);
+    }
+
+    private static ReferrerFilter.Config createConfiguration(boolean allowEmpty, String[] allowHosts, String[] allowHostsRexexp, 
+                                                             String[] excludeAgentsRegexp, String[] excludePaths) {
+        return new ReferrerFilter.Config() {
             @Override
             public Class<? extends Annotation> annotationType() {
                 return null;
@@ -41,20 +52,17 @@ public class ReferrerFilterTest {
 
             @Override
             public boolean allow_empty() {
-                return false;
+                return allowEmpty;
             }
 
             @Override
             public String[] allow_hosts() {
-                return new String[]{"relhost"};
+                return allowHosts;
             }
 
             @Override
             public String[] allow_hosts_regexp() {
-                return new String[]{
-                    "http://([^.]*.)?abshost:80",
-                    "^app://.+"
-                };
+                return allowHostsRexexp;
             }
 
             @Override
@@ -64,10 +72,14 @@ public class ReferrerFilterTest {
 
             @Override
             public String[] exclude_agents_regexp() {
-                return new String[]{"[a-zA-Z]*\\/[0-9]*\\.[0-9]*;Some-Agent\\s.*"};
+                return excludeAgentsRegexp;
             }
-        };
-        filter = new ReferrerFilter(config);
+
+            @Override
+            public String[] exclude_paths() {
+                return excludePaths;
+            }
+        }; 
     }
 
     @Test
@@ -86,51 +98,90 @@ public class ReferrerFilterTest {
         Assert.assertEquals("127.0.0.1", filter.getHost("http://127.0.0.1:242").host);
         Assert.assertEquals("localhost", filter.getHost("http://localhost:256235/etewteq.ff").host);
         Assert.assertEquals("127.0.0.1", filter.getHost("http://127.0.0.1/wetew.qerq").host);
-        Assert.assertEquals(null, filter.getHost("http:/admin:admin@somehost:4343/somewhere"));
+        Assert.assertNull(filter.getHost("http:/admin:admin@somehost:4343/somewhere"));
     }
 
-    private HttpServletRequest getRequest(final String referrer, final String userAgent) {
+    private static HttpServletRequest getRequest(final String referrer, final String userAgent, final String pathInfo) {
         final HttpServletRequest request = mock(HttpServletRequest.class);
         when(request.getMethod()).thenReturn("POST");
-        when(request.getRequestURI()).thenReturn("http://somehost/somewhere");
+        if (pathInfo != null) {
+            when(request.getRequestURI()).thenReturn("http://somehost/somewhere"+pathInfo);
+            when(request.getPathInfo()).thenReturn(pathInfo);
+        } else {
+            when(request.getRequestURI()).thenReturn("http://somehost/somewhere");
+        }
         when(request.getHeader("referer")).thenReturn(referrer);
         if ( userAgent != null && userAgent.length() > 0 ) {
             when(request.getHeader("User-Agent")).thenReturn(userAgent);
         }
         return request;
     }
+    
+    private static HttpServletRequest getRequest(final String referrer, final String userAgent) {
+        return getRequest(referrer, userAgent, null);
+    }
 
-    private HttpServletRequest getRequest(final String referrer) {
+    private static HttpServletRequest getRequest(final String referrer) {
         return getRequest(referrer, null);
     }
 
     @Test
     public void testValidRequest() {
-        Assert.assertEquals(false, filter.isValidRequest(getRequest(null)));
-        Assert.assertEquals(true, filter.isValidRequest(getRequest("relative")));
-        Assert.assertEquals(true, filter.isValidRequest(getRequest("/relative/too")));
-        Assert.assertEquals(true, filter.isValidRequest(getRequest("/relative/but/[illegal]")));
-        Assert.assertEquals(false, filter.isValidRequest(getRequest("http://somehost")));
-        Assert.assertEquals(true, filter.isValidRequest(getRequest("http://localhost")));
-        Assert.assertEquals(true, filter.isValidRequest(getRequest("http://127.0.0.1")));
-        Assert.assertEquals(false, filter.isValidRequest(getRequest("http://somehost/but/[illegal]")));
-        Assert.assertEquals(true, filter.isValidRequest(getRequest("http://relhost")));
-        Assert.assertEquals(true, filter.isValidRequest(getRequest("http://relhost:9001")));
-        Assert.assertEquals(false, filter.isValidRequest(getRequest("http://abshost:9001")));
-        Assert.assertEquals(false, filter.isValidRequest(getRequest("https://abshost:80")));
-        Assert.assertEquals(true, filter.isValidRequest(getRequest("http://abshost:80")));
-        Assert.assertEquals(false, filter.isValidRequest(getRequest("http://abshost:9001")));
-        Assert.assertEquals(true, filter.isValidRequest(getRequest("http://another.abshost:80")));
-        Assert.assertEquals(false, filter.isValidRequest(getRequest("http://yet.another.abshost:80")));
-        Assert.assertEquals(true, filter.isValidRequest(getRequest("app://yet.another.abshost:80")));
-        Assert.assertEquals(false, filter.isValidRequest(getRequest("?://")));
+        assertFalse(filter.isValidRequest(getRequest(null)));
+        assertTrue(filter.isValidRequest(getRequest("relative")));
+        assertTrue(filter.isValidRequest(getRequest("/relative/too")));
+        assertTrue(filter.isValidRequest(getRequest("/relative/but/[illegal]")));
+        assertFalse(filter.isValidRequest(getRequest("http://somehost")));
+        assertTrue(filter.isValidRequest(getRequest("http://localhost")));
+        assertTrue(filter.isValidRequest(getRequest("http://127.0.0.1")));
+        assertFalse(filter.isValidRequest(getRequest("http://somehost/but/[illegal]")));
+        assertTrue(filter.isValidRequest(getRequest("http://relhost")));
+        assertTrue(filter.isValidRequest(getRequest("http://relhost:9001")));
+        assertFalse(filter.isValidRequest(getRequest("http://abshost:9001")));
+        assertFalse(filter.isValidRequest(getRequest("https://abshost:80")));
+        assertTrue(filter.isValidRequest(getRequest("http://abshost:80")));
+        assertFalse(filter.isValidRequest(getRequest("http://abshost:9001")));
+        assertTrue(filter.isValidRequest(getRequest("http://another.abshost:80")));
+        assertFalse(filter.isValidRequest(getRequest("http://yet.another.abshost:80")));
+        assertTrue(filter.isValidRequest(getRequest("app://yet.another.abshost:80")));
+        assertFalse(filter.isValidRequest(getRequest("?://")));
+    }
+    
+    @Test
+    public void testExcludedPath() {
+        assertTrue(filter.isValidRequest(getRequest(null, null, "/test_path")));
+        assertFalse(filter.isValidRequest(getRequest(null, null, "/test_path/subtree")));
+        assertFalse(filter.isValidRequest(getRequest(null, null, "/test_path_sibling")));
+        
+        assertTrue(filter.isValidRequest(getRequest("relative", null, "/test_path")));
+        assertTrue(filter.isValidRequest(getRequest("http://yet.another.abshost:80", null, "/test_path")));
+    }
+
+    @Test
+    public void testExcludedPathNull() {
+        ReferrerFilter rf = new ReferrerFilter(createConfiguration(false, null, null, null, null));
+        
+        assertFalse(rf.isValidRequest(getRequest(null, null, "/test_path")));
+        assertFalse(rf.isValidRequest(getRequest(null, null, "/test_path/subtree")));
+        assertFalse(rf.isValidRequest(getRequest(null, null, "/test_path_sibling")));
+
+        assertTrue(rf.isValidRequest(getRequest("relative", null, "/test_path")));
+        assertFalse(rf.isValidRequest(getRequest("http://yet.another.abshost:80", null, "/test_path")));
+    }
+    
+    @Test
+    public void testAllowEmpty() {
+        ReferrerFilter rf = new ReferrerFilter(createConfiguration(true, null, null, null, null));
+
+        assertTrue(rf.isValidRequest(getRequest(null, null, "/test_path")));
+        assertTrue(rf.isValidRequest(getRequest("", null, null)));
     }
 
     @Test
     public void testIsBrowserRequest() {
         String userAgent = "Mozilla/5.0;Some-Agent (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko)";
-        Assert.assertEquals(false, filter.isBrowserRequest(getRequest(null, userAgent)));
+        assertFalse(filter.isBrowserRequest(getRequest(null, userAgent)));
         userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko)";
-        Assert.assertEquals(true, filter.isBrowserRequest(getRequest(null, userAgent)));
+        assertTrue(filter.isBrowserRequest(getRequest(null, userAgent)));
     }
 }