diff options
author | Joakim Erdfelt | 2014-06-27 19:35:31 +0000 |
---|---|---|
committer | Joakim Erdfelt | 2014-06-27 19:35:31 +0000 |
commit | 225f9cfa2045e2108653944d59f577ae7a82dea4 (patch) | |
tree | 9cc44c06a30bd32783f50a5eeb2f223e570d52ff | |
parent | d007a3f750d4b0f8860bdcaca5ac712d8bd3f4a9 (diff) | |
download | org.eclipse.jetty.project-225f9cfa2045e2108653944d59f577ae7a82dea4.tar.gz org.eclipse.jetty.project-225f9cfa2045e2108653944d59f577ae7a82dea4.tar.xz org.eclipse.jetty.project-225f9cfa2045e2108653944d59f577ae7a82dea4.zip |
Adding AliasedConstraintTest
4 files changed, 178 insertions, 2 deletions
diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml index 7690ac5808..78a7352b9a 100644 --- a/jetty-security/pom.xml +++ b/jetty-security/pom.xml @@ -77,8 +77,8 @@ <version>${project.version}</version> </dependency> <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> + <groupId>org.eclipse.jetty.toolchain</groupId> + <artifactId>jetty-test-helper</artifactId> <scope>test</scope> </dependency> </dependencies> diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java new file mode 100644 index 0000000000..13e82ddb31 --- /dev/null +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java @@ -0,0 +1,174 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.LocalConnector; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.server.handler.ResourceHandler; +import org.eclipse.jetty.server.session.SessionHandler; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.security.Constraint; +import org.eclipse.jetty.util.security.Password; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +/** + * Some requests for static data that is served by ResourceHandler, but some is secured. + * <p> + * This is mainly here to test security bypass techniques using aliased names that should be caught. + */ +@RunWith(Parameterized.class) +public class AliasedConstraintTest +{ + private static final String TEST_REALM = "TestRealm"; + private static Server server; + private static LocalConnector connector; + private static ConstraintSecurityHandler security; + + @BeforeClass + public static void startServer() throws Exception + { + server = new Server(); + connector = new LocalConnector(); + server.setConnectors(new Connector[] { connector }); + + ContextHandler context = new ContextHandler(); + SessionHandler session = new SessionHandler(); + + HashLoginService loginService = new HashLoginService(TEST_REALM); + loginService.putUser("user0",new Password("password"),new String[] {}); + loginService.putUser("user",new Password("password"),new String[] { "user" }); + loginService.putUser("user2",new Password("password"),new String[] { "user" }); + loginService.putUser("admin",new Password("password"),new String[] { "user", "administrator" }); + loginService.putUser("user3",new Password("password"),new String[] { "foo" }); + + context.setContextPath("/ctx"); + server.setHandler(context); + context.setHandler(session); + + server.addBean(loginService); + + security = new ConstraintSecurityHandler(); + session.setHandler(security); + ResourceHandler handler = new ResourceHandler(); + String resourceBase = MavenTestingUtils.getTestResourceDir("docroot").getAbsolutePath(); + handler.setResourceBase(resourceBase); + security.setHandler(handler); + + List<ConstraintMapping> constraints = new ArrayList<ConstraintMapping>(); + + Constraint constraint0 = new Constraint(); + constraint0.setAuthenticate(true); + constraint0.setName("forbid"); + ConstraintMapping mapping0 = new ConstraintMapping(); + mapping0.setPathSpec("/forbid/*"); + mapping0.setConstraint(constraint0); + constraints.add(mapping0); + + Set<String> knownRoles = new HashSet<String>(); + knownRoles.add("user"); + knownRoles.add("administrator"); + + security.setConstraintMappings(constraints,knownRoles); + server.start(); + } + + @AfterClass + public static void stopServer() throws Exception + { + server.stop(); + } + + @Parameters(name = "{0}: {1}") + public static Collection<Object[]> data() + { + List<Object[]> data = new ArrayList<Object[]>(); + + final String OPENCONTENT = "this is open content"; + + data.add(new Object[] { "/ctx/all/index.txt", HttpStatus.OK_200, OPENCONTENT }); + data.add(new Object[] { "/ctx/ALL/index.txt", HttpStatus.NOT_FOUND_404, null }); + data.add(new Object[] { "/ctx/ALL/Fred/../index.txt", HttpStatus.NOT_FOUND_404, null }); + data.add(new Object[] { "/ctx/../bar/../ctx/all/index.txt", HttpStatus.OK_200, OPENCONTENT }); + data.add(new Object[] { "/ctx/forbid/index.txt", HttpStatus.FORBIDDEN_403, null }); + data.add(new Object[] { "/ctx/all/../forbid/index.txt", HttpStatus.FORBIDDEN_403, null }); + data.add(new Object[] { "/ctx/FoRbId/index.txt", HttpStatus.NOT_FOUND_404, null }); + + return data; + } + + @Parameter(value = 0) + public String uri; + + @Parameter(value = 1) + public int expectedStatusCode; + + @Parameter(value = 2) + public String expectedContent; + + @Test + public void testAccess() throws Exception + { + StringBuilder request = new StringBuilder(); + request.append("GET ").append(uri).append(" HTTP/1.1\r\n"); + request.append("Host: localhost\r\n"); + request.append("Connection: close\r\n"); + request.append("\r\n"); + + String response = connector.getResponses(request.toString()); + + switch (expectedStatusCode) + { + case 200: + assertThat(response,startsWith("HTTP/1.1 200 OK")); + break; + case 403: + assertThat(response,startsWith("HTTP/1.1 403 Forbidden")); + break; + case 404: + assertThat(response,startsWith("HTTP/1.1 404 Not Found")); + break; + default: + fail("Write a handler for response status code: " + expectedStatusCode); + break; + } + + if (expectedContent != null) + { + assertThat(response,containsString("this is open content")); + } + } +} diff --git a/jetty-security/src/test/resources/docroot/all/index.txt b/jetty-security/src/test/resources/docroot/all/index.txt new file mode 100644 index 0000000000..290f702703 --- /dev/null +++ b/jetty-security/src/test/resources/docroot/all/index.txt @@ -0,0 +1 @@ +this is open content.
\ No newline at end of file diff --git a/jetty-security/src/test/resources/docroot/forbid/index.txt b/jetty-security/src/test/resources/docroot/forbid/index.txt new file mode 100644 index 0000000000..aed1cf32e1 --- /dev/null +++ b/jetty-security/src/test/resources/docroot/forbid/index.txt @@ -0,0 +1 @@ +this is forbidden content.
\ No newline at end of file |