You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:12:42 UTC
[sling-org-apache-sling-security] 04/20: SLING-2141 - Add a way to
check the referrer for modification requests
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.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-security.git
commit ac5acb361b4b53b2140436695459a4a6ef11f704
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Fri Jul 15 06:07:54 2011 +0000
SLING-2141 - Add a way to check the referrer for modification requests
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/security@1146968 13f79535-47bb-0310-9956-ffa450edef68
---
pom.xml | 14 ++++
.../apache/sling/security/impl/ReferrerFilter.java | 55 ++++++++++------
.../sling/security/impl/ReferrerFilterTest.java | 74 ++++++++++++++++++++++
3 files changed, 124 insertions(+), 19 deletions(-)
diff --git a/pom.xml b/pom.xml
index 84adade..2c9ef01 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,5 +94,19 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.8.2</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
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 9c0cae2..ed3dec5 100644
--- a/src/main/java/org/apache/sling/security/impl/ReferrerFilter.java
+++ b/src/main/java/org/apache/sling/security/impl/ReferrerFilter.java
@@ -1,19 +1,22 @@
/*
- * Copyright 1997-2011 Day Management AG
- * Barfuesserplatz 6, 4001 Basel, Switzerland
- * All Rights Reserved.
+ * 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
*
- * This software is the confidential and proprietary information of
- * Day Management AG, ("Confidential Information"). You shall not
- * disclose such Confidential Information and shall use it only in
- * accordance with the terms of the license agreement you entered into
- * with Day.
+ * 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.sling.security.impl;
import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@@ -38,6 +41,9 @@ import org.slf4j.LoggerFactory;
label="%referrer.name")
public class ReferrerFilter implements Filter {
+ /** Logger. */
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
private static final boolean DEFAULT_ALLOW_EMPTY = true;
@Property(boolValue=DEFAULT_ALLOW_EMPTY)
@@ -65,9 +71,6 @@ public class ReferrerFilter implements Filter {
}
}
- /** Logger. */
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
private boolean isModification(final HttpServletRequest req) {
final String method = req.getMethod();
if ("POST".equals(method)) {
@@ -100,7 +103,23 @@ public class ReferrerFilter implements Filter {
chain.doFilter(req, res);
}
- private boolean isValidRequest(final HttpServletRequest request) {
+ String getHost(final String referrer) {
+ final int startPos = referrer.indexOf("://") + 3;
+ if ( startPos == 2 ) {
+ // we consider this illegal
+ return null;
+ }
+ final int endPos = referrer.indexOf('/', startPos);
+ final String hostPart = (endPos == -1 ? referrer.substring(startPos) : referrer.substring(startPos, endPos));
+ final int hostNameStart = hostPart.indexOf('@') + 1;
+ final int hostNameEnd = hostPart.lastIndexOf(':');
+ if (hostNameEnd < hostNameStart ) {
+ return hostPart.substring(hostNameStart);
+ }
+ return hostPart.substring(hostNameStart, hostNameEnd);
+ }
+
+ boolean isValidRequest(final HttpServletRequest request) {
final String referrer = request.getHeader("referer");
// check for missing/empty referrer
if ( referrer == null || referrer.trim().length() == 0 ) {
@@ -113,16 +132,14 @@ public class ReferrerFilter implements Filter {
if ( referrer.indexOf(":/") == - 1 ) {
return true;
}
- final URI uri;
- try {
- uri = new URI(referrer);
- } catch (URISyntaxException e) {
+
+ final String host = getHost(referrer);
+ if ( host == null ) {
// if this is invalid we just return invalid
this.logger.info("Rejected illegal referrer header for {} request to {} : {}",
new Object[] {request.getMethod(), request.getRequestURI(), referrer});
return false;
}
- final String host = uri.getHost();
final boolean valid;
if ( this.allowHosts == null ) {
valid = host.equals(request.getServerName());
diff --git a/src/test/java/org/apache/sling/security/impl/ReferrerFilterTest.java b/src/test/java/org/apache/sling/security/impl/ReferrerFilterTest.java
new file mode 100644
index 0000000..f6264c1
--- /dev/null
+++ b/src/test/java/org/apache/sling/security/impl/ReferrerFilterTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.sling.security.impl;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.service.component.ComponentContext;
+
+public class ReferrerFilterTest {
+
+ protected ReferrerFilter filter;
+
+ @Before public void setup() {
+ filter = new ReferrerFilter();
+ final ComponentContext ctx = mock(ComponentContext.class);
+ final Dictionary<String, Object> props = new Hashtable<String, Object>();
+ when(ctx.getProperties()).thenReturn(props);
+ filter.activate(ctx);
+ }
+
+ @Test public void testHostName() {
+ Assert.assertEquals("somehost", filter.getHost("http://somehost"));
+ Assert.assertEquals("somehost", filter.getHost("http://somehost/somewhere"));
+ Assert.assertEquals("somehost", filter.getHost("http://somehost:4242/somewhere"));
+ Assert.assertEquals("somehost", filter.getHost("http://admin@somehost/somewhere"));
+ Assert.assertEquals("somehost", filter.getHost("http://admin@somehost:1/somewhere"));
+ Assert.assertEquals("somehost", filter.getHost("http://admin:admin@somehost/somewhere"));
+ Assert.assertEquals("somehost", filter.getHost("http://admin:admin@somehost:4343/somewhere"));
+ Assert.assertEquals(null, filter.getHost("http:/admin:admin@somehost:4343/somewhere"));
+ }
+
+ private HttpServletRequest getRequest(final String referrer) {
+ final HttpServletRequest request = mock(HttpServletRequest.class);
+ when(request.getMethod()).thenReturn("POST");
+ when(request.getRequestURI()).thenReturn("http://somehost/somewhere");
+ when(request.getHeader("referer")).thenReturn(referrer);
+ when(request.getServerName()).thenReturn("me");
+ return request;
+ }
+
+ @Test public void testValidRequest() {
+ Assert.assertEquals(true, 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://me")));
+ Assert.assertEquals(false, filter.isValidRequest(getRequest("http://somehost/but/[illegal]")));
+ Assert.assertEquals(true, filter.isValidRequest(getRequest("http://me/but/[illegal]")));
+ }
+}
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.