From fe12431d2e25d3b62597b272a69ab1558fdc94cb Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Tue, 19 Apr 2011 15:27:43 +0000 Subject: [PATCH] Bug 343277 add support for an optional context white list git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@3022 7e9141cc-0065-0410-87d8-b60c137991c4 --- VERSION.txt | 3 +- .../eclipse/jetty/webapp/WebAppContext.java | 42 ++++++++++++++ .../jetty/webapp/WebAppContextTest.java | 58 +++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/VERSION.txt b/VERSION.txt index 7da01f2a26a..128c39b3f3d 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,5 +1,6 @@ -jetty-7.4.1-SNAPSHOT +jetty-7.4.1-SNAPSHOT + 343083 Set nested dispatch type. + + 343277 add support for a context white list jetty-7.4.0.v20110414 + 342504 Scanner Listener diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java index 26407ac2793..c4e2f9d5feb 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java @@ -25,6 +25,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.servlet.ServletContext; import javax.servlet.http.HttpSessionActivationListener; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingListener; @@ -129,6 +130,8 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL private boolean _parentLoaderPriority= Boolean.getBoolean("org.eclipse.jetty.server.webapp.parentLoaderPriority"); private PermissionCollection _permissions; + private String[] _contextWhiteList = null; + private File _tmpDir; private String _war; private String _extraClasspath; @@ -977,6 +980,20 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL { _permissions = permissions; } + + /** + * Set the context white list + * + * In certain circumstances you want may want to deny access of one webapp from another + * when you may not fully trust the webapp. Setting this white list will enable a + * check when a servlet called getContext(String), validating that the uriInPath + * for the given webapp has been declaratively allows access to the context. + * @param contextWhiteList + */ + public void setContextWhiteList(String[] contextWhiteList) + { + _contextWhiteList = contextWhiteList; + } /* ------------------------------------------------------------ */ /** @@ -1181,6 +1198,31 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL return resource.getURL(); } + + /* ------------------------------------------------------------ */ + @Override + public ServletContext getContext(String uripath) + { + ServletContext servletContext = super.getContext(uripath); + + if ( servletContext != null && _contextWhiteList != null ) + { + for ( String context : _contextWhiteList ) + { + if ( context.equals(uripath) ) + { + return servletContext; + } + } + + return null; + } + else + { + return servletContext; + } + } + } /* ------------------------------------------------------------ */ diff --git a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java index cff429e1166..d2cfc895c47 100644 --- a/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java +++ b/jetty-webapp/src/test/java/org/eclipse/jetty/webapp/WebAppContextTest.java @@ -12,11 +12,19 @@ // ======================================================================== package org.eclipse.jetty.webapp; +import java.io.IOException; import java.util.Arrays; +import javax.servlet.GenericServlet; import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import junit.framework.Assert; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.HandlerList; import org.junit.Test; import static org.junit.Assert.assertNotNull; @@ -96,4 +104,54 @@ public class WebAppContextTest // This fails: assertNotNull(ctx.getRealPath("/doesnotexist/")); } + + /** + * tests that the servlet context white list works + * + * @throws Exception + */ + @Test + public void testContextWhiteList() throws Exception + { + Server server = new Server(0); + HandlerList handlers = new HandlerList(); + WebAppContext contextA = new WebAppContext(".", "/A"); + + contextA.addServlet( ServletA.class, "/s"); + handlers.addHandler(contextA); + WebAppContext contextB = new WebAppContext(".", "/B"); + + contextB.addServlet(ServletB.class, "/s"); + contextB.setContextWhiteList(new String [] { "/doesnotexist", "/B/s" } ); + handlers.addHandler(contextB); + + server.setHandler(handlers); + server.start(); + + // context A should be able to get both A and B servlet contexts + Assert.assertNotNull(contextA.getServletHandler().getServletContext().getContext("/A/s")); + Assert.assertNotNull(contextA.getServletHandler().getServletContext().getContext("/B/s")); + + // context B has a contextWhiteList set and should only be able to get ones that are approved + Assert.assertNull(contextB.getServletHandler().getServletContext().getContext("/A/s")); + Assert.assertNotNull(contextB.getServletHandler().getServletContext().getContext("/B/s")); + } + + class ServletA extends GenericServlet + { + @Override + public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException + { + this.getServletContext().getContext("/A/s"); + } + } + + class ServletB extends GenericServlet + { + @Override + public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException + { + this.getServletContext().getContext("/B/s"); + } + } }