CVE-2016-6797
Description
The ResourceLinkFactory implementation in Apache Tomcat 9.0.0.M1 to 9.0.0.M9, 8.5.0 to 8.5.4, 8.0.0.RC1 to 8.0.36, 7.0.0 to 7.0.70 and 6.0.0 to 6.0.45 did not limit web application access to global JNDI resources to those resources explicitly linked to the web application. Therefore, it was possible for a web application to access any global JNDI resource whether an explicit ResourceLink had been configured or not.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.tomcat:tomcatMaven | >= 9.0.0.M1, < 9.0.0.M10 | 9.0.0.M10 |
org.apache.tomcat:tomcatMaven | >= 8.5.0, < 8.5.5 | 8.5.5 |
org.apache.tomcat:tomcatMaven | >= 8.0.0, < 8.0.37 | 8.0.37 |
org.apache.tomcat:tomcatMaven | >= 7.0.0, < 7.0.72 | 7.0.72 |
Affected products
30- Apache Software Foundation/Apache Tomcatv5Range: 9.0.0.M1 to 9.0.0.M9
- cpe:2.3:a:oracle:tekelec_platform_distribution:*:*:*:*:*:*:*:*Range: >=7.4.0,<=7.7.1
- cpe:2.3:o:debian:debian_linux:8.0:*:*:*:*:*:*:*
- cpe:2.3:a:netapp:oncommand_insight:-:*:*:*:*:*:*:*
- cpe:2.3:a:netapp:oncommand_shift:-:*:*:*:*:*:*:*
- cpe:2.3:a:netapp:snap_creator_framework:-:*:*:*:*:*:*:*
- cpe:2.3:o:canonical:ubuntu_linux:16.04:*:*:*:esm:*:*:*
- cpe:2.3:a:redhat:jboss_enterprise_web_server:3.0.0:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_eus:7.6:*:*:*:*:*:*:*+ 3 more
- cpe:2.3:o:redhat:enterprise_linux_eus:7.6:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_eus:7.7:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_eus:7.4:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_eus:7.5:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_server:7.0:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_server_aus:7.4:*:*:*:*:*:*:*+ 2 more
- cpe:2.3:o:redhat:enterprise_linux_server_aus:7.4:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_server_aus:7.6:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_server_aus:7.7:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_server_tus:7.6:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:o:redhat:enterprise_linux_server_tus:7.6:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_server_tus:7.7:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_workstation:7.0:*:*:*:*:*:*:*
cpe:2.3:a:apache:tomcat:*:*:*:*:*:*:*:*+ 9 more
- cpe:2.3:a:apache:tomcat:*:*:*:*:*:*:*:*range: >=6.0.0,<=6.0.45
- cpe:2.3:a:apache:tomcat:9.0.0:milestone1:*:*:*:*:*:*
- cpe:2.3:a:apache:tomcat:9.0.0:milestone2:*:*:*:*:*:*
- cpe:2.3:a:apache:tomcat:9.0.0:milestone3:*:*:*:*:*:*
- cpe:2.3:a:apache:tomcat:9.0.0:milestone4:*:*:*:*:*:*
- cpe:2.3:a:apache:tomcat:9.0.0:milestone5:*:*:*:*:*:*
- cpe:2.3:a:apache:tomcat:9.0.0:milestone6:*:*:*:*:*:*
- cpe:2.3:a:apache:tomcat:9.0.0:milestone7:*:*:*:*:*:*
- cpe:2.3:a:apache:tomcat:9.0.0:milestone8:*:*:*:*:*:*
- cpe:2.3:a:apache:tomcat:9.0.0:milestone9:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_desktop:7.0:*:*:*:*:*:*:*
Patches
4b3406e6c3183When adding and removing ResourceLinks dynamically, ensure that the global resource is only visible via the ResourceLinkFactory when it is meant to be.
4 files changed · +218 −46
java/org/apache/catalina/core/NamingContextListener.java+58 −39 modified@@ -5,9 +5,9 @@ * 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. @@ -41,6 +41,7 @@ import org.apache.catalina.ContainerEvent; import org.apache.catalina.ContainerListener; import org.apache.catalina.Context; +import org.apache.catalina.Engine; import org.apache.catalina.Host; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; @@ -68,6 +69,7 @@ import org.apache.naming.ResourceRef; import org.apache.naming.ServiceRef; import org.apache.naming.TransactionRef; +import org.apache.naming.factory.ResourceLinkFactory; import org.apache.tomcat.util.modeler.Registry; import org.apache.tomcat.util.res.StringManager; @@ -88,8 +90,8 @@ public class NamingContextListener protected Log logger = log; - - + + /** * Name of the associated naming context. */ @@ -131,13 +133,13 @@ public class NamingContextListener */ protected javax.naming.Context envCtx = null; - + /** * Objectnames hashtable. */ protected HashMap<String, ObjectName> objectNames = new HashMap<String, ObjectName>(); - + /** * Determines if an attempt to write to a read-only context results in an @@ -192,23 +194,23 @@ public void setName(String name) { this.name = name; } - + /** * Return the comp context. */ @Deprecated public javax.naming.Context getCompContext() { return this.compCtx; } - + /** * Return the env context. */ public javax.naming.Context getEnvContext() { return this.envCtx; } - + /** * Return the associated naming context. @@ -282,7 +284,7 @@ public void lifecycleEvent(LifecycleEvent event) { ContextAccessController.setReadOnly(getName()); try { ContextBindings.bindClassLoader - (container, container, + (container, container, ((Container) container).getLoader().getClassLoader()); } catch (NamingException e) { logger.error(sm.getString("naming.bindFailed", e)); @@ -294,7 +296,7 @@ public void lifecycleEvent(LifecycleEvent event) { (namingContext); try { ContextBindings.bindClassLoader - (container, container, + (container, container, this.getClass().getClassLoader()); } catch (NamingException e) { logger.error(sm.getString("naming.bindFailed", e)); @@ -322,14 +324,14 @@ public void lifecycleEvent(LifecycleEvent event) { if (container instanceof Context) { ContextBindings.unbindClassLoader - (container, container, + (container, container, ((Container) container).getLoader().getClassLoader()); } if (container instanceof Server) { namingResources.removePropertyChangeListener(this); ContextBindings.unbindClassLoader - (container, container, + (container, container, this.getClass().getClassLoader()); } @@ -344,6 +346,11 @@ public void lifecycleEvent(LifecycleEvent event) { registry.unregisterComponent(objectName); } } + + javax.naming.Context global = getGlobalNamingContext(); + if (global != null) { + ResourceLinkFactory.deregisterGlobalResourceAccess(global); + } } finally { objectNames.clear(); @@ -391,7 +398,7 @@ public void containerEvent(ContainerEvent event) { String environmentName = (String) event.getData(); if (environmentName != null) { - ContextEnvironment env = + ContextEnvironment env = namingResources.findEnvironment(environmentName); addEnvironment(env); } @@ -400,7 +407,7 @@ public void containerEvent(ContainerEvent event) { String localEjbName = (String) event.getData(); if (localEjbName != null) { - ContextLocalEjb localEjb = + ContextLocalEjb localEjb = namingResources.findLocalEjb(localEjbName); addLocalEjb(localEjb); } @@ -409,7 +416,7 @@ public void containerEvent(ContainerEvent event) { String resourceName = (String) event.getData(); if (resourceName != null) { - ContextResource resource = + ContextResource resource = namingResources.findResource(resourceName); addResource(resource); } @@ -418,7 +425,7 @@ public void containerEvent(ContainerEvent event) { String resourceLinkName = (String) event.getData(); if (resourceLinkName != null) { - ContextResourceLink resourceLink = + ContextResourceLink resourceLink = namingResources.findResourceLink(resourceLinkName); addResourceLink(resourceLink); } @@ -427,7 +434,7 @@ public void containerEvent(ContainerEvent event) { String resourceEnvRefName = (String) event.getData(); if (resourceEnvRefName != null) { - ContextResourceEnvRef resourceEnvRef = + ContextResourceEnvRef resourceEnvRef = namingResources.findResourceEnvRef(resourceEnvRefName); addResourceEnvRef(resourceEnvRef); } @@ -436,7 +443,7 @@ public void containerEvent(ContainerEvent event) { String serviceName = (String) event.getData(); if (serviceName != null) { - ContextService service = + ContextService service = namingResources.findService(serviceName); addService(service); } @@ -599,14 +606,14 @@ private void processGlobalResourcesChange(String name, } } else if (name.equals("resourceEnvRef")) { if (oldValue != null) { - ContextResourceEnvRef resourceEnvRef = + ContextResourceEnvRef resourceEnvRef = (ContextResourceEnvRef) oldValue; if (resourceEnvRef.getName() != null) { removeResourceEnvRef(resourceEnvRef.getName()); } } if (newValue != null) { - ContextResourceEnvRef resourceEnvRef = + ContextResourceEnvRef resourceEnvRef = (ContextResourceEnvRef) newValue; if (resourceEnvRef.getName() != null) { addResourceEnvRef(resourceEnvRef); @@ -670,7 +677,7 @@ private void createNamingContext() } // Resource links - ContextResourceLink[] resourceLinks = + ContextResourceLink[] resourceLinks = namingResources.findResourceLinks(); for (i = 0; i < resourceLinks.length; i++) { addResourceLink(resourceLinks[i]); @@ -689,7 +696,7 @@ private void createNamingContext() } // Environment entries - ContextEnvironment[] contextEnvironments = + ContextEnvironment[] contextEnvironments = namingResources.findEnvironments(); for (i = 0; i < contextEnvironments.length; i++) { addEnvironment(contextEnvironments[i]); @@ -723,7 +730,7 @@ private void createNamingContext() } } } catch (NameAlreadyBoundException e) { - // Ignore because UserTransaction was obviously + // Ignore because UserTransaction was obviously // added via ResourceLink } catch (NamingException e) { logger.error(sm.getString("naming.bindFailed", e)); @@ -733,7 +740,7 @@ private void createNamingContext() // Binding the resources directory context if (container instanceof Context) { try { - compCtx.bind("Resources", + compCtx.bind("Resources", ((Container) container).getResources()); } catch (NamingException e) { logger.error(sm.getString("naming.bindFailed", e)); @@ -763,30 +770,30 @@ protected ObjectName createObjectName(ContextResource resource) if (domain == null) { domain = "Catalina"; } - + ObjectName name = null; String quotedResourceName = ObjectName.quote(resource.getName()); - if (container instanceof Server) { + if (container instanceof Server) { name = new ObjectName(domain + ":type=DataSource" + - ",class=" + resource.getType() + + ",class=" + resource.getType() + ",name=" + quotedResourceName); - } else if (container instanceof Context) { + } else if (container instanceof Context) { String contextName = ((Context)container).getName(); if (!contextName.startsWith("/")) contextName = "/" + contextName; Host host = (Host) ((Context)container).getParent(); name = new ObjectName(domain + ":type=DataSource" + - ",context=" + contextName + + ",context=" + contextName + ",host=" + host.getName() + ",class=" + resource.getType() + ",name=" + quotedResourceName); } - + return (name); } - + /** * Set the specified EJBs in the naming context. */ @@ -964,7 +971,7 @@ public void addService(ContextService service) { wsdlURL = ((Context) container). getServletContext(). getResource("/" + service.getWsdlfile()); - logger.debug(" Changing service ref wsdl file for /" + logger.debug(" Changing service ref wsdl file for /" + service.getWsdlfile()); } catch (MalformedURLException e) { logger.error(sm.getString("naming.wsdlFailed", e)); @@ -998,7 +1005,7 @@ public void addService(ContextService service) { jaxrpcURL = ((Context) container). getServletContext(). getResource("/" + service.getJaxrpcmappingfile()); - logger.debug(" Changing service ref jaxrpc file for /" + logger.debug(" Changing service ref jaxrpc file for /" + service.getJaxrpcmappingfile()); } catch (MalformedURLException e) { logger.error(sm.getString("naming.wsdlFailed", e)); @@ -1055,7 +1062,7 @@ public void addService(ContextService service) { try { if (logger.isDebugEnabled()) { - logger.debug(" Adding service ref " + logger.debug(" Adding service ref " + service.getName() + " " + ref); } createSubcontexts(envCtx, service.getName()); @@ -1087,7 +1094,7 @@ public void addResource(ContextResource resource) { } try { if (logger.isDebugEnabled()) { - logger.debug(" Adding resource ref " + logger.debug(" Adding resource ref " + resource.getName() + " " + ref); } createSubcontexts(envCtx, resource.getName()); @@ -1107,7 +1114,7 @@ public void addResource(ContextResource resource) { logger.warn(sm.getString("naming.jmxRegistrationFailed", e)); } } - + } @@ -1155,8 +1162,8 @@ public void addResourceLink(ContextResourceLink resourceLink) { ref.add(refAddr); } } - javax.naming.Context ctx = - "UserTransaction".equals(resourceLink.getName()) + javax.naming.Context ctx = + "UserTransaction".equals(resourceLink.getName()) ? compCtx : envCtx; try { if (logger.isDebugEnabled()) @@ -1167,6 +1174,17 @@ public void addResourceLink(ContextResourceLink resourceLink) { logger.error(sm.getString("naming.bindFailed", e)); } + ResourceLinkFactory.registerGlobalResourceAccess( + getGlobalNamingContext(), resourceLink.getName(), resourceLink.getGlobal()); + } + + + private javax.naming.Context getGlobalNamingContext() { + if (container instanceof Context) { + Engine e = (Engine) ((Context) container).getParent().getParent(); + return e.getService().getServer().getGlobalNamingContext(); + } + return null; } @@ -1270,6 +1288,7 @@ public void removeResourceLink(String name) { logger.error(sm.getString("naming.unbindFailed", e)); } + ResourceLinkFactory.deregisterGlobalResourceAccess(getGlobalNamingContext(), name); }
java/org/apache/naming/factory/ResourceLinkFactory.java+68 −7 modified@@ -5,18 +5,21 @@ * 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.naming.factory; +import java.util.HashMap; import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import javax.naming.Context; import javax.naming.Name; @@ -29,7 +32,7 @@ /** * <p>Object factory for resource links.</p> - * + * * @author Remy Maucherat */ public class ResourceLinkFactory implements ObjectFactory { @@ -41,12 +44,14 @@ public class ResourceLinkFactory implements ObjectFactory { */ private static Context globalContext = null; + private static Map<ClassLoader,Map<String,String>> globalResourceRegistrations = + new ConcurrentHashMap<ClassLoader,Map<String,String>>(); // --------------------------------------------------------- Public Methods /** * Set the global context (note: can only be used once). - * + * * @param newGlobalContext new global context value */ public static void setGlobalContext(Context newGlobalContext) { @@ -59,17 +64,67 @@ public static void setGlobalContext(Context newGlobalContext) { } + public static void registerGlobalResourceAccess(Context globalContext, String localName, + String globalName) { + validateGlobalContext(globalContext); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Map<String,String> registrations = globalResourceRegistrations.get(cl); + if (registrations == null) { + // Web application initialization is single threaded so this is + // safe. + registrations = new HashMap<String,String>(); + globalResourceRegistrations.put(cl, registrations); + } + registrations.put(localName, globalName); + } + + + public static void deregisterGlobalResourceAccess(Context globalContext, String localName) { + validateGlobalContext(globalContext); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Map<String,String> registrations = globalResourceRegistrations.get(cl); + if (registrations != null) { + registrations.remove(localName); + } + } + + + public static void deregisterGlobalResourceAccess(Context globalContext) { + validateGlobalContext(globalContext); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + globalResourceRegistrations.remove(cl); + } + + + private static void validateGlobalContext(Context globalContext) { + if (ResourceLinkFactory.globalContext != null && + ResourceLinkFactory.globalContext != globalContext) { + throw new SecurityException("Caller provided invalid global context"); + } + } + + + private static boolean validateGlobalResourceAccess(String globalName) { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Map<String,String> registrations = globalResourceRegistrations.get(cl); + if (registrations != null && registrations.containsValue(globalName)) { + return true; + } + return false; + } + + // -------------------------------------------------- ObjectFactory Methods /** * Create a new DataSource instance. - * + * * @param obj The reference object describing the DataSource */ @Override public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?,?> environment) throws NamingException { - + if (!(obj instanceof ResourceLinkRef)) { return null; } @@ -82,6 +137,12 @@ public Object getObjectInstance(Object obj, Name name, Context nameCtx, RefAddr refAddr = ref.get(ResourceLinkRef.GLOBALNAME); if (refAddr != null) { globalName = refAddr.getContent().toString(); + // When running under a security manager confirm that the current + // web application has really been configured to access the specified + // global resource + if (!validateGlobalResourceAccess(globalName)) { + return null; + } Object result = null; result = globalContext.lookup(globalName); // Check the expected type
test/org/apache/naming/TestNamingContext.java+87 −0 added@@ -0,0 +1,87 @@ +package org.apache.naming; + +import javax.naming.Context; +import javax.naming.NamingException; + +import org.apache.catalina.deploy.ContextEnvironment; +import org.apache.catalina.deploy.ContextResourceLink; +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.naming.factory.ResourceLinkFactory; +import org.junit.Assert; +import org.junit.Test; + +public class TestNamingContext extends TomcatBaseTest { + + private static final String COMP_ENV = "comp/env"; + private static final String GLOBAL_NAME = "global"; + private static final String LOCAL_NAME = "local"; + private static final String DATA = "Cabbage"; + + + @Test + public void testGlobalNaming() throws Exception { + Tomcat tomcat = getTomcatInstance(); + tomcat.enableNaming(); + + org.apache.catalina.Context ctx = tomcat.addContext("", null); + + tomcat.start(); + + Context webappInitial = ContextBindings.getContext(ctx); + + // Nothing added at the moment so should be null + Object obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertNull(obj); + + ContextEnvironment ce = new ContextEnvironment(); + ce.setName(GLOBAL_NAME); + ce.setValue(DATA); + ce.setType(DATA.getClass().getName()); + + tomcat.getServer().getGlobalNamingResources().addEnvironment(ce); + + // No link so still should be null + obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertNull(obj); + + // Now add a resource link to the context + ContextResourceLink crl = new ContextResourceLink(); + crl.setGlobal(GLOBAL_NAME); + crl.setName(LOCAL_NAME); + crl.setType(DATA.getClass().getName()); + ctx.getNamingResources().addResourceLink(crl); + + // Link exists so should be OK now + obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertEquals(DATA, obj); + + // Try shortcut + ResourceLinkFactory factory = new ResourceLinkFactory(); + ResourceLinkRef rlr = new ResourceLinkRef(DATA.getClass().getName(), GLOBAL_NAME, null, null); + obj = factory.getObjectInstance(rlr, null, null, null); + Assert.assertEquals(DATA, obj); + + // Remove the link + ctx.getNamingResources().removeResourceLink(LOCAL_NAME); + + // No link so should be null + obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertNull(obj); + + // Shortcut should fail too + obj = factory.getObjectInstance(rlr, null, null, null); + Assert.assertNull(obj); + } + + + private Object doLookup(Context context, String name) { + Object result = null; + try { + result = context.lookup(name); + } catch (NamingException nnfe) { + // Ignore + } + return result; + } +}
webapps/docs/changelog.xml+5 −0 modified@@ -137,6 +137,11 @@ >CVE-2016-5388</a>) by default and to provide a mechanism that can be used to mitigate any future, similar issues. (markt) </add> + <add> + When adding and removing <code>ResourceLink</code>s dynamically, ensure + that the global resource is only visible via the + <code>ResourceLinkFactory</code> when it is meant to be. (markt) + </add> </changelog> </subsection> <subsection name="Coyote">
824c7dc78105When adding and removing ResourceLinks dynamically, ensure that the global resource is only visible via the ResourceLinkFactory when it is meant to be.
4 files changed · +172 −0
java/org/apache/catalina/core/NamingContextListener.java+19 −0 modified@@ -40,6 +40,7 @@ import org.apache.catalina.ContainerEvent; import org.apache.catalina.ContainerListener; import org.apache.catalina.Context; +import org.apache.catalina.Engine; import org.apache.catalina.Host; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; @@ -58,6 +59,7 @@ import org.apache.naming.ResourceRef; import org.apache.naming.ServiceRef; import org.apache.naming.TransactionRef; +import org.apache.naming.factory.ResourceLinkFactory; import org.apache.tomcat.util.descriptor.web.ContextEjb; import org.apache.tomcat.util.descriptor.web.ContextEnvironment; import org.apache.tomcat.util.descriptor.web.ContextHandler; @@ -325,6 +327,11 @@ public void lifecycleEvent(LifecycleEvent event) { registry.unregisterComponent(objectName); } } + + javax.naming.Context global = getGlobalNamingContext(); + if (global != null) { + ResourceLinkFactory.deregisterGlobalResourceAccess(global); + } } finally { objectNames.clear(); @@ -1148,6 +1155,17 @@ public void addResourceLink(ContextResourceLink resourceLink) { logger.error(sm.getString("naming.bindFailed", e)); } + ResourceLinkFactory.registerGlobalResourceAccess( + getGlobalNamingContext(), resourceLink.getName(), resourceLink.getGlobal()); + } + + + private javax.naming.Context getGlobalNamingContext() { + if (container instanceof Context) { + Engine e = (Engine) ((Context) container).getParent().getParent(); + return e.getService().getServer().getGlobalNamingContext(); + } + return null; } @@ -1251,6 +1269,7 @@ public void removeResourceLink(String name) { logger.error(sm.getString("naming.unbindFailed", e)); } + ResourceLinkFactory.deregisterGlobalResourceAccess(getGlobalNamingContext(), name); }
java/org/apache/naming/factory/ResourceLinkFactory.java+61 −0 modified@@ -16,7 +16,10 @@ */ package org.apache.naming.factory; +import java.util.HashMap; import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import javax.naming.Context; import javax.naming.Name; @@ -41,6 +44,8 @@ public class ResourceLinkFactory implements ObjectFactory { */ private static Context globalContext = null; + private static Map<ClassLoader,Map<String,String>> globalResourceRegistrations = + new ConcurrentHashMap<>(); // --------------------------------------------------------- Public Methods @@ -59,6 +64,56 @@ public static void setGlobalContext(Context newGlobalContext) { } + public static void registerGlobalResourceAccess(Context globalContext, String localName, + String globalName) { + validateGlobalContext(globalContext); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Map<String,String> registrations = globalResourceRegistrations.get(cl); + if (registrations == null) { + // Web application initialization is single threaded so this is + // safe. + registrations = new HashMap<>(); + globalResourceRegistrations.put(cl, registrations); + } + registrations.put(localName, globalName); + } + + + public static void deregisterGlobalResourceAccess(Context globalContext, String localName) { + validateGlobalContext(globalContext); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Map<String,String> registrations = globalResourceRegistrations.get(cl); + if (registrations != null) { + registrations.remove(localName); + } + } + + + public static void deregisterGlobalResourceAccess(Context globalContext) { + validateGlobalContext(globalContext); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + globalResourceRegistrations.remove(cl); + } + + + private static void validateGlobalContext(Context globalContext) { + if (ResourceLinkFactory.globalContext != null && + ResourceLinkFactory.globalContext != globalContext) { + throw new SecurityException("Caller provided invalid global context"); + } + } + + + private static boolean validateGlobalResourceAccess(String globalName) { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Map<String,String> registrations = globalResourceRegistrations.get(cl); + if (registrations != null && registrations.containsValue(globalName)) { + return true; + } + return false; + } + + // -------------------------------------------------- ObjectFactory Methods /** @@ -82,6 +137,12 @@ public Object getObjectInstance(Object obj, Name name, Context nameCtx, RefAddr refAddr = ref.get(ResourceLinkRef.GLOBALNAME); if (refAddr != null) { globalName = refAddr.getContent().toString(); + // When running under a security manager confirm that the current + // web application has really been configured to access the specified + // global resource + if (!validateGlobalResourceAccess(globalName)) { + return null; + } Object result = null; result = globalContext.lookup(globalName); // Check the expected type
test/org/apache/naming/TestNamingContext.java+87 −0 added@@ -0,0 +1,87 @@ +package org.apache.naming; + +import javax.naming.Context; +import javax.naming.NamingException; + +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.naming.factory.ResourceLinkFactory; +import org.apache.tomcat.util.descriptor.web.ContextEnvironment; +import org.apache.tomcat.util.descriptor.web.ContextResourceLink; +import org.junit.Assert; +import org.junit.Test; + +public class TestNamingContext extends TomcatBaseTest { + + private static final String COMP_ENV = "comp/env"; + private static final String GLOBAL_NAME = "global"; + private static final String LOCAL_NAME = "local"; + private static final String DATA = "Cabbage"; + + + @Test + public void testGlobalNaming() throws Exception { + Tomcat tomcat = getTomcatInstance(); + tomcat.enableNaming(); + + org.apache.catalina.Context ctx = tomcat.addContext("", null); + + tomcat.start(); + + Context webappInitial = ContextBindings.getContext(ctx); + + // Nothing added at the moment so should be null + Object obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertNull(obj); + + ContextEnvironment ce = new ContextEnvironment(); + ce.setName(GLOBAL_NAME); + ce.setValue(DATA); + ce.setType(DATA.getClass().getName()); + + tomcat.getServer().getGlobalNamingResources().addEnvironment(ce); + + // No link so still should be null + obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertNull(obj); + + // Now add a resource link to the context + ContextResourceLink crl = new ContextResourceLink(); + crl.setGlobal(GLOBAL_NAME); + crl.setName(LOCAL_NAME); + crl.setType(DATA.getClass().getName()); + ctx.getNamingResources().addResourceLink(crl); + + // Link exists so should be OK now + obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertEquals(DATA, obj); + + // Try shortcut + ResourceLinkFactory factory = new ResourceLinkFactory(); + ResourceLinkRef rlr = new ResourceLinkRef(DATA.getClass().getName(), GLOBAL_NAME, null, null); + obj = factory.getObjectInstance(rlr, null, null, null); + Assert.assertEquals(DATA, obj); + + // Remove the link + ctx.getNamingResources().removeResourceLink(LOCAL_NAME); + + // No link so should be null + obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertNull(obj); + + // Shortcut should fail too + obj = factory.getObjectInstance(rlr, null, null, null); + Assert.assertNull(obj); + } + + + private Object doLookup(Context context, String name) { + Object result = null; + try { + result = context.lookup(name); + } catch (NamingException nnfe) { + // Ignore + } + return result; + } +}
webapps/docs/changelog.xml+5 −0 modified@@ -170,6 +170,11 @@ >CVE-2016-5388</a>) by default and to provide a mechanism that can be used to mitigate any future, similar issues. (markt) </add> + <add> + When adding and removing <code>ResourceLink</code>s dynamically, ensure + that the global resource is only visible via the + <code>ResourceLinkFactory</code> when it is meant to be. (markt) + </add> </changelog> </subsection> <subsection name="Coyote">
d6b5600afe75When adding and removing ResourceLinks dynamically, ensure that the global resource is only visible via the ResourceLinkFactory when it is meant to be.
4 files changed · +172 −0
java/org/apache/catalina/core/NamingContextListener.java+19 −0 modified@@ -40,6 +40,7 @@ import org.apache.catalina.ContainerEvent; import org.apache.catalina.ContainerListener; import org.apache.catalina.Context; +import org.apache.catalina.Engine; import org.apache.catalina.Host; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; @@ -58,6 +59,7 @@ import org.apache.naming.ResourceRef; import org.apache.naming.ServiceRef; import org.apache.naming.TransactionRef; +import org.apache.naming.factory.ResourceLinkFactory; import org.apache.tomcat.util.descriptor.web.ContextEjb; import org.apache.tomcat.util.descriptor.web.ContextEnvironment; import org.apache.tomcat.util.descriptor.web.ContextHandler; @@ -316,6 +318,11 @@ public void lifecycleEvent(LifecycleEvent event) { registry.unregisterComponent(objectName); } } + + javax.naming.Context global = getGlobalNamingContext(); + if (global != null) { + ResourceLinkFactory.deregisterGlobalResourceAccess(global); + } } finally { objectNames.clear(); @@ -1152,6 +1159,17 @@ public void addResourceLink(ContextResourceLink resourceLink) { log.error(sm.getString("naming.bindFailed", e)); } + ResourceLinkFactory.registerGlobalResourceAccess( + getGlobalNamingContext(), resourceLink.getName(), resourceLink.getGlobal()); + } + + + private javax.naming.Context getGlobalNamingContext() { + if (container instanceof Context) { + Engine e = (Engine) ((Context) container).getParent().getParent(); + return e.getService().getServer().getGlobalNamingContext(); + } + return null; } @@ -1269,6 +1287,7 @@ public void removeResourceLink(String name) { log.error(sm.getString("naming.unbindFailed", e)); } + ResourceLinkFactory.deregisterGlobalResourceAccess(getGlobalNamingContext(), name); }
java/org/apache/naming/factory/ResourceLinkFactory.java+61 −0 modified@@ -16,7 +16,10 @@ */ package org.apache.naming.factory; +import java.util.HashMap; import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import javax.naming.Context; import javax.naming.Name; @@ -41,6 +44,8 @@ public class ResourceLinkFactory implements ObjectFactory { */ private static Context globalContext = null; + private static Map<ClassLoader,Map<String,String>> globalResourceRegistrations = + new ConcurrentHashMap<>(); // --------------------------------------------------------- Public Methods @@ -59,6 +64,56 @@ public static void setGlobalContext(Context newGlobalContext) { } + public static void registerGlobalResourceAccess(Context globalContext, String localName, + String globalName) { + validateGlobalContext(globalContext); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Map<String,String> registrations = globalResourceRegistrations.get(cl); + if (registrations == null) { + // Web application initialization is single threaded so this is + // safe. + registrations = new HashMap<>(); + globalResourceRegistrations.put(cl, registrations); + } + registrations.put(localName, globalName); + } + + + public static void deregisterGlobalResourceAccess(Context globalContext, String localName) { + validateGlobalContext(globalContext); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Map<String,String> registrations = globalResourceRegistrations.get(cl); + if (registrations != null) { + registrations.remove(localName); + } + } + + + public static void deregisterGlobalResourceAccess(Context globalContext) { + validateGlobalContext(globalContext); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + globalResourceRegistrations.remove(cl); + } + + + private static void validateGlobalContext(Context globalContext) { + if (ResourceLinkFactory.globalContext != null && + ResourceLinkFactory.globalContext != globalContext) { + throw new SecurityException("Caller provided invalid global context"); + } + } + + + private static boolean validateGlobalResourceAccess(String globalName) { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Map<String,String> registrations = globalResourceRegistrations.get(cl); + if (registrations != null && registrations.containsValue(globalName)) { + return true; + } + return false; + } + + // -------------------------------------------------- ObjectFactory Methods /** @@ -82,6 +137,12 @@ public Object getObjectInstance(Object obj, Name name, Context nameCtx, RefAddr refAddr = ref.get(ResourceLinkRef.GLOBALNAME); if (refAddr != null) { globalName = refAddr.getContent().toString(); + // When running under a security manager confirm that the current + // web application has really been configured to access the specified + // global resource + if (!validateGlobalResourceAccess(globalName)) { + return null; + } Object result = null; result = globalContext.lookup(globalName); // Check the expected type
test/org/apache/naming/TestNamingContext.java+87 −0 added@@ -0,0 +1,87 @@ +package org.apache.naming; + +import javax.naming.Context; +import javax.naming.NamingException; + +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.naming.factory.ResourceLinkFactory; +import org.apache.tomcat.util.descriptor.web.ContextEnvironment; +import org.apache.tomcat.util.descriptor.web.ContextResourceLink; +import org.junit.Assert; +import org.junit.Test; + +public class TestNamingContext extends TomcatBaseTest { + + private static final String COMP_ENV = "comp/env"; + private static final String GLOBAL_NAME = "global"; + private static final String LOCAL_NAME = "local"; + private static final String DATA = "Cabbage"; + + + @Test + public void testGlobalNaming() throws Exception { + Tomcat tomcat = getTomcatInstance(); + tomcat.enableNaming(); + + org.apache.catalina.Context ctx = tomcat.addContext("", null); + + tomcat.start(); + + Context webappInitial = ContextBindings.getContext(ctx); + + // Nothing added at the moment so should be null + Object obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertNull(obj); + + ContextEnvironment ce = new ContextEnvironment(); + ce.setName(GLOBAL_NAME); + ce.setValue(DATA); + ce.setType(DATA.getClass().getName()); + + tomcat.getServer().getGlobalNamingResources().addEnvironment(ce); + + // No link so still should be null + obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertNull(obj); + + // Now add a resource link to the context + ContextResourceLink crl = new ContextResourceLink(); + crl.setGlobal(GLOBAL_NAME); + crl.setName(LOCAL_NAME); + crl.setType(DATA.getClass().getName()); + ctx.getNamingResources().addResourceLink(crl); + + // Link exists so should be OK now + obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertEquals(DATA, obj); + + // Try shortcut + ResourceLinkFactory factory = new ResourceLinkFactory(); + ResourceLinkRef rlr = new ResourceLinkRef(DATA.getClass().getName(), GLOBAL_NAME, null, null); + obj = factory.getObjectInstance(rlr, null, null, null); + Assert.assertEquals(DATA, obj); + + // Remove the link + ctx.getNamingResources().removeResourceLink(LOCAL_NAME); + + // No link so should be null + obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertNull(obj); + + // Shortcut should fail too + obj = factory.getObjectInstance(rlr, null, null, null); + Assert.assertNull(obj); + } + + + private Object doLookup(Context context, String name) { + Object result = null; + try { + result = context.lookup(name); + } catch (NamingException nnfe) { + // Ignore + } + return result; + } +}
webapps/docs/changelog.xml+5 −0 modified@@ -153,6 +153,11 @@ >CVE-2016-5388</a>) by default and to provide a mechanism that can be used to mitigate any future, similar issues. (markt) </add> + <add> + When adding and removing <code>ResourceLink</code>s dynamically, ensure + that the global resource is only visible via the + <code>ResourceLinkFactory</code> when it is meant to be. (markt) + </add> </changelog> </subsection> <subsection name="Coyote">
2859ac3eae13When adding and removing ResourceLinks dynamically, ensure
4 files changed · +172 −0
java/org/apache/catalina/core/NamingContextListener.java+19 −0 modified@@ -40,6 +40,7 @@ import org.apache.catalina.ContainerEvent; import org.apache.catalina.ContainerListener; import org.apache.catalina.Context; +import org.apache.catalina.Engine; import org.apache.catalina.Host; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; @@ -58,6 +59,7 @@ import org.apache.naming.ResourceRef; import org.apache.naming.ServiceRef; import org.apache.naming.TransactionRef; +import org.apache.naming.factory.ResourceLinkFactory; import org.apache.tomcat.util.descriptor.web.ContextEjb; import org.apache.tomcat.util.descriptor.web.ContextEnvironment; import org.apache.tomcat.util.descriptor.web.ContextHandler; @@ -316,6 +318,11 @@ public void lifecycleEvent(LifecycleEvent event) { registry.unregisterComponent(objectName); } } + + javax.naming.Context global = getGlobalNamingContext(); + if (global != null) { + ResourceLinkFactory.deregisterGlobalResourceAccess(global); + } } finally { objectNames.clear(); @@ -1152,6 +1159,17 @@ public void addResourceLink(ContextResourceLink resourceLink) { log.error(sm.getString("naming.bindFailed", e)); } + ResourceLinkFactory.registerGlobalResourceAccess( + getGlobalNamingContext(), resourceLink.getName(), resourceLink.getGlobal()); + } + + + private javax.naming.Context getGlobalNamingContext() { + if (container instanceof Context) { + Engine e = (Engine) ((Context) container).getParent().getParent(); + return e.getService().getServer().getGlobalNamingContext(); + } + return null; } @@ -1269,6 +1287,7 @@ public void removeResourceLink(String name) { log.error(sm.getString("naming.unbindFailed", e)); } + ResourceLinkFactory.deregisterGlobalResourceAccess(getGlobalNamingContext(), name); }
java/org/apache/naming/factory/ResourceLinkFactory.java+61 −0 modified@@ -16,7 +16,10 @@ */ package org.apache.naming.factory; +import java.util.HashMap; import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import javax.naming.Context; import javax.naming.Name; @@ -41,6 +44,8 @@ public class ResourceLinkFactory implements ObjectFactory { */ private static Context globalContext = null; + private static Map<ClassLoader,Map<String,String>> globalResourceRegistrations = + new ConcurrentHashMap<>(); // --------------------------------------------------------- Public Methods @@ -59,6 +64,56 @@ public static void setGlobalContext(Context newGlobalContext) { } + public static void registerGlobalResourceAccess(Context globalContext, String localName, + String globalName) { + validateGlobalContext(globalContext); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Map<String,String> registrations = globalResourceRegistrations.get(cl); + if (registrations == null) { + // Web application initialization is single threaded so this is + // safe. + registrations = new HashMap<>(); + globalResourceRegistrations.put(cl, registrations); + } + registrations.put(localName, globalName); + } + + + public static void deregisterGlobalResourceAccess(Context globalContext, String localName) { + validateGlobalContext(globalContext); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Map<String,String> registrations = globalResourceRegistrations.get(cl); + if (registrations != null) { + registrations.remove(localName); + } + } + + + public static void deregisterGlobalResourceAccess(Context globalContext) { + validateGlobalContext(globalContext); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + globalResourceRegistrations.remove(cl); + } + + + private static void validateGlobalContext(Context globalContext) { + if (ResourceLinkFactory.globalContext != null && + ResourceLinkFactory.globalContext != globalContext) { + throw new SecurityException("Caller provided invalid global context"); + } + } + + + private static boolean validateGlobalResourceAccess(String globalName) { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Map<String,String> registrations = globalResourceRegistrations.get(cl); + if (registrations != null && registrations.containsValue(globalName)) { + return true; + } + return false; + } + + // -------------------------------------------------- ObjectFactory Methods /** @@ -82,6 +137,12 @@ public Object getObjectInstance(Object obj, Name name, Context nameCtx, RefAddr refAddr = ref.get(ResourceLinkRef.GLOBALNAME); if (refAddr != null) { globalName = refAddr.getContent().toString(); + // When running under a security manager confirm that the current + // web application has really been configured to access the specified + // global resource + if (!validateGlobalResourceAccess(globalName)) { + return null; + } Object result = null; result = globalContext.lookup(globalName); // Check the expected type
test/org/apache/naming/TestNamingContext.java+87 −0 added@@ -0,0 +1,87 @@ +package org.apache.naming; + +import javax.naming.Context; +import javax.naming.NamingException; + +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.naming.factory.ResourceLinkFactory; +import org.apache.tomcat.util.descriptor.web.ContextEnvironment; +import org.apache.tomcat.util.descriptor.web.ContextResourceLink; +import org.junit.Assert; +import org.junit.Test; + +public class TestNamingContext extends TomcatBaseTest { + + private static final String COMP_ENV = "comp/env"; + private static final String GLOBAL_NAME = "global"; + private static final String LOCAL_NAME = "local"; + private static final String DATA = "Cabbage"; + + + @Test + public void testGlobalNaming() throws Exception { + Tomcat tomcat = getTomcatInstance(); + tomcat.enableNaming(); + + org.apache.catalina.Context ctx = tomcat.addContext("", null); + + tomcat.start(); + + Context webappInitial = ContextBindings.getContext(ctx); + + // Nothing added at the moment so should be null + Object obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertNull(obj); + + ContextEnvironment ce = new ContextEnvironment(); + ce.setName(GLOBAL_NAME); + ce.setValue(DATA); + ce.setType(DATA.getClass().getName()); + + tomcat.getServer().getGlobalNamingResources().addEnvironment(ce); + + // No link so still should be null + obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertNull(obj); + + // Now add a resource link to the context + ContextResourceLink crl = new ContextResourceLink(); + crl.setGlobal(GLOBAL_NAME); + crl.setName(LOCAL_NAME); + crl.setType(DATA.getClass().getName()); + ctx.getNamingResources().addResourceLink(crl); + + // Link exists so should be OK now + obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertEquals(DATA, obj); + + // Try shortcut + ResourceLinkFactory factory = new ResourceLinkFactory(); + ResourceLinkRef rlr = new ResourceLinkRef(DATA.getClass().getName(), GLOBAL_NAME, null, null); + obj = factory.getObjectInstance(rlr, null, null, null); + Assert.assertEquals(DATA, obj); + + // Remove the link + ctx.getNamingResources().removeResourceLink(LOCAL_NAME); + + // No link so should be null + obj = doLookup(webappInitial, COMP_ENV + "/" + LOCAL_NAME); + Assert.assertNull(obj); + + // Shortcut should fail too + obj = factory.getObjectInstance(rlr, null, null, null); + Assert.assertNull(obj); + } + + + private Object doLookup(Context context, String name) { + Object result = null; + try { + result = context.lookup(name); + } catch (NamingException nnfe) { + // Ignore + } + return result; + } +}
webapps/docs/changelog.xml+5 −0 modified@@ -153,6 +153,11 @@ >CVE-2016-5388</a>) by default and to provide a mechanism that can be used to mitigate any future, similar issues. (markt) </add> + <add> + When adding and removing <code>ResourceLink</code>s dynamically, ensure + that the global resource is only visible via the + <code>ResourceLinkFactory</code> when it is meant to be. (markt) + </add> </changelog> </subsection> <subsection name="Coyote">
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
50- www.oracle.com/security-alerts/cpuoct2021.htmlnvdPatchThird Party AdvisoryWEB
- rhn.redhat.com/errata/RHSA-2017-0457.htmlnvdThird Party AdvisoryWEB
- www.debian.org/security/2016/dsa-3720nvdThird Party AdvisoryWEB
- access.redhat.com/errata/RHSA-2017:0455nvdThird Party AdvisoryWEB
- access.redhat.com/errata/RHSA-2017:0456nvdThird Party AdvisoryWEB
- access.redhat.com/errata/RHSA-2017:2247nvdThird Party AdvisoryWEB
- github.com/advisories/GHSA-q6x7-f33r-3wxxghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2016-6797ghsaADVISORY
- security.netapp.com/advisory/ntap-20180605-0001/nvdThird Party Advisory
- usn.ubuntu.com/4557-1/nvdThird Party Advisory
- www.securityfocus.com/bid/93940nvdBroken Link
- www.securitytracker.com/id/1037145nvdBroken Link
- github.com/apache/tomcat/commit/2859ac3eae132383cb6f3f2042e25d7a4a281b0dghsaWEB
- github.com/apache/tomcat/commit/b3406e6c318378cbf440f902f9fdbb8b440aef4eghsaWEB
- github.com/apache/tomcat/commit/d6b5600afe75e1086dd564344e1d085966e4237dghsaWEB
- github.com/apache/tomcat80/commit/824c7dc781056442046db0ae34bcf1497f23f44cghsaWEB
- lists.apache.org/thread.html/343558d982879bf88ec20dbf707f8c11255f8e219e81d45c4f8d0551%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/343558d982879bf88ec20dbf707f8c11255f8e219e81d45c4f8d0551@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/37220405a377c0182d2afdbc36461c4783b2930fbeae3a17f1333113%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/37220405a377c0182d2afdbc36461c4783b2930fbeae3a17f1333113@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/388a323769f1dff84c9ec905455aa73fbcb20338e3c7eb131457f708%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/388a323769f1dff84c9ec905455aa73fbcb20338e3c7eb131457f708@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/39ae1f0bd5867c15755a6f959b271ade1aea04ccdc3b2e639dcd903b%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/39ae1f0bd5867c15755a6f959b271ade1aea04ccdc3b2e639dcd903b@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/3d19773b4cf0377db62d1e9328bf9160bf1819f04f988315086931d7%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/3d19773b4cf0377db62d1e9328bf9160bf1819f04f988315086931d7@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/6af47120905aa7d8fe12f42e8ff2284fb338ba141d3b77b8c7cb61b3%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/6af47120905aa7d8fe12f42e8ff2284fb338ba141d3b77b8c7cb61b3@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/845312a10aabbe2c499fca94003881d2c79fc993d85f34c1f5c77424%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/845312a10aabbe2c499fca94003881d2c79fc993d85f34c1f5c77424@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/88855876c33f2f9c532ffb75bfee570ccf0b17ffa77493745af9a17a%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/88855876c33f2f9c532ffb75bfee570ccf0b17ffa77493745af9a17a@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/9325837eb00cba5752c092047433c7f0415134d16e7f391447ff4352%40%3Cannounce.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/9325837eb00cba5752c092047433c7f0415134d16e7f391447ff4352@%3Cannounce.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/b5e3f51d28cd5d9b1809f56594f2cf63dcd6a90429e16ea9f83bbedc%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/b5e3f51d28cd5d9b1809f56594f2cf63dcd6a90429e16ea9f83bbedc@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/b84ad1258a89de5c9c853c7f2d3ad77e5b8b2930be9e132d5cef6b95%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/b84ad1258a89de5c9c853c7f2d3ad77e5b8b2930be9e132d5cef6b95@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/b8a1bf18155b552dcf9a928ba808cbadad84c236d85eab3033662cfb%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/b8a1bf18155b552dcf9a928ba808cbadad84c236d85eab3033662cfb@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r03c597a64de790ba42c167efacfa23300c3d6c9fe589ab87fe02859c%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/r03c597a64de790ba42c167efacfa23300c3d6c9fe589ab87fe02859c@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r587e50b86c1a96ee301f751d50294072d142fd6dc08a8987ae9f3a9b%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/r587e50b86c1a96ee301f751d50294072d142fd6dc08a8987ae9f3a9b@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r9136ff5b13e4f1941360b5a309efee2c114a14855578c3a2cbe5d19c%40%3Cdev.tomcat.apache.org%3EnvdWEB
- lists.apache.org/thread.html/r9136ff5b13e4f1941360b5a309efee2c114a14855578c3a2cbe5d19c@%3Cdev.tomcat.apache.org%3EghsaWEB
- security.netapp.com/advisory/ntap-20180605-0001ghsaWEB
- usn.ubuntu.com/4557-1ghsaWEB
- web.archive.org/web/20170320064509/http://www.securitytracker.com/id/1037145ghsaWEB
- web.archive.org/web/20170423095945/http://www.securityfocus.com/bid/93940ghsaWEB
News mentions
0No linked articles in our index yet.