This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.security-1.0.12 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-security.git
commit 25c57332507f918b153897cab7d9b7c9929c0d18 Author: Antonio Sanso <[email protected]> AuthorDate: Tue Jul 28 09:22:19 2015 +0000 SLING-4883 - Extend content disposition filter protection to jcr:data git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/security@1693046 13f79535-47bb-0310-9956-ffa450edef68 --- .../security/impl/ContentDispositionFilter.java | 25 ++--- .../impl/ContentDispositionFilterTest.java | 118 ++++++++++++++++++--- 2 files changed, 114 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java b/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java index 9b72674..9eccb06 100644 --- a/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java +++ b/src/main/java/org/apache/sling/security/impl/ContentDispositionFilter.java @@ -202,30 +202,31 @@ public class ContentDispositionFilter implements Filter { return; } request.setAttribute(ATTRIBUTE_NAME, type); + Resource resource = request.getResource(); + String resourcePath = resource.getPath(); + + if (contentDispositionPaths.contains(resourcePath)) { - String pathInfo = request.getPathInfo(); - if (contentDispositionPaths.contains(pathInfo)) { - - if (contentTypesMapping.containsKey(pathInfo)) { - Set <String> exceptions = contentTypesMapping.get(pathInfo); + if (contentTypesMapping.containsKey(resourcePath)) { + Set <String> exceptions = contentTypesMapping.get(resourcePath); if (!exceptions.contains(type)) { - setContentDisposition(); + setContentDisposition(resource); } } else { - setContentDisposition(); + setContentDisposition(resource); } } for (String path : contentDispositionPathsPfx) { - if (request.getPathInfo().startsWith(path)) { + if (resourcePath.startsWith(path)) { if (contentTypesMapping.containsKey(path)) { Set <String> exceptions = contentTypesMapping.get(path); if (!exceptions.contains(type)) { - setContentDisposition(); + setContentDisposition(resource); break; } } else { - setContentDisposition(); + setContentDisposition(resource); break; } @@ -236,8 +237,8 @@ public class ContentDispositionFilter implements Filter { //---------- PRIVATE METHODS --------- - private void setContentDisposition() { - if (!this.containsHeader(CONTENT_DISPOSTION)) { + private void setContentDisposition(Resource resource) { + if (!this.containsHeader(CONTENT_DISPOSTION) && this.isJcrData(resource)) { this.addHeader(CONTENT_DISPOSTION, CONTENT_DISPOSTION_ATTACHMENT); } } diff --git a/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java b/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java index 51b6477..abc2c4f 100644 --- a/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java +++ b/src/test/java/org/apache/sling/security/impl/ContentDispositionFilterTest.java @@ -213,6 +213,8 @@ public class ContentDispositionFilterTest { public void test_doFilter1() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); + contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -234,7 +236,9 @@ public class ContentDispositionFilterTest { allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue(null)); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/libs")); allowing(response).setContentType("text/html"); //CONTENT DISPOSITION MUST NOT SET @@ -249,6 +253,7 @@ public class ContentDispositionFilterTest { public void test_doFilter2() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -270,7 +275,9 @@ public class ContentDispositionFilterTest { allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue(null)); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/content/usergenerated/author")); allowing(response).setContentType("text/html"); //CONTENT DISPOSITION MUST NOT SET @@ -284,6 +291,8 @@ public class ContentDispositionFilterTest { public void test_doFilter3() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); + final ValueMap properties = context.mock(ValueMap.class); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -303,7 +312,7 @@ public class ContentDispositionFilterTest { final ContentDispositionFilter.RewriterResponse rewriterResponse = contentDispositionFilter. new RewriterResponse(request, response) { public void addHeader(String name, String value) { counter.incrementAndGet(); - } + } }; context.checking(new Expectations() { @@ -313,8 +322,14 @@ public class ContentDispositionFilterTest { allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue(null)); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/content/usergenerated")); + allowing(resource).adaptTo(ValueMap.class); + will(returnValue(properties)); + allowing(properties).containsKey(PROP_JCR_DATA); + will(returnValue(true)); allowing(response).setContentType("text/html"); //CONTENT DISPOSITION IS SET exactly(1).of(response).addHeader("Content-Disposition", "attachment"); @@ -328,6 +343,7 @@ public class ContentDispositionFilterTest { public void test_doFilter4() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -349,7 +365,9 @@ public class ContentDispositionFilterTest { allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue(null)); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/libs")); allowing(response).setContentType("text/html"); //CONTENT DISPOSITION MUST NOT SET @@ -364,6 +382,8 @@ public class ContentDispositionFilterTest { public void test_doFilter5() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); + final ValueMap properties = context.mock(ValueMap.class); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -392,8 +412,14 @@ public class ContentDispositionFilterTest { allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue(null)); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/content/usergenerated/author")); + allowing(resource).adaptTo(ValueMap.class); + will(returnValue(properties)); + allowing(properties).containsKey(PROP_JCR_DATA); + will(returnValue(true)); allowing(response).setContentType("text/html"); //CONTENT DISPOSITION IS SET exactly(1).of(response).addHeader("Content-Disposition", "attachment"); @@ -407,6 +433,8 @@ public class ContentDispositionFilterTest { public void test_doFilter6() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); + final ValueMap properties = context.mock(ValueMap.class); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -435,8 +463,14 @@ public class ContentDispositionFilterTest { allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue(null)); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/content/usergenerated/")); + allowing(resource).adaptTo(ValueMap.class); + will(returnValue(properties)); + allowing(properties).containsKey(PROP_JCR_DATA); + will(returnValue(true)); allowing(response).setContentType("text/html"); //CONTENT DISPOSITION IS SET exactly(1).of(response).addHeader("Content-Disposition", "attachment"); @@ -450,6 +484,7 @@ public class ContentDispositionFilterTest { public void test_doFilter7() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -471,7 +506,9 @@ public class ContentDispositionFilterTest { allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue(null)); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/libs")); allowing(response).setContentType("text/html"); //CONTENT DISPOSITION MUST NOT SET @@ -486,6 +523,7 @@ public class ContentDispositionFilterTest { public void test_doFilter8() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -507,7 +545,9 @@ public class ContentDispositionFilterTest { allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue(null)); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/content/usergenerated/author")); allowing(response).setContentType("text/html"); //CONTENT DISPOSITION MUST NOT SET @@ -521,6 +561,7 @@ public class ContentDispositionFilterTest { public void test_doFilter9() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -542,7 +583,9 @@ public class ContentDispositionFilterTest { allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue(null)); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/content/usergenerated")); allowing(response).setContentType("text/html"); //CONTENT DISPOSITION MUST NOT SET @@ -556,6 +599,8 @@ public class ContentDispositionFilterTest { public void test_doFilter10() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); + final ValueMap properties = context.mock(ValueMap.class); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -584,8 +629,14 @@ public class ContentDispositionFilterTest { allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue(null)); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "image/jpeg"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/content/usergenerated")); + allowing(resource).adaptTo(ValueMap.class); + will(returnValue(properties)); + allowing(properties).containsKey(PROP_JCR_DATA); + will(returnValue(true)); allowing(response).setContentType("image/jpeg"); //CONTENT DISPOSITION IS SET exactly(1).of(response).addHeader("Content-Disposition", "attachment"); @@ -599,6 +650,7 @@ public class ContentDispositionFilterTest { public void test_doFilter11() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -620,7 +672,9 @@ public class ContentDispositionFilterTest { allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue(null)); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/libs")); allowing(response).setContentType("text/html"); //CONTENT DISPOSITION MUST NOT SET @@ -635,6 +689,7 @@ public class ContentDispositionFilterTest { public void test_doFilter12() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -656,7 +711,9 @@ public class ContentDispositionFilterTest { allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue(null)); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/content/usergenerated/author")); allowing(response).setContentType("text/html"); //CONTENT DISPOSITION MUST NOT SET @@ -670,6 +727,7 @@ public class ContentDispositionFilterTest { public void test_doFilter13() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -691,7 +749,9 @@ public class ContentDispositionFilterTest { allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue(null)); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/content/usergenerated/author")); allowing(response).setContentType("text/html"); //CONTENT DISPOSITION MUST NOT SET @@ -705,6 +765,8 @@ public class ContentDispositionFilterTest { public void test_doFilter14() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); + final ValueMap properties = context.mock(ValueMap.class); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -734,8 +796,14 @@ public class ContentDispositionFilterTest { allowing(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue(null)); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "image/jpeg"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/content/usergenerated/author")); + allowing(resource).adaptTo(ValueMap.class); + will(returnValue(properties)); + allowing(properties).containsKey(PROP_JCR_DATA); + will(returnValue(true)); allowing(response).setContentType("image/jpeg"); //CONTENT DISPOSITION IS SET exactly(1).of(response).addHeader("Content-Disposition", "attachment"); @@ -753,6 +821,8 @@ public class ContentDispositionFilterTest { public void test_doFilter15() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); + final ValueMap properties = context.mock(ValueMap.class); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -783,8 +853,14 @@ public class ContentDispositionFilterTest { exactly(1).of(request).getAttribute(RewriterResponse.ATTRIBUTE_NAME); will(returnValue("text/html")); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/content/usergenerated")); + allowing(resource).adaptTo(ValueMap.class); + will(returnValue(properties)); + allowing(properties).containsKey(PROP_JCR_DATA); + will(returnValue(true)); allowing(response).setContentType("text/html"); //CONTENT DISPOSITION IS SET exactly(1).of(response).addHeader("Content-Disposition", "attachment"); @@ -802,6 +878,8 @@ public class ContentDispositionFilterTest { public void test_doFilter16() throws Throwable{ final SlingHttpServletRequest request = context.mock(SlingHttpServletRequest.class); final SlingHttpServletResponse response = context.mock(SlingHttpServletResponse.class); + final Resource resource = context.mock(Resource.class, "resource" ); + final ValueMap properties = context.mock(ValueMap.class); contentDispositionFilter = new ContentDispositionFilter(); final ComponentContext ctx = context.mock(ComponentContext.class); @@ -836,8 +914,14 @@ public class ContentDispositionFilterTest { will(returnValue("text/html")); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/xml"); allowing(request).setAttribute(RewriterResponse.ATTRIBUTE_NAME, "text/html"); - allowing(request).getPathInfo(); + allowing(request).getResource(); + will(returnValue(resource)); + allowing(resource).getPath(); will(returnValue("/content/usergenerated")); + allowing(resource).adaptTo(ValueMap.class); + will(returnValue(properties)); + allowing(properties).containsKey(PROP_JCR_DATA); + will(returnValue(true)); allowing(response).setContentType("text/html"); allowing(response).setContentType("text/xml"); //CONTENT DISPOSITION IS SET -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
