You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by ma...@apache.org on 2017/05/10 21:04:43 UTC
archiva-redback-core git commit: Fixing X-Forwarded-Host header
handling
Repository: archiva-redback-core
Updated Branches:
refs/heads/master 396694765 -> 4e4e3428c
Fixing X-Forwarded-Host header handling
Project: http://git-wip-us.apache.org/repos/asf/archiva-redback-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/archiva-redback-core/commit/4e4e3428
Tree: http://git-wip-us.apache.org/repos/asf/archiva-redback-core/tree/4e4e3428
Diff: http://git-wip-us.apache.org/repos/asf/archiva-redback-core/diff/4e4e3428
Branch: refs/heads/master
Commit: 4e4e3428c4f7db396f36cc169c2a67c0d05ea6e7
Parents: 3966947
Author: Martin Stockhammer <ma...@apache.org>
Authored: Wed May 10 22:59:51 2017 +0200
Committer: Martin Stockhammer <ma...@apache.org>
Committed: Wed May 10 22:59:51 2017 +0200
----------------------------------------------------------------------
.../RequestValidationInterceptor.java | 28 ++-
.../RequestValidationInterceptorTest.java | 249 ++++++++++++-------
2 files changed, 175 insertions(+), 102 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/4e4e3428/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/RequestValidationInterceptor.java
----------------------------------------------------------------------
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/RequestValidationInterceptor.java b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/RequestValidationInterceptor.java
index 0351348..2b8f1c6 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/RequestValidationInterceptor.java
+++ b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/RequestValidationInterceptor.java
@@ -31,6 +31,7 @@ import org.apache.archiva.redback.integration.filter.authentication.basic.HttpBa
import org.apache.archiva.redback.policy.AccountLockedException;
import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.archiva.redback.users.User;
+import org.apache.commons.lang.StringUtils;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.message.Message;
import org.slf4j.Logger;
@@ -343,7 +344,7 @@ public class RequestValidationInterceptor
catch ( MalformedURLException ex )
{
log.error( "Configured baseUrl (rest.baseUrl={}) is invalid. Message: {}", baseUrlStr,
- ex.getMessage() );
+ ex.getMessage() );
}
}
}
@@ -405,7 +406,7 @@ public class RequestValidationInterceptor
if ( noHeader && denyAbsentHeaders )
{
log.warn( "Request denied. No Origin or Referer header found and {}=true",
- UserConfigurationKeys.REST_CSRF_ABSENTORIGIN_DENY );
+ UserConfigurationKeys.REST_CSRF_ABSENTORIGIN_DENY );
containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() );
return;
}
@@ -483,7 +484,7 @@ public class RequestValidationInterceptor
if ( !td.isValid() || !td.getUser().equals( username ) )
{
log.error( "Invalid data in validation token header {} for user {}: isValid={}, username={}",
- X_XSRF_TOKEN, username, td.isValid(), td.getUser() );
+ X_XSRF_TOKEN, username, td.isValid(), td.getUser() );
containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() );
}
}
@@ -535,15 +536,22 @@ public class RequestValidationInterceptor
{
xforwardedProto = requestUrl.getProtocol();
}
- if ( xforwarded != null )
+
+ if ( xforwarded != null && !StringUtils.isEmpty( xforwarded ) )
{
- try
- {
- urls.add( new URL( xforwardedProto + "://" + xforwarded ) );
- }
- catch ( MalformedURLException ex )
+ // X-Forwarded-Host header may contain multiple hosts if there is
+ // more than one proxy between the client and the server
+ String[] forwardedList = xforwarded.split( "\\s*,\\s*" );
+ for ( String hostname : forwardedList )
{
- log.warn( "X-Forwarded-Host Header is malformed: {}", ex.getMessage() );
+ try
+ {
+ urls.add( new URL( xforwardedProto + "://" + hostname ) );
+ }
+ catch ( MalformedURLException ex )
+ {
+ log.warn( "X-Forwarded-Host Header is malformed: {}", ex.getMessage() );
+ }
}
}
return urls;
http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/4e4e3428/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/RequestValidationInterceptorTest.java
----------------------------------------------------------------------
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/RequestValidationInterceptorTest.java b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/RequestValidationInterceptorTest.java
index aad961a..4668c4a 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/RequestValidationInterceptorTest.java
+++ b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/RequestValidationInterceptorTest.java
@@ -38,169 +38,234 @@ import java.util.List;
/**
* Created by Martin Stockhammer on 21.01.17.
- *
+ * <p>
* Unit Test for RequestValidationInterceptor. The unit tests are all without token validation.
- *
*/
-@RunWith(JUnit4.class)
-public class RequestValidationInterceptorTest extends TestCase {
-
+@RunWith( JUnit4.class )
+public class RequestValidationInterceptorTest extends TestCase
+{
@Test
- public void validateRequestWithoutHeader() throws UserConfigurationException, IOException {
+ public void validateRequestWithoutHeader() throws UserConfigurationException, IOException
+ {
TokenManager tm = new TokenManager();
MockUserConfiguration cfg = new MockUserConfiguration();
- cfg.addValue(UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION,"true");
- RequestValidationInterceptor interceptor = new RequestValidationInterceptor(cfg);
+ cfg.addValue( UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION, "true" );
+ RequestValidationInterceptor interceptor = new RequestValidationInterceptor( cfg );
MockHttpServletRequest request = new MockHttpServletRequest();
- interceptor.setHttpRequest(request);
+ interceptor.setHttpRequest( request );
+ interceptor.init();
+ MockContainerRequestContext ctx = new MockContainerRequestContext();
+ interceptor.filter( ctx );
+ assertTrue( ctx.isAborted() );
+ }
+
+ @Test
+ public void validateRequestWithOrigin() throws UserConfigurationException, IOException
+ {
+ TokenManager tm = new TokenManager();
+ MockUserConfiguration cfg = new MockUserConfiguration();
+ cfg.addValue( UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION, "true" );
+ RequestValidationInterceptor interceptor = new RequestValidationInterceptor( cfg );
+ MockHttpServletRequest request = new MockHttpServletRequest( "GET", "/api/v1/userService" );
+ request.setServerName( "test.archiva.org" );
+ request.addHeader( "Origin", "http://test.archiva.org/myservlet" );
+ interceptor.setHttpRequest( request );
+ interceptor.init();
+ MockContainerRequestContext ctx = new MockContainerRequestContext();
+ interceptor.filter( ctx );
+ assertFalse( ctx.isAborted() );
+ }
+
+ @Test
+ public void validateRequestWithBadOrigin() throws UserConfigurationException, IOException
+ {
+ TokenManager tm = new TokenManager();
+ MockUserConfiguration cfg = new MockUserConfiguration();
+ cfg.addValue( UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION, "true" );
+ RequestValidationInterceptor interceptor = new RequestValidationInterceptor( cfg );
+ MockHttpServletRequest request = new MockHttpServletRequest( "GET", "/api/v1/userService" );
+ request.setServerName( "test.archiva.org" );
+ request.addHeader( "Origin", "http://test2.archiva.org/myservlet" );
+ interceptor.setHttpRequest( request );
+ interceptor.init();
+ MockContainerRequestContext ctx = new MockContainerRequestContext();
+ interceptor.filter( ctx );
+ assertTrue( ctx.isAborted() );
+ }
+
+ @Test
+ public void validateRequestWithReferer() throws UserConfigurationException, IOException
+ {
+ TokenManager tm = new TokenManager();
+ MockUserConfiguration cfg = new MockUserConfiguration();
+ cfg.addValue( UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION, "true" );
+ RequestValidationInterceptor interceptor = new RequestValidationInterceptor( cfg );
+ MockHttpServletRequest request = new MockHttpServletRequest( "GET", "/api/v1/userService" );
+ request.setServerName( "test.archiva.org" );
+ request.addHeader( "Referer", "http://test.archiva.org/myservlet2" );
+ interceptor.setHttpRequest( request );
interceptor.init();
MockContainerRequestContext ctx = new MockContainerRequestContext();
- interceptor.filter(ctx);
- assertTrue(ctx.isAborted());
+ interceptor.filter( ctx );
+ assertFalse( ctx.isAborted() );
}
@Test
- public void validateRequestWithOrigin() throws UserConfigurationException, IOException {
+ public void validateRequestWithBadReferer() throws UserConfigurationException, IOException
+ {
TokenManager tm = new TokenManager();
MockUserConfiguration cfg = new MockUserConfiguration();
- cfg.addValue(UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION,"true");
- RequestValidationInterceptor interceptor = new RequestValidationInterceptor(cfg);
- MockHttpServletRequest request = new MockHttpServletRequest("GET","/api/v1/userService");
- request.setServerName("test.archiva.org");
- request.addHeader("Origin","http://test.archiva.org/myservlet");
- interceptor.setHttpRequest(request);
+ cfg.addValue( UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION, "true" );
+ RequestValidationInterceptor interceptor = new RequestValidationInterceptor( cfg );
+ MockHttpServletRequest request = new MockHttpServletRequest( "GET", "/api/v1/userService" );
+ request.setServerName( "test.archiva.org" );
+ request.addHeader( "Referer", "http://test3.archiva.org/myservlet2" );
+ interceptor.setHttpRequest( request );
interceptor.init();
MockContainerRequestContext ctx = new MockContainerRequestContext();
- interceptor.filter(ctx);
- assertFalse(ctx.isAborted());
+ interceptor.filter( ctx );
+ assertTrue( ctx.isAborted() );
}
@Test
- public void validateRequestWithBadOrigin() throws UserConfigurationException, IOException {
+ public void validateRequestWithOriginAndReferer() throws UserConfigurationException, IOException
+ {
TokenManager tm = new TokenManager();
MockUserConfiguration cfg = new MockUserConfiguration();
- cfg.addValue(UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION,"true");
- RequestValidationInterceptor interceptor = new RequestValidationInterceptor(cfg);
- MockHttpServletRequest request = new MockHttpServletRequest("GET","/api/v1/userService");
- request.setServerName("test.archiva.org");
- request.addHeader("Origin","http://test2.archiva.org/myservlet");
- interceptor.setHttpRequest(request);
+ cfg.addValue( UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION, "true" );
+ RequestValidationInterceptor interceptor = new RequestValidationInterceptor( cfg );
+ MockHttpServletRequest request = new MockHttpServletRequest( "GET", "/api/v1/userService" );
+ request.setServerName( "test.archiva.org" );
+ request.addHeader( "Origin", "http://test.archiva.org/myservlet" );
+ request.addHeader( "Referer", "http://test.archiva.org/myservlet2" );
+ interceptor.setHttpRequest( request );
interceptor.init();
MockContainerRequestContext ctx = new MockContainerRequestContext();
- interceptor.filter(ctx);
- assertTrue(ctx.isAborted());
+ interceptor.filter( ctx );
+ assertFalse( ctx.isAborted() );
}
@Test
- public void validateRequestWithReferer() throws UserConfigurationException, IOException {
+ public void validateRequestWithOriginAndRefererAndXForwarded() throws UserConfigurationException, IOException
+ {
TokenManager tm = new TokenManager();
MockUserConfiguration cfg = new MockUserConfiguration();
- cfg.addValue(UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION,"true");
- RequestValidationInterceptor interceptor = new RequestValidationInterceptor(cfg);
- MockHttpServletRequest request = new MockHttpServletRequest("GET","/api/v1/userService");
- request.setServerName("test.archiva.org");
- request.addHeader("Referer","http://test.archiva.org/myservlet2");
- interceptor.setHttpRequest(request);
+ cfg.addValue( UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION, "true" );
+ RequestValidationInterceptor interceptor = new RequestValidationInterceptor( cfg );
+ MockHttpServletRequest request = new MockHttpServletRequest( "GET", "/api/v1/userService" );
+ request.setServerName( "xxx.archiva.org" );
+ request.addHeader( "Origin", "http://test.archiva.org/myservlet" );
+ request.addHeader( "Referer", "http://test.archiva.org/myservlet2" );
+ request.addHeader( "X-Forwarded-Host", "test.archiva.org" );
+ interceptor.setHttpRequest( request );
interceptor.init();
MockContainerRequestContext ctx = new MockContainerRequestContext();
- interceptor.filter(ctx);
- assertFalse(ctx.isAborted());
+ interceptor.filter( ctx );
+ assertFalse( ctx.isAborted() );
}
@Test
- public void validateRequestWithBadReferer() throws UserConfigurationException, IOException {
+ public void validateRequestWithOriginAndRefererAndWrongXForwarded() throws UserConfigurationException, IOException
+ {
TokenManager tm = new TokenManager();
MockUserConfiguration cfg = new MockUserConfiguration();
- cfg.addValue(UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION,"true");
- RequestValidationInterceptor interceptor = new RequestValidationInterceptor(cfg);
- MockHttpServletRequest request = new MockHttpServletRequest("GET","/api/v1/userService");
- request.setServerName("test.archiva.org");
- request.addHeader("Referer","http://test3.archiva.org/myservlet2");
- interceptor.setHttpRequest(request);
+ cfg.addValue( UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION, "true" );
+ RequestValidationInterceptor interceptor = new RequestValidationInterceptor( cfg );
+ MockHttpServletRequest request = new MockHttpServletRequest( "GET", "/api/v1/userService" );
+ request.setServerName( "xxx.archiva.org" );
+ request.addHeader( "Origin", "http://test.archiva.org/myservlet" );
+ request.addHeader( "Referer", "http://test.archiva.org/myservlet2" );
+ request.addHeader( "X-Forwarded-Host", "test2.archiva.org" );
+ interceptor.setHttpRequest( request );
interceptor.init();
MockContainerRequestContext ctx = new MockContainerRequestContext();
- interceptor.filter(ctx);
- assertTrue(ctx.isAborted());
+ interceptor.filter( ctx );
+ assertTrue( ctx.isAborted() );
}
@Test
- public void validateRequestWithOriginAndReferer() throws UserConfigurationException, IOException {
+ public void validateRequestWithOriginAndRefererAndXForwardedMultiple() throws UserConfigurationException, IOException
+ {
TokenManager tm = new TokenManager();
MockUserConfiguration cfg = new MockUserConfiguration();
- cfg.addValue(UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION,"true");
- RequestValidationInterceptor interceptor = new RequestValidationInterceptor(cfg);
- MockHttpServletRequest request = new MockHttpServletRequest("GET","/api/v1/userService");
- request.setServerName("test.archiva.org");
- request.addHeader("Origin","http://test.archiva.org/myservlet");
- request.addHeader("Referer","http://test.archiva.org/myservlet2");
- interceptor.setHttpRequest(request);
+ cfg.addValue( UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION, "true" );
+ RequestValidationInterceptor interceptor = new RequestValidationInterceptor( cfg );
+ MockHttpServletRequest request = new MockHttpServletRequest( "GET", "/api/v1/userService" );
+ request.setServerName( "xxx.archiva.org" );
+ request.addHeader( "Origin", "http://test.archiva.org/myservlet" );
+ request.addHeader( "Referer", "http://test.archiva.org/myservlet2" );
+ request.addHeader( "X-Forwarded-Host", "my.proxy.org, test.archiva.org:80" );
+ interceptor.setHttpRequest( request );
interceptor.init();
MockContainerRequestContext ctx = new MockContainerRequestContext();
- interceptor.filter(ctx);
- assertFalse(ctx.isAborted());
+ interceptor.filter( ctx );
+ assertFalse( ctx.isAborted() );
}
@Test
- public void validateRequestWithOriginAndStaticUrl() throws UserConfigurationException, IOException {
+ public void validateRequestWithOriginAndStaticUrl() throws UserConfigurationException, IOException
+ {
MockUserConfiguration cfg = new MockUserConfiguration();
List<String> urls = new ArrayList<String>();
- urls.add("http://test.archiva.org");
- cfg.addList("rest.baseUrl",urls);
- cfg.addValue(UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION,"true");
+ urls.add( "http://test.archiva.org" );
+ cfg.addList( "rest.baseUrl", urls );
+ cfg.addValue( UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION, "true" );
TokenManager tm = new TokenManager();
- RequestValidationInterceptor interceptor = new RequestValidationInterceptor(cfg);
- MockHttpServletRequest request = new MockHttpServletRequest("GET","/api/v1/userService");
- request.setServerName("test4.archiva.org");
- request.addHeader("Origin","http://test.archiva.org/myservlet");
- interceptor.setHttpRequest(request);
+ RequestValidationInterceptor interceptor = new RequestValidationInterceptor( cfg );
+ MockHttpServletRequest request = new MockHttpServletRequest( "GET", "/api/v1/userService" );
+ request.setServerName( "test4.archiva.org" );
+ request.addHeader( "Origin", "http://test.archiva.org/myservlet" );
+ interceptor.setHttpRequest( request );
interceptor.init();
MockContainerRequestContext ctx = new MockContainerRequestContext();
- interceptor.filter(ctx);
- assertFalse(ctx.isAborted());
+ interceptor.filter( ctx );
+ assertFalse( ctx.isAborted() );
}
@Test
- public void validateRequestWithBadOriginAndStaticUrl() throws UserConfigurationException, IOException {
+ public void validateRequestWithBadOriginAndStaticUrl() throws UserConfigurationException, IOException
+ {
MockUserConfiguration cfg = new MockUserConfiguration();
List<String> urls = new ArrayList<String>();
- urls.add("http://mytest.archiva.org");
- cfg.addList("rest.baseUrl",urls);
- cfg.addValue(UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION,"true");
+ urls.add( "http://mytest.archiva.org" );
+ cfg.addList( "rest.baseUrl", urls );
+ cfg.addValue( UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION, "true" );
TokenManager tm = new TokenManager();
- RequestValidationInterceptor interceptor = new RequestValidationInterceptor(cfg);
- MockHttpServletRequest request = new MockHttpServletRequest("GET","/api/v1/userService");
- request.setServerName("mytest.archiva.org");
- request.addHeader("Origin","http://test.archiva.org/myservlet");
- interceptor.setHttpRequest(request);
+ RequestValidationInterceptor interceptor = new RequestValidationInterceptor( cfg );
+ MockHttpServletRequest request = new MockHttpServletRequest( "GET", "/api/v1/userService" );
+ request.setServerName( "mytest.archiva.org" );
+ request.addHeader( "Origin", "http://test.archiva.org/myservlet" );
+ interceptor.setHttpRequest( request );
interceptor.init();
MockContainerRequestContext ctx = new MockContainerRequestContext();
- interceptor.filter(ctx);
- assertTrue(ctx.isAborted());
+ interceptor.filter( ctx );
+ assertTrue( ctx.isAborted() );
}
@Test
- public void validateRequestWithOriginListAndStaticUrl() throws UserConfigurationException, IOException {
+ public void validateRequestWithOriginListAndStaticUrl() throws UserConfigurationException, IOException
+ {
MockUserConfiguration cfg = new MockUserConfiguration();
List<String> urls = new ArrayList<String>();
- urls.add("http://mytest.archiva.org");
- urls.add("http://mytest2.archiva.org");
- urls.add("http://test.archiva.org");
- cfg.addList("rest.baseUrl",urls);
- cfg.addValue(UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION,"true");
+ urls.add( "http://mytest.archiva.org" );
+ urls.add( "http://mytest2.archiva.org" );
+ urls.add( "http://test.archiva.org" );
+ cfg.addList( "rest.baseUrl", urls );
+ cfg.addValue( UserConfigurationKeys.REST_CSRF_DISABLE_TOKEN_VALIDATION, "true" );
TokenManager tm = new TokenManager();
- RequestValidationInterceptor interceptor = new RequestValidationInterceptor(cfg);
- MockHttpServletRequest request = new MockHttpServletRequest("GET","/api/v1/userService");
- request.setServerName("mytest.archiva.org");
- request.addHeader("Origin","http://test.archiva.org/myservlet");
- interceptor.setHttpRequest(request);
+ RequestValidationInterceptor interceptor = new RequestValidationInterceptor( cfg );
+ MockHttpServletRequest request = new MockHttpServletRequest( "GET", "/api/v1/userService" );
+ request.setServerName( "mytest.archiva.org" );
+ request.addHeader( "Origin", "http://test.archiva.org/myservlet" );
+ interceptor.setHttpRequest( request );
interceptor.init();
MockContainerRequestContext ctx = new MockContainerRequestContext();
- interceptor.filter(ctx);
- assertFalse(ctx.isAborted());
+ interceptor.filter( ctx );
+ assertFalse( ctx.isAborted() );
}
}