CVE-2018-1000130
Description
JNDI Injection in Jolokia proxy mode allows remote attackers to execute arbitrary Java code on the server.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
JNDI Injection in Jolokia proxy mode allows remote attackers to execute arbitrary Java code on the server.
Vulnerability
JNDI Injection vulnerability in Jolokia agent version 1.3.7 when using proxy mode. The proxy mode allows the agent to connect to remote JMX services, and the JNDI lookup is not properly sanitized, enabling an attacker to inject a malicious JNDI URL leading to remote code execution. [1][3]
Exploitation
An attacker can exploit this vulnerability by sending a crafted request to the Jolokia agent in proxy mode, specifying a malicious JNDI URL as the target JMX service. No authentication is required for the attack. The attacker controls the remote JNDI server, which returns a malicious Java object that is executed on the server. [1][3]
Impact
Successful exploitation allows a remote attacker to execute arbitrary Java code on the server with the privileges of the Jolokia agent process, leading to complete compromise of the confidentiality, integrity, and availability of the affected system. [2]
Mitigation
The vulnerability is fixed in Jolokia version 1.5.0, which introduces white listing of allowed JMX service URLs [1][3]. Red Hat Fuse 7.1 includes this fix (RHSA-2018:2669) [2]. Users should upgrade to Jolokia 1.5.0 or later, or apply the workaround by restricting access to the Jolokia endpoint and ensuring proxy mode is disabled if not needed.
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.jolokia:jolokia-coreMaven | >= 1.3.7, < 1.5.0 | 1.5.0 |
Affected products
1Patches
2fd7b93da30c6chore(war-agent): Throw exception if proxy mode is used but not enabled explicitly.
2 files changed · +78 −12
agent/core/src/main/java/org/jolokia/http/AgentServlet.java+24 −12 modified@@ -157,18 +157,30 @@ public void init(ServletConfig pServletConfig) throws ServletException { * @param pConfig configuration to update */ private void addJsr160DispatcherIfExternallyConfigured(Configuration pConfig) { - for (String param : new String[] { - System.getProperty("org.jolokia.jsr160ProxyEnabled"), - System.getenv("JOLOKIA_JSR160_PROXY_ENABLED") - }) { - if (param !=null && (param.isEmpty() || Boolean.parseBoolean(param))){ - String dispatchers = pConfig.get(ConfigKey.DISPATCHER_CLASSES); - - pConfig.updateGlobalConfiguration( - Collections.singletonMap( - ConfigKey.DISPATCHER_CLASSES.getKeyValue(), - (dispatchers != null ? dispatchers + "," : "") + "org.jolokia.jsr160.Jsr160RequestDispatcher")); - return; + String dispatchers = pConfig.get(ConfigKey.DISPATCHER_CLASSES); + String jsr160DispatcherClass = "org.jolokia.jsr160.Jsr160RequestDispatcher"; + + if (dispatchers == null || !dispatchers.contains(jsr160DispatcherClass)) { + for (String param : new String[]{ + System.getProperty("org.jolokia.jsr160ProxyEnabled"), + System.getenv("JOLOKIA_JSR160_PROXY_ENABLED") + }) { + if (param != null && (param.isEmpty() || Boolean.parseBoolean(param))) { + { + pConfig.updateGlobalConfiguration( + Collections.singletonMap( + ConfigKey.DISPATCHER_CLASSES.getKeyValue(), + (dispatchers != null ? dispatchers + "," : "") + jsr160DispatcherClass)); + } + return; + } + } + if (dispatchers == null) { + // We add a breaking dispatcher to avoid silently ignoring a JSR160 proxy request + // when it is now enabled + pConfig.updateGlobalConfiguration(Collections.singletonMap( + ConfigKey.DISPATCHER_CLASSES.getKeyValue(), + Jsr160ProxyNotEnabledByDefaultAnymoreDispatcher.class.getCanonicalName())); } } }
agent/core/src/main/java/org/jolokia/http/Jsr160ProxyNotEnabledByDefaultAnymoreDispatcher.java+54 −0 added@@ -0,0 +1,54 @@ +package org.jolokia.http; + +import java.io.IOException; + +import javax.management.AttributeNotFoundException; +import javax.management.InstanceNotFoundException; +import javax.management.MBeanException; +import javax.management.ReflectionException; + +import org.jolokia.backend.RequestDispatcher; +import org.jolokia.backend.executor.NotChangedException; +import org.jolokia.config.Configuration; +import org.jolokia.converter.Converters; +import org.jolokia.detector.ServerHandle; +import org.jolokia.handler.RequestHandlerManager; +import org.jolokia.request.JmxRequest; +import org.jolokia.restrictor.Restrictor; + +/** + * Temporary dispatcher added to avoid confusion for users which use 1.5.0 as a drop in replacement + * for a JSR-160 proxy server. Otherwise Jolokia requests for a JSR-160 target will be silently + * ignored and the MBeans of the Proxy server would be queried. + * + * @author roland + * @since 08.02.18 + */ +public class Jsr160ProxyNotEnabledByDefaultAnymoreDispatcher implements RequestDispatcher { + + + // Constructor required for the backend to be able to crete the constructor + public Jsr160ProxyNotEnabledByDefaultAnymoreDispatcher(Converters pConverters, + ServerHandle pServerInfo, + Restrictor pRestrictor, + Configuration pConfig) { + } + + @Override + public Object dispatchRequest(JmxRequest pJmxReq) throws InstanceNotFoundException, AttributeNotFoundException, ReflectionException, MBeanException, IOException, NotChangedException { + throw new IllegalArgumentException( + "No JSR-160 proxy is enabled by default since Jolokia 1.5.0. " + + "Please refer to the reference manual, section \"Proxy Mode\", " + + "for how to switch on JSR-160 proxy mode again."); + } + + @Override + public boolean canHandle(JmxRequest pJmxRequest) { + return pJmxRequest.getTargetConfig() != null; + } + + @Override + public boolean useReturnValueWithPath(JmxRequest pJmxRequest) { + return false; + } +}
1b360b8889f0fix(jsr160-proxy): Add support for white listing JMX service URLs
29 files changed · +526 −157
agent/core/src/main/java/org/jolokia/backend/BackendManager.java+26 −11 modified@@ -332,8 +332,7 @@ private void init(Configuration pConfig) { pConfig, logHandler); ServerHandle serverHandle = localDispatcher.getServerHandle(); - requestDispatchers = createRequestDispatchers(pConfig != null ? pConfig.get(DISPATCHER_CLASSES) : null, - converters,serverHandle,restrictor); + requestDispatchers = createRequestDispatchers(pConfig, converters,serverHandle,restrictor); requestDispatchers.add(localDispatcher); // Backendstore for remembering agent state @@ -361,15 +360,16 @@ private int getNullSaveIntLimit(String pValue) { // Construct configured dispatchers by reflection. Returns always // a list, an empty one if no request dispatcher should be created - private List<RequestDispatcher> createRequestDispatchers(String pClasses, + private List<RequestDispatcher> createRequestDispatchers(Configuration pConfig, Converters pConverters, ServerHandle pServerHandle, Restrictor pRestrictor) { List<RequestDispatcher> ret = new ArrayList<RequestDispatcher>(); - if (pClasses != null && pClasses.length() > 0) { - String[] names = pClasses.split("\\s*,\\s*"); + String classes = pConfig != null ? pConfig.get(DISPATCHER_CLASSES) : null; + if (classes != null && classes.length() > 0) { + String[] names = classes.split("\\s*,\\s*"); for (String name : names) { - ret.add(createDispatcher(name, pConverters, pServerHandle, pRestrictor)); + ret.add(createDispatcher(name, pConverters, pServerHandle, pRestrictor, pConfig)); } } return ret; @@ -378,19 +378,34 @@ private List<RequestDispatcher> createRequestDispatchers(String pClasses, // Create a single dispatcher private RequestDispatcher createDispatcher(String pDispatcherClass, Converters pConverters, - ServerHandle pServerHandle, Restrictor pRestrictor) { + ServerHandle pServerHandle, + Restrictor pRestrictor, + Configuration pConfig) { try { Class clazz = ClassUtil.classForName(pDispatcherClass, getClass().getClassLoader()); if (clazz == null) { throw new IllegalArgumentException("Couldn't lookup dispatcher " + pDispatcherClass); } - Constructor constructor = clazz.getConstructor(Converters.class, - ServerHandle.class, - Restrictor.class); - return (RequestDispatcher) + try { + Constructor constructor = clazz.getConstructor(Converters.class, + ServerHandle.class, + Restrictor.class, + Configuration.class); + return (RequestDispatcher) + constructor.newInstance(pConverters, + pServerHandle, + pRestrictor, + pConfig); + } catch (NoSuchMethodException exp) { + // Try without configuration as fourth parameter + Constructor constructor = clazz.getConstructor(Converters.class, + ServerHandle.class, + Restrictor.class); + return (RequestDispatcher) constructor.newInstance(pConverters, pServerHandle, pRestrictor); + } } catch (NoSuchMethodException e) { throw new IllegalArgumentException("Class " + pDispatcherClass + " has invalid constructor: " + e,e); } catch (IllegalAccessException e) {
agent/core/src/main/java/org/jolokia/config/ConfigKey.java+6 −0 modified@@ -51,6 +51,12 @@ public enum ConfigKey { */ DISPATCHER_CLASSES("dispatcherClasses", true, false), + /** + * Path to a white list of patterns which are matched against possible + * JMX service URL for incoming requests + */ + JSR160_PROXY_ALLOWED_TARGETS("jsr160ProxyAllowedTargets", true, false), + /** * Log handler class to use, which must have an empty constructor. * If not set, then a default logging mechanism is used.
agent/core/src/main/java/org/jolokia/detector/GeronimoDetector.java+2 −2 modified@@ -19,8 +19,8 @@ import org.jolokia.backend.executor.MBeanServerExecutor; /** - * Detector for the Geronimo JEE Server - * + * Detector for the Geronimo Java EE Server + * * @author roland * @since 05.12.10 */
agent/core/src/main/java/org/jolokia/http/AgentServlet.java+31 −4 modified@@ -137,14 +137,42 @@ public void init(ServletConfig pServletConfig) throws ServletException { logHandler.info("Using custom access restriction provided by " + restrictor); } configMimeType = config.get(ConfigKey.MIME_TYPE); - backendManager = new BackendManager(config,logHandler, restrictor); - requestHandler = new HttpRequestHandler(config,backendManager,logHandler); + + addJsr160DispatcherIfExternallyConfigured(config); + backendManager = new BackendManager(config, logHandler, restrictor); + + requestHandler = new HttpRequestHandler(config, backendManager, logHandler); allowDnsReverseLookup = config.getAsBoolean(ConfigKey.ALLOW_DNS_REVERSE_LOOKUP); streamingEnabled = config.getAsBoolean(ConfigKey.STREAMING); initDiscoveryMulticast(config); } + + /** + * Add the JsrRequestDispatcher if configured via a system property or env variable. + * The JSR160 dispatcher is disabled by default, but this allows to enable it again + * without reconfiguring the servlet + * + * @param pConfig configuration to update + */ + private void addJsr160DispatcherIfExternallyConfigured(Configuration pConfig) { + for (String param : new String[] { + System.getProperty("org.jolokia.jsr160ProxyEnabled"), + System.getenv("JOLOKIA_JSR160_PROXY_ENABLED") + }) { + if (param !=null && (param.isEmpty() || Boolean.parseBoolean(param))){ + String dispatchers = pConfig.get(ConfigKey.DISPATCHER_CLASSES); + + pConfig.updateGlobalConfiguration( + Collections.singletonMap( + ConfigKey.DISPATCHER_CLASSES.getKeyValue(), + (dispatchers != null ? dispatchers + "," : "") + "org.jolokia.jsr160.Jsr160RequestDispatcher")); + return; + } + } + } + /** * Hook for creating an own restrictor * @@ -474,8 +502,7 @@ private void sendResponse(HttpServletResponse pResp, HttpServletRequest pReq, JS setContentType(pResp, MimeTypeUtil.getResponseMimeType( pReq.getParameter(ConfigKey.MIME_TYPE.getKeyValue()), - configMimeType, callback - )); + configMimeType, callback)); pResp.setStatus(HttpServletResponse.SC_OK); setNoCacheHeaders(pResp); if (pJson == null) {
agent/jsr160/src/main/java/org/jolokia/jsr160/Jsr160RequestDispatcher.java+108 −5 modified@@ -16,9 +16,18 @@ * limitations under the License. */ +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; import javax.management.*; import javax.management.remote.*; @@ -27,6 +36,8 @@ import org.jolokia.backend.RequestDispatcher; import org.jolokia.backend.executor.MBeanServerExecutor; import org.jolokia.backend.executor.NotChangedException; +import org.jolokia.config.ConfigKey; +import org.jolokia.config.Configuration; import org.jolokia.converter.Converters; import org.jolokia.detector.ServerHandle; import org.jolokia.handler.JsonRequestHandler; @@ -43,19 +54,30 @@ */ public class Jsr160RequestDispatcher implements RequestDispatcher { + + public static final String ALLOWED_TARGETS_SYSPROP = "org.jolokia.jsr160ProxyAllowedTargets"; + public static final String ALLOWED_TARGETS_ENV = "JOLOKIA_JSR160_PROXY_ALLOWED_TARGETS"; + + // White and blacklist for patterns to match the JMX Service URL against + private final Set<String> whiteList; + private final Set<String> blackList; + private RequestHandlerManager requestHandlerManager; /** * Constructor * * @param pConverters object/string converters - * @param serverInfo server info for dealing with version information - * @param restrictor restrictor for restricting access to certain MBeans + * @param pServerInfo server info for dealing with version information + * @param pRestrictor restrictor for restricting access to certain MBeans */ public Jsr160RequestDispatcher(Converters pConverters, - ServerHandle serverInfo, - Restrictor restrictor) { - requestHandlerManager = new RequestHandlerManager(pConverters, serverInfo, restrictor); + ServerHandle pServerInfo, + Restrictor pRestrictor, + Configuration pConfig) { + requestHandlerManager = new RequestHandlerManager(pConverters, pServerInfo, pRestrictor); + whiteList = extractWhiteList(pConfig); + blackList = extractBlackList(pConfig); } /** @@ -98,6 +120,10 @@ private JMXConnector createConnector(JmxRequest pJmxReq) throws IOException { throw new IllegalArgumentException("No proxy configuration in request " + pJmxReq); } String urlS = targetConfig.getUrl(); + if (!acceptTargetUrl(urlS)) { + throw new SecurityException(String.format("Target URL %s is not allowed by configuration", urlS)); + } + JMXServiceURL url = new JMXServiceURL(urlS); Map<String,Object> env = prepareEnv(targetConfig.getEnv()); @@ -145,4 +171,81 @@ public boolean useReturnValueWithPath(JmxRequest pJmxRequest) { JsonRequestHandler handler = requestHandlerManager.getRequestHandler(pJmxRequest.getType()); return handler.useReturnValueWithPath(); } + + // Whether a given JMX Service URL is acceptable + private boolean acceptTargetUrl(String urlS) { + // Whitelist has precedence. Only patterns on the white list are allowed + if (whiteList != null) { + return checkPattern(whiteList, urlS, true); + } + + // Then blacklist: Everything on this list is forbidden + if (blackList != null) { + return checkPattern(blackList, urlS, false); + } + + // If no list is configured, then everything is allowed + return true; + } + + private boolean checkPattern(Set<String> patterns, String urlS, boolean isPositive) { + for (String pattern : patterns) { + if (Pattern.compile(pattern).matcher(urlS).matches()) { + return isPositive; + } + } + return !isPositive; + } + + private Set<String> extractWhiteList(Configuration pConfig) { + return extractFrom(pConfig != null ? pConfig.get(ConfigKey.JSR160_PROXY_ALLOWED_TARGETS) : null, + System.getProperty(ALLOWED_TARGETS_SYSPROP), + System.getenv(ALLOWED_TARGETS_ENV)); + } + + private Set<String> extractFrom(String ... paths) { + Set<String> ret = new HashSet<String>(); + for (String path : paths) { + if (path != null) { + ret.addAll(readPatterns(path)); + } + } + return ret.size() > 0 ? ret : null; + } + + private List<? extends String> readPatterns(String pPath) { + BufferedReader reader = null; + List<String> ret = new ArrayList<String>(); + Pattern commentPattern = Pattern.compile("^\\s*#.*$"); + try { + reader = new BufferedReader(new FileReader(pPath)); + String line = reader.readLine(); + while (line != null) { + if (!commentPattern.matcher(line).matches()) { + ret.add(line); + } + line = reader.readLine(); + } + return ret; + } catch (FileNotFoundException e) { + throw new IllegalArgumentException(String.format("No such pattern file %s", pPath )); + } catch (IOException e) { + throw new IllegalStateException(String.format("Error while reading pattern file %s: %s", pPath, e.getMessage() )); + } finally { + try { + if (reader != null) { + reader.close(); + } + } catch (IOException e) { + // we tried + } + } + } + + private Set<String> extractBlackList(Configuration pConfig) { + // Bad, bad .... + return Collections.singleton("service:jmx:rmi:///jndi/ldap:.*"); + } + + }
agent/jsr160/src/test/java/org/jolokia/jsr160/Jsr160RequestDispatcherTest.java+94 −5 modified@@ -21,8 +21,11 @@ import java.util.Map; import javax.management.*; +import javax.naming.CommunicationException; +import javax.naming.NamingException; import org.jolokia.backend.executor.NotChangedException; +import org.jolokia.config.ConfigKey; import org.jolokia.config.Configuration; import org.jolokia.config.ProcessingParameters; import org.jolokia.converter.Converters; @@ -46,7 +49,7 @@ public class Jsr160RequestDispatcherTest { @BeforeTest private void setup() { - dispatcher = createDispatcherPointingToLocalMBeanServer(); + dispatcher = createDispatcherPointingToLocalMBeanServer(null); procParams = new Configuration().getProcessingParameters(new HashMap<String, String>()); } @@ -98,13 +101,98 @@ public void simpleDispatchWithUser() throws InstanceNotFoundException, IOExcepti } } + @Test + public void simpleWhiteListWithConfig() throws Exception { + + String whiteListPath = getFilePathFor("/org/jolokia/jsr160/pattern-whitelist.txt"); + Configuration config = new Configuration( + ConfigKey.JSR160_PROXY_ALLOWED_TARGETS, whiteListPath); + runWhiteListTest(config); + } + + @Test + public void simpleWhiteListWithSysProp() throws Exception { + String whiteListPath = getFilePathFor("/org/jolokia/jsr160/pattern-whitelist.txt"); + try { + System.setProperty(Jsr160RequestDispatcher.ALLOWED_TARGETS_SYSPROP, whiteListPath); + runWhiteListTest(null); + } finally { + System.getProperties().remove(Jsr160RequestDispatcher.ALLOWED_TARGETS_SYSPROP); + } + } + + @Test + public void whiteListWithIllegalPath() throws Exception { + String invalidPath = "/very/unlikely/path"; + Configuration config = new Configuration( + ConfigKey.JSR160_PROXY_ALLOWED_TARGETS, invalidPath); + try { + createDispatcherPointingToLocalMBeanServer(config); + fail(); + } catch (IllegalArgumentException exp) { + assertTrue(exp.getMessage().contains(invalidPath)); + } + } + + @Test + public void defaultBlackList() throws Exception { + String blackListedUrl = "service:jmx:rmi:///jndi/ldap://localhost:9092/jmxrmi"; + JmxReadRequest req = preparePostReadRequestWithServiceUrl(blackListedUrl, null); + try { + dispatcher.dispatchRequest(req); + fail("Exception should have been thrown for " + blackListedUrl); + } catch (SecurityException exp) { + assertTrue(exp.getMessage().contains(blackListedUrl)); + } + } + + private void runWhiteListTest(Configuration config) throws InstanceNotFoundException, AttributeNotFoundException, ReflectionException, MBeanException, IOException, NotChangedException { + Jsr160RequestDispatcher dispatcher = createDispatcherPointingToLocalMBeanServer(config); + + Object[] testData = new Object[] { + "service:jmx:test:///jndi/rmi://devil.com:6666/jmxrmi", false, + "service:jmx:test:///jndi/rmi://localhost:9999/jmxrmi", true, + "service:jmx:test:///jndi/rmi://jolokia.org:8888/jmxrmi", true, + "service:jmx:rmi:///jndi/ldap://localhost:9999/jmxrmi", true, + "service:jmx:test:///jndi/ad://localhost:9999/jmxrmi", false, + "service:jmx:rmi:///jndi/ldap://localhost:9092/jmxrmi", true + }; + + for (int i = 0; i < testData.length; i +=2) { + JmxReadRequest req = preparePostReadRequestWithServiceUrl((String) testData[i], null); + try { + dispatcher.dispatchRequest(req); + if (!(Boolean) testData[i+1]) { + fail("Exception should have been thrown for " + testData[i]); + } + } catch (SecurityException exp) { + if ((Boolean) testData[i+1]) { + fail("Security exception for pattern " + testData[i]); + } + } catch (IOException exp) { + // That's fine if allowed to pass + assertTrue(exp.getCause() instanceof CommunicationException); + if (!(Boolean) testData[i+1]) { + fail("Should not come that fat " + testData[i]); + } + } + } + } + + private String getFilePathFor(String resource) { + return this.getClass().getResource(resource).getFile(); + } // ========================================================================================================= private JmxReadRequest preparePostReadRequest(String pUser, String... pAttribute) { + return preparePostReadRequestWithServiceUrl("service:jmx:test:///jndi/rmi://localhost:9999/jmxrmi", pUser, pAttribute); + } + + private JmxReadRequest preparePostReadRequestWithServiceUrl(String pJmxServiceUrl, String pUser, String... pAttribute) { JSONObject params = new JSONObject(); JSONObject target = new JSONObject(); - target.put("url","service:jmx:test:///jndi/rmi://localhost:9999/jmxrmi"); + target.put("url",pJmxServiceUrl); if (pUser != null) { target.put("user","roland"); target.put("password","s!cr!et"); @@ -119,10 +207,10 @@ private JmxReadRequest preparePostReadRequest(String pUser, String... pAttribute return (JmxReadRequest) JmxRequestFactory.createPostRequest(params, procParams); } - private Jsr160RequestDispatcher createDispatcherPointingToLocalMBeanServer() { + private Jsr160RequestDispatcher createDispatcherPointingToLocalMBeanServer(Configuration pConfig) { Converters converters = new Converters(); ServerHandle handle = new ServerHandle(null,null,null, null); - return new Jsr160RequestDispatcher(converters,handle,new AllowAllRestrictor()) { + return new Jsr160RequestDispatcher(converters,handle,new AllowAllRestrictor(), pConfig) { @Override protected Map<String, Object> prepareEnv(Map<String, String> pTargetConfig) { Map ret = super.prepareEnv(pTargetConfig); @@ -138,7 +226,8 @@ protected Map<String, Object> prepareEnv(Map<String, String> pTargetConfig) { private Jsr160RequestDispatcher getOriginalDispatcher() { return new Jsr160RequestDispatcher(new Converters(), new ServerHandle(null,null,null, null), - new AllowAllRestrictor()); + new AllowAllRestrictor(), + null); } }
agent/jsr160/src/test/resources/org/jolokia/jsr160/pattern-whitelist.txt+2 −0 added@@ -0,0 +1,2 @@ +service:jmx:test:///jndi/rmi:.*//(localhost|jolokia.org):.*/jmxrmi +service:jmx:rmi:///jndi/ldap:.*//localhost:.*/jmxrmi \ No newline at end of file
agent/war/src/main/webapp/WEB-INF/web.xml+0 −8 modified@@ -24,14 +24,6 @@ <servlet> <servlet-name>jolokia-agent</servlet-name> <servlet-class>org.jolokia.http.AgentServlet</servlet-class> - <init-param> - <description> - Class names (comma separated) of RequestDispatcher used in addition - to the LocalRequestDispatcher - </description> - <param-name>dispatcherClasses</param-name> - <param-value>org.jolokia.jsr160.Jsr160RequestDispatcher</param-value> - </init-param> <init-param> <description> Debugging state after startup. Can be changed via
agent/war/src/site/apt/index.apt+1 −1 modified@@ -1,3 +1,3 @@ Jolokia WAR agent - JEE Jolokia agent packaged as Web-Archive (war). \ No newline at end of file + Java EE Jolokia agent packaged as Web-Archive (war). \ No newline at end of file
client/javascript/test-app/src/main/webapp/WEB-INF/web.xml+0 −8 modified@@ -24,14 +24,6 @@ <servlet> <servlet-name>jolokia-agent</servlet-name> <servlet-class>org.jolokia.http.AgentServlet</servlet-class> - <init-param> - <description> - Classnames (comma separated) of RequestDispatcher used in addition - to the LocalRequestDispatcher - </description> - <param-name>dispatcherClasses</param-name> - <param-value>org.jolokia.jsr160.Jsr160RequestDispatcher</param-value> - </init-param> <init-param> <description> Debugging state after startup. Can be changed via
README.md+1 −1 modified@@ -13,7 +13,7 @@ REST-stylish way. Multiple agents are provided for different environments: -* **WAR Agent** for deployment as web application in a JEE Server. +* **WAR Agent** for deployment as web application in a Java EE Server. * **OSGi Agent** for deployment in an [OSGi][2] container. This agent is packaged as a bundle and comes in two flavors (minimal, all-in-one).
src/assembly/README+6 −6 modified@@ -13,16 +13,16 @@ Agents Multiple agents are provided for different environments: - * WAR Agent for deployment as web application in a JEE Server - + * WAR Agent for deployment as web application in a Java EE Server + * OSGi Agent for deployment in an OSGi container. This agent is packaged as a bundle and comes in two flavors (minimal, all-in-one) - + * Mule Agent for usage within a Mule ESB - + * JVM JDK6 Agent which can be used with any Oracle/Sun JVM, - Version 6 + Version 6 All agents can be found in the agents/ subdirectory. For installation instructions, please refer to http://www.jolokia.org/agent.html @@ -48,7 +48,7 @@ Reference documentation Jolokia's reference documentation is contained below reference/ and comes in two flavors: As a set of HTML documents (reference/html/index.html) and a rendered PDF document -(reference/jolokia.pdf) +(reference/jolokia.pdf) Resources ---------
src/docbkx/agents/osgi.xml+8 −3 modified@@ -138,7 +138,7 @@ <literal>org.jolokia</literal> and are listed in <xref linkend="table-agents-osgi-properties"/>. They are mostly the same as the <literal>init-param</literal> options for - a Jolokia servlet when used in a JEE WAR artifact. + a Jolokia servlet when used in a Java EE WAR artifact. </para> <table id="table-agents-osgi-properties"> <title>Jolokia Bundle Properties</title> @@ -195,6 +195,11 @@ of <classname>org.jolokia.jsr160.Jsr160RequestDispatcher</classname> allows the agent to play the role of a JSR-160 proxy. + By default no extract dispatchers are enabled. + You can use the system property <literal>org.jolokia.jsr160ProxyEnabled</literal> or the + environment variable <literal>JOLOKIA_JSR160_PROXY_ENABLED</literal> to enable the the JSR-160 proxy. + In that case you should be sure that you enable authentication for the web application to protect access + to the proxy. </td> </tr> <tr> @@ -342,7 +347,7 @@ Is set to <literal>true</literal> then this servlet will listen for multicast request (multicastgroup 239.192.48.84, port 24884). By default this option is disabled in order to - avoid conflicts with an JEE standards (though this should't + avoid conflicts with an Java EE standards (though this should't harm anyways). This option can also be switched on with an environment variable <literal>JOLOKIA_DISCOVERY</literal> or the system @@ -409,7 +414,7 @@ <para> You have a couple of choices when running jolokia on Glassfish v3 and up, since Glassfish is a both a fully - fledged JEE container and an OSGi container. If you + fledged Java EE container and an OSGi container. If you choose to run the <xref linkend="agents-war"/> then it is completely straight forward just deploy the war in the normal way. If you choose to deploy
src/docbkx/agents/war.xml+21 −7 modified@@ -16,13 +16,13 @@ --> <section id="agents-war"> - <title>JEE Agent (WAR)</title> + <title>Java EE Agent (WAR)</title> <section id="war-agent-installation"> <title>Installation and Configuration</title> <para> The WAR agent is the most popular variant, and can be deployed - in a servlet container just like any other JEE web application.<sidebar> + in a servlet container just like any other Java EE web application.<sidebar> <title>Tomcat example</title> A simple example for deploying the agent on Tomcat can be found in the Jolokia <ulink @@ -70,7 +70,7 @@ </variablelist> <para> The configuration options <literal>discoveryEnabled</literal> and - <literal>discoveryAgentUrl</literal> can be provied via environent + <literal>discoveryAgentUrl</literal> can be provided via environment variables or system properties, too. See the below for details. </para> <table id="agent-war-init-params"> @@ -89,13 +89,27 @@ to the <constant>LocalRequestDispatcher</constant>. Dispatchers are a technique used by the JSR-160 proxy to dispatch (or - 'route') a request to a different destination. + 'route') a request to a different destination. By default no extract dispatchers are enabled (changed in 1.5.0) + You can use the system property <literal>org.jolokia.jsr160ProxyEnabled</literal> or the + environment variable <literal>JOLOKIA_JSR160_PROXY_ENABLED</literal> to enable the the JSR-160 proxy. + In that case you should be sure that you enable authentication for the web application to protect access + to the proxy. </td> <td> <literal>org.jolokia.jsr160.Jsr160RequestDispatcher</literal> (this is the dispatcher for the JSR-160 proxy) </td> </tr> + <tr> + <td><constant>jsr160ProxyAllowedTargets</constant></td> + <td> + Path to a white list of patterns which are matched against possible + JMX service URL for incoming requests + </td> + <td> + <literal>/opt/jolokia/jsr160-proxy-allowed-patterns.txt</literal> + </td> + </tr> <tr> <td><constant>policyLocation</constant></td> <td> @@ -326,7 +340,7 @@ Is set to <literal>true</literal> then this servlet will listen for multicast request (multicastgroup 239.192.48.84, port 24884). By default this option is disabled in order to - avoid conflicts with an JEE standards (though this should't + avoid conflicts with an Java EE standards (though this should't harm anyways). This option can also be switched on with an environment variable <literal>JOLOKIA_DISCOVERY</literal> or the system @@ -414,7 +428,7 @@ <section id="agent-war-security"> <title>Security Setup</title> <para> - In order use JEE security within the war, some extra + In order use Java EE security within the war, some extra configuration steps are required within <filename>web.xml</filename>.<sidebar> <title>Using jmx4perl's <literal>jolokia</literal> tool</title> @@ -508,7 +522,7 @@ distinguish multiple Jolokia MBeans by adding an extra propery to those MBeans' names. This also needs to be done if multiple webapps containing Jolokia agents are deployed on - the same JEE server. + the same Java EE server. </para> </section> </section>
src/docbkx/agents.xml+9 −9 modified@@ -17,7 +17,7 @@ <chapter id="agents" xmlns:xi="http://www.w3.org/2001/XInclude"> <title>Agents</title> - + <para> Jolokia is an agent based approach to JMX, which requires that clients install an extra piece of software, the so-called @@ -34,17 +34,17 @@ lightweight servlet container exists. Tomcat or Jetty are both a perfect choice for a Jolokia proxy server. </para> - </footnote>. + </footnote>. </para> <variablelist> <varlistentry> <term><emphasis role="bold">Webarchive (War) agent</emphasis></term> <listitem> - This agent is packaged as a JEE Webarchive (War). It is the + This agent is packaged as a Java EE Webarchive (War). It is the standard installation artifact for Java webapplications and probably one of the best known deployment formats. Jolokia ships with a war-agent which can be deployed like any other web - application. This agent has been tested on many JEE + application. This agent has been tested on many Java EE servers, from well-known market leaders to rarer species. </listitem> </varlistentry> @@ -90,28 +90,28 @@ <listitem> Starting with Java 6 the JDK provided by Oracle contains a lightweight HTTP-Server which is used e.g. for the reference - WebService stack implementation included in Java 6. Using + WebService stack implementation included in Java 6. Using the Java-agent API (normally used by profilers and other development tools requiring the instrumentation during the class loading phase), the JVM 6 Jolokia agent is the most generic one. It is able to instrument <emphasis>any</emphasis> Java application running on a Oracle JDK 6<footnote> <para> - You could even instrument a JEE application server this way, + You could even instrument a Java EE application server this way, however this is not recommended. </para> </footnote>. This Jolokia agent variant is fully featured, however tends to - be a bit slow since the + be a bit slow since the provided HTTP-Server is not optimized for performance. However it is useful for servers like Hadoop or Teracotta, which do not provide convenient hooks for an HTTP-exporting agent on their own. </listitem> </varlistentry> </variablelist> - - + + <xi:include href='agents/war.xml'/> <xi:include href='agents/osgi.xml'/> <xi:include href='agents/mule.xml'/>
src/docbkx/architecture.xml+8 −8 modified@@ -63,7 +63,7 @@ are available for exporting its protocol via HTTP. The most prominent being to put the agent into a servlet container. This can be a lightweight one like Tomcat or Jetty or a full-blown - JEE Server. Since it acts like a usual web application the + Java EE Server. Since it acts like a usual web application the deployment of the agent is well understood and should pose no entry barrier for any developer who has ever dealt with Java web applications. @@ -95,7 +95,7 @@ about this. </para> </section> - + <section id="proxy-mode"> <title>Proxy Mode</title> <para> @@ -115,15 +115,15 @@ <literal>jolokia.war</literal>, which by default supports both the <emphasis>agent mode</emphasis> and the <emphasis>proxy mode</emphasis>. A lightweight container like Tomcat or Jetty is - a perfect choice for this kind of setup. + a perfect choice for this kind of setup. </para> <para> Figure <xref linkend="fig-architecture-proxy"/> describes a typical setup for the proxy mode. A client sends a usual Jolokia request containing an extra section for specifying the target which should be queried. All routing information is contained in the request itself so that the proxy can act universally without the need of a specific - configuration. + configuration. </para> <figure id="fig-architecture-proxy"> @@ -138,14 +138,14 @@ <para> Having said all that, the proxy mode has some limitations which are - listed in <xref linkend="proxy"/>. - </para> + listed in <xref linkend="proxy"/>. + </para> <para> To summarize, the proxy mode should be used only when required. The agent servlet on its own is more powerful than the proxy mode since it eliminates an additional layer adding to the overall complexity and performance. Also, some features like merging of MBeanServers are not available in the proxy mode. - </para> - </section> + </para> + </section> </chapter> \ No newline at end of file
src/docbkx/introduction.xml+2 −2 modified@@ -20,7 +20,7 @@ <para> JMX (Java Management Extensions) is <emphasis>the</emphasis> standard management solution in the Java world. Since JDK 1.5 it - is available in every Java Virtual Machine and especially JEE + is available in every Java Virtual Machine and especially Java EE application servers use JMX for their management business. </para> <para> @@ -45,7 +45,7 @@ remotely. Unfortunately, the underlying transport protocol (RMI) and programing model is very Java centric and is not usable outside the Java world. - </para> + </para> <para> This is where Jolokia steps in. It is an agent based approach, living side by side with JSR-160, but uses the much more open HTTP
src/docbkx/proxy.xml+78 −6 modified@@ -17,7 +17,7 @@ <chapter id="proxy"> <title>Proxy Mode </title> - + <para> Using Jolokia in proxy mode enables for agentless operation on the target server. A dedicated agent deployment proxies by @@ -30,18 +30,85 @@ <para> Agents of all types support the proxy mode. However, since one has usually the free choice of platform for a dedicated Jolokia - proxy, an enviroment optimized for HTTP communication should be - used. These are either servlet container or JEE server hosting + proxy, an environment optimized for HTTP communication should be + used. These are either servlet container or Java EE server hosting the WAR agent or an OSGi runtime with an OSGi HttpService (which - in turn is typically based on an embedded serlvet container like + in turn is typically based on an embedded servlet container like Tomcat or Jetty). The two other agents, the Mule and JVM agents - are not that well suited for this job. + are not that well suited for this job and do not contain the proxy. + </para> + <para> + Please note that the proxy mode is <emphasis>not</emphasis> switched on by default + since version 1.5.0. You have to explicitly switch it on for the WAR or OSGI agent: + </para> + <itemizedlist> + <listitem> + Repackaging the <literal>jolokia.war</literal> and adapt <literal>web.xml</literal> to + include the init option <literal>dispatcherClasses</literal> with a value <literal>org.jolokia.jsr160.Jsr160RequestDispatcher</literal>. + </listitem> + <listitem> + Set the system property <literal>org.jolokia.jsr160ProxyEnabled</literal> + </listitem> + <listitem> + Set the environment variable <literal>JOLOKIA_JSR160_PROXY_ENABLED</literal> + </listitem> + </itemizedlist> + <para> + The first option requires you to repackage the <literal>jolokia.war</literal> and add the following section to + the <literal>web.xml</literal> descriptor: + </para> + <programlisting language="xml"><![CDATA[ +<init-param> + <description> + Classnames (comma separated) of RequestDispatcher used in addition + to the LocalRequestDispatcher + </description> + <param-name>dispatcherClasses</param-name> + <param-value>org.jolokia.jsr160.Jsr160RequestDispatcher</param-value> +</init-param> +]]></programlisting> + <para> + The two other options by using a Java system property or an environment variable do not require a repackaging, so + these are the recommended way. + </para> + <para> + Additionally you can configured a white list with patterns for all allowed JMX service URL in a Jolokia Request. + This white list is a plain text file which contains <ulink + url="https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html">Patterns</ulink> line by line. Lines starting with <literal>#</literal> are ignored. + This file can be configured in various ways: + </para> + <itemizedlist> + <listitem> + Repackaging the <literal>jolokia.war</literal> and adapt <literal>web.xml</literal> to + include the init option <literal>jsr160ProxyAllowedTargets</literal> with a file path to the white list. This should + be an absolute path or a relative path if you know where your Java EE server sets the current directory. + </listitem> + <listitem> + Set the system property <literal>org.jolokia.jsr160ProxyAllowedTargets</literal> to the path of the whitelist + </listitem> + <listitem> + Set the environment variable <literal>JOLOKIA_JSR160_PROXY_ALLOWED_TARGETS</literal> to the path of the + whitelist. + </listitem> + </itemizedlist> + <para> + By default the following patterns are disallowed, but you can re-enable them when providing them in the whitelist: + </para> + <programlisting><![CDATA[ +# Disallow all JNDI lookups via LDAP +service:jmx:rmi:///jndi/ldap:.* +]]></programlisting> + <para> + In any case it is highly recommended to use a dedicated Java EE servlet server for the JSR-160 proxy which + is secured by configuring the server authentication properly for this servlet. An unprotected Jolokia proxy can be + tricked to execute local code by a malicious attacker. As said previously, the Jolokia proxy should be avoided if + possible in favor of direct access over the Jolokia protocol. </para> <para> All client libraries (jmx4perl, Java and Javascript) support the usage of proxy mode in its API. </para> - + <section title="proxy-limitations"> <title>Limitations of proxy mode</title> <para> @@ -82,6 +149,11 @@ JDK and AppServer Version) which don't work at all properly (e.g. JDK 1.5 and JBoss 5). </listitem> + <listitem> + The proxy mode can be exploited for local code execution if not secured properly. + So its is highly recommended to not make the agent available without any authentication to any + non trusted environment. + </listitem> </itemizedlist> </section> </chapter> \ No newline at end of file
src/site/apt/agent.apt+5 −5 modified@@ -9,7 +9,7 @@ Agents Various agents are available for providing Jolokia services in different environments: - * <<WAR Agent>> for deployment as web application in a JEE Server. + * <<WAR Agent>> for deployment as web application in a Java EE Server. * <<OSGi Agent>> for deployment in an OSGi container. This agent is packaged as a bundle and comes in two flavors (minimal, @@ -23,7 +23,7 @@ Agents * WAR Agent The WAR agent <<<jolokia.war>>> deploys as a regular web archive - (WAR) in a JEE server. Deployment is simple (often only a copy in a + (WAR) in a Java EE server. Deployment is simple (often only a copy in a certain directory) and the agent can be tuned like a normal web application. Setting it up the agent servlet for secure communication is a well known business (but specific to every @@ -78,7 +78,7 @@ Agents Pax Web HTTP-Service. This bundle is useful for quick installations, where no HTTP-Service is already existent. However, for best fitting the OSGi philosophy, the usage of the minimal bundle is - recommended. + recommended. The OSGi agent has been tested with the following containers: @@ -122,14 +122,14 @@ Agents * HornetQ 2.2.14 - [] + [] Read more about the {{{./agent/jvm.html}JVM agent}} and its installation. * Mule Agent The {{{http://www.mulesoft.org}Mule Standalone ESB}} offers a dedicated JMX agent - interface, into which this agents plugs in seemlessly. + interface, into which this agents plugs in seemlessly. This agent has been tested for Mule 2 and Mule 3 (3.1.1 and 3.2.0).
src/site/apt/agent/war.apt+5 −5 modified@@ -1,13 +1,13 @@ -Webarchive (WAR) Agent +Webarchive (WAR) Agent - This agent is most suitable for JEE environments. It gets deployed + This agent is most suitable for Java EE environments. It gets deployed as a usual web archive. The specific deployment procedure depends on - the JEE server in used. E.g. for Tomcat, its not more than a copy of - <<jolokia.war>> into the the <<<webapps/>>> directory. + the Java EE server in used. E.g. for Tomcat, its not more than a copy of + <<jolokia.war>> into the the <<<webapps/>>> directory. As soon as it is deployed, the agents offers its services under the URL of the deployed web application. For Tomcat running with its - standard configuration the agent is then reachable under + standard configuration the agent is then reachable under ------ http://localhost:8080/jolokia
src/site/xdoc/about.xml+7 −7 modified@@ -18,19 +18,19 @@ <document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd"> - + <properties> <title>The Jolokia Story</title> <author email="roland@jolokia.org">Roland Huss</author> </properties> - + <body> <section name="The Story"> <p style="text-align: left;"> <img src="images/jolokia_home.png" style="float: right; margin: 0 0 10px 20px;" alt="Jolokia, homegrown"/> All started up early 2009 when my colleague Gerhard Lausser, our local Nagios guru, came up in my office and complained - heavily about how damned hard it is to monitor JEE servers + heavily about how damned hard it is to monitor Java EE servers with <a href="http://www.nagios.org">Nagios</a>. As you might know, Nagios uses a plethora of plugins for doing the hard monitoring stuff. These are running locally on a central @@ -77,7 +77,7 @@ administrator at university in my former life), my initial goal was to use pure Perl for accessing remote JMX information without the need of a local Java integration. In turned out that an agent - based approach was the simplest way. The first agent, a JEE + based approach was the simplest way. The first agent, a Java EE webapplication, which on the frontside translates HTTP requests with a JSON payload to local JMX calls (and vice versa for the response), was really lightweight. It knew how to read and set attributes and @@ -118,7 +118,7 @@ a chili head and grow chilis since 2006. I love chilis as much as JMX. That's the main reason. </p> - <p> + <p> The other reason is, that a chili is a good metaphore for a hot, new approach for JMX remoting. Especially when it is the hottest one ;-) @@ -150,7 +150,7 @@ <a href="http://www.wanderinghorse.net/home/stephan/">Stephan Beal</a> for ironing out my dump english and proofreading the - documentation. + documentation. </li> </ul> </section> @@ -198,7 +198,7 @@ distribution, or any form of commercialization of such material beyond the scope of the copyright law shall require the prior written consent of its respective author or - creator. + creator. </p> <p> <strong>Data Protection</strong>
src/site/xdoc/client/perl.xml+3 −3 modified@@ -18,7 +18,7 @@ <document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd"> - + <properties> <title>Jmx4Perl</title> <author email="roland@jolokia.org">Roland Huss</author> @@ -29,7 +29,7 @@ <p> As described in this <a href="../about.html">story</a>, Jolokia has its origins in the Perl world where it starts as a simple solution for monitoring - Java JEE applications with + Java Java EE applications with <a href="http://www.nagios.org">Nagios</a>. <a href="http://www.jmx4perl.org">Jmx4perl</a> was its former name, which in addition the agents contains powerfule Perl modules for accessing Jolokia instrumented @@ -44,7 +44,7 @@ <pre class="prettyprint lang-perl"> use strict; use JMX::Jmx4Perl; - use JMX::Jmx4Perl::Alias; # Import MBean aliases + use JMX::Jmx4Perl::Alias; # Import MBean aliases # Basic usage print "Memory Used: ",
src/site/xdoc/features/bulk-requests.xml+9 −9 modified@@ -18,7 +18,7 @@ <document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd"> - + <properties> <title>Bulk Requests</title> <author email="roland@jolokia.org">Roland Huss</author> @@ -35,13 +35,13 @@ database connection pool utilisation, HTTP request response for various web application are examples for valuable metrics to monitor. Typically, 10-20 monitored attributes are a good - setup for a single JEE server. + setup for a single Java EE server. </p> <p> With the traditional approach using JSR-160 JMX connectors, a connection is opened, and for each attribute queried a separate RMI (or optional JMXMP) request needs to be send to - the server resulting in several client-server turnarounds. + the server resulting in several client-server turnarounds. Wouldn't it be nice to use a single request for querying all those parameters ? </p> @@ -78,7 +78,7 @@ <pre class="prettyprint"><![CDATA[ [{ "operation":"gc", "mbean":"java.lang:type=Memory", - "type":"EXEC" + "type":"EXEC" }, { "mbean":"java.lang:type=Memory", @@ -87,7 +87,7 @@ }]]]></pre> <p> The answer returned is also represented in JSON and looks like - this: + this: </p> <pre class="prettyprint"><![CDATA[ [{ "timestamp":1285442161, @@ -107,13 +107,13 @@ "committed":"85000192", "init":"0", "used":"3660720" } - }]]]></pre> + }]]]></pre> <p> Another example how bulk requests can be used is the <a - href="http://www.nagios.org/">Nagios</a> + href="http://www.nagios.org/">Nagios</a> Plugin <a href="http://search.cpan.org/~roland/jmx4perl/scripts/check_jmx4perl">check_jmx4perl</a>, - which uses bulk requests + which uses bulk requests for its <em>multi check</em> features, which allows for a single Nagios check monitor as many JMX attributes and operations as required. @@ -133,6 +133,6 @@ </ul> </subsection> </section> - </body> + </body> </document>
src/site/xdoc/features/overview.xml+12 −12 modified@@ -18,7 +18,7 @@ <document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd"> - + <properties> <title>Overview</title> <author email="roland@jolokia.org">Roland Huss</author> @@ -32,13 +32,13 @@ <p> Jolokia is an agent based approach for remote JMX access. It is an alternative to standard <a - href="http://jcp.org/en/jsr/detail?id=160">JSR 160</a> + href="http://jcp.org/en/jsr/detail?id=160">JSR 160</a> connectors. The communication between client and agent goes over HTTP (either GET or POST), where the request and response payload is represented in JSON. </p> <p> - The Jolokia protocol supports the following operations: + The Jolokia protocol supports the following operations: </p> <ul> <li>Reading and writing JMX attributes</li> @@ -61,7 +61,7 @@ <img src="../images/jolokia_architecture.png" alt="Architecture"/> </div> <p> - This approach has some advantages: + This approach has some advantages: </p> <ul> <li> @@ -75,7 +75,7 @@ <li> Fine grained <a href="security.html">security</a> with access restriction on MBean operation and attribute - level. + level. </li> <li> Merging of multiple <code>MBeanServer</code> into one @@ -95,7 +95,7 @@ href="polyglot.html">client</a> side due to the platform neutral nature of HTTP and JSON. </li> - <li> + <li> JSON serialization allows for deep access into returned objects without having custom type definitions installed on the client side. @@ -107,7 +107,7 @@ <a href="firewall.html">firewall</a> configuration. The JSR-160 default connector in contrast is not that smart since RMI uses a random port for its communication by - default. + default. </li> <li> As paradox as it might sound, setting up an agent is often @@ -127,13 +127,13 @@ export so an extra installation step is not welcome. Also, updating Jolokia normally implies a redeployment of the agent. These are all good reasons, for which Jolokia has an - answer, too. By installing a dedicated JEE-Server with an + answer, too. By installing a dedicated Java EE-Server with an deployed agent, Jolokia can operate in <a href="proxy.html">proxy mode</a>, in which case it translate Jolokia JSON request into JSR-160 client request for operation on the target server. Vice versa, the result over a JSR-160 connector then gets translated into a JSON response which is - returned to Jolokia client. + returned to Jolokia client. </p> <subsection name="Example"> <p> @@ -169,7 +169,7 @@ "mbean":"java.lang:type=Memory", "attribute":"HeapMemoryUsage", "type":"read" - }, + }, "value": { "max":"129957888", "committed":"85000192", @@ -184,7 +184,7 @@ Learn something about <a href="bulk-requests.html">bulk JMX requests</a>. </li> <li> - See why jolokia is the <a href="polyglot.html">perfect choice</a> for non-Java environments + See why jolokia is the <a href="polyglot.html">perfect choice</a> for non-Java environments to access Java servers via JMX. </li> <li> @@ -193,6 +193,6 @@ </ul> </subsection> </section> - </body> + </body> </document>
src/site/xdoc/features/proxy.xml+7 −7 modified@@ -18,7 +18,7 @@ <document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd"> - + <properties> <title>JMX Proxy</title> <author email="roland@jolokia.org">Roland Huss</author> @@ -34,7 +34,7 @@ political reasons or an already established JSR-160 export on the instrumented servers. In these environments, Jolokia can operate as a <strong>JMX Proxy</strong>. In this setup, the - agent is deployed on a dedicated proxy JEE server (or other + agent is deployed on a dedicated proxy Java EE server (or other supported agent platform). The proxy bridges between Jolokia JSON request and responses to remote JSR-160 calls to the target server. The following diagrams gives an illustration of @@ -66,7 +66,7 @@ http://jolokia-proxy:8080/jolokia</pre> "type":"READ" "mbean":"java.lang:type=Threading", "attribute":"ThreadCount", - "target": { + "target": { "url":"service:jmx:rmi:///jndi/rmi://jboss-as:8686/jmxrmi", "password":"admin", "user":"s!cr!t" @@ -91,22 +91,22 @@ http://jolokia-proxy:8080/jolokia</pre> requests, so that a Jolokia bulk request arriving at the proxy gets dispatched into multiple JSR-160 requests for the target. The JSR-160 remote connection has to be - established only once, though. + established only once, though. </li> <li> The JMX target URL addresses the MBeanServer directly, so MBeanServer merging as it happens for direct operation is not available. Also, certain workarounds for bugs in the server's JMX implementation are not available. (e.g. see - this <a href="http://labs.consol.de/blog/jmx4perl/jboss-remote-jmx/">blog post</a> for a JBoss bug when + this <a href="http://labs.consol.de/blog/jmx4perl/jboss-remote-jmx/">blog post</a> for a JBoss bug when accessing MXBeans in the PlatformMBeanServer) </li> <li> When no-standard Java types are returned by JMX operations or attribute read calls, these types must be available on the proxy, too. Using the Jolokia agent directly, complex data types are serialized deeply into a JSON - representation automatically. + representation automatically. </li> <li> For each Jolokia request, a new JMX connection (likely @@ -130,6 +130,6 @@ http://jolokia-proxy:8080/jolokia</pre> </ul> </subsection> </section> - </body> + </body> </document>
src/site/xdoc/features/security.xml+5 −5 modified@@ -18,7 +18,7 @@ <document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd"> - + <properties> <title>Secure</title> <author email="roland@jolokia.org">Roland Huss</author> @@ -32,7 +32,7 @@ <p> Security in Jolokia is provided on two levels: The transport channel (HTTP) is secured the standard way as it is defined in - the JEE specifications. The agent itself can be configured to + the Java EE specifications. The agent itself can be configured to use a very fine grained policy which can restrict access on the MBean level for various parameters. </p> @@ -47,7 +47,7 @@ <p> The security definitions support a wildcard notation and allow/deny sections similar to the security setup of an Apache - HTTP-Server. + HTTP-Server. </p> <subsection name="Example"> <p> @@ -61,7 +61,7 @@ <host>localhost</host> <host>10.0.0.0/16</host> </remote> - + <cors> <allow-origin>http://www.jmx4perl.org</allow-origin> <allow-origin>*.jolokia.org</allow-origin> @@ -133,6 +133,6 @@ </ul> </subsection> </section> - </body> + </body> </document>
src/site/xdoc/features/simple.xml+6 −6 modified@@ -18,7 +18,7 @@ <document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd"> - + <properties> <title>Simple</title> <author email="roland@jolokia.org">Roland Huss</author> @@ -36,12 +36,12 @@ <ul> <li> The <a href="../agent/war.html">WAR Agent</a> gets deployed as any other - JEE web application. Often this is as simpe as a simple + Java EE web application. Often this is as simpe as a simple copy of the agent war-artifact into a certain directory (like for Tomcat). Or it gets deployed via an administrative user interface (web GUI or command line tool). In any case, the procedure should be familar to any Java developer or - administrator dealing with JEE applications. + administrator dealing with Java EE applications. </li> <li> The <a href="../agent/osgi.html">OSGi Agent</a> gets deployed as any other @@ -71,7 +71,7 @@ <code>PlatformMBeanServer</code>. On our blog, detailed analysis for JSR-160 setup for <a href="http://labs.consol.de/blog/jmx4perl/configuring-remote-jmx-access-for-weblogic/">Weblogic</a> - and <a + and <a href="http://labs.consol.de/blog/jmx4perl/jboss-remote-jmx/">JBoss</a> has been posted. </p> <p> @@ -96,7 +96,7 @@ example, a so called <em>path</em> (i.e. <code>used</code>) is appended to the URL which allows for deep access in more complex Java types (<code>CompositeData</code> in this - case). + case). </p> <subsection name="Next"> <ul> @@ -112,6 +112,6 @@ </ul> </subsection> </section> - </body> + </body> </document>
src/site/xdoc/index.xml+64 −4 modified@@ -63,7 +63,7 @@ </li> <li> <a href="agent.html">Agents</a> exist for many - platforms (JEE, OSGi, Mule, JVM). + platforms (Java EE, OSGi, Mule, JVM). </li> <li> <a href="support.html">Support</a> is available through various channels. @@ -75,6 +75,66 @@ <span style="clear: both;"></span> </subsection> <section name="News"> +<subsection name="Security fixes with 1.5.0"> + <div class="news-date"></div> + <p> + Two security issues for Jolokia have recently been discovered by Olga Barinova of + <a href="https://www.gdssecurity.com/">Gotham Digital Science</a>: + </p> + <ul> + <li>The Jolokia <a href="https://jolokia.org/reference/html/proxy.html">JMX proxy mode</a> is vulnerable + to remote code execution in a specific scenario. Note that this + only affects the <a href="https://jolokia.org/reference/html/agents.html#agents-war">WAR agent</a>, which has the proxy mode enabled by default. + The <a href="https://jolokia.org/reference/html/agents.html#agents-jvm">JVM agent</a> is not affected as it does not support the JMX proxy mode</li> + <li>An XSS attack can be performed by manipulating the <code>mimeType</code> query parameter to coerce the Web browser to + display the JSON response directly. However, we consider the impact quite low, as Jolokia responses are <em>not</em> + shown directly in the browser but used by a JavaScript library, which has to perform its own escaping of user + provided response data. Jolokia 1.5.0 fixes this hole nevertheless. + </li> + </ul> + <p> + Jolokia 1.5.0 now fixes these issue in the following way: + </p> + <p> + As a first measure, the JMX proxy mode is <strong>disabled by default</strong> for the WAR agent. + You can switch it on if you need as usual by adding the relevant configuration to <code>web.xml</code>. + But you can now also enable the proxy mode without touching <code>jolokia.war</code>: + By setting a Java system property or an environment variable, the proxy mode + can be switched on again, too. + These parameters can be easily added to the startup script of your servlet container. + </p> + <p> + Also, you can now configure a whitelist with allowed patterns for the JMX service URL used as + the target URL of the proxy. + These patterns are supposed to be contained in a plain text file, line by line. + This file then can be referenced by a system property, an env variable or directly configured in <code>web.xml</code> + in the war file. + </p> + <p> + For the configuration options of the Jolokia proxy please refer to + the <a href="https://jolokia.org/reference/html/proxy.html">Proxy Mode</a> section of the reference manual. + </p> + <p> + Finally, we always recommend using a dedicated server when using the JMX proxy mode, e.g. a Jetty or Tomcat servlet container. + These servers should be protected by requiring some authentication. The authentication setup is specific to the + Java EE server but you have to edit the Jolokia WAR agent to enable authentication as described in the <a href="https://jolokia.org/reference/html/agents.html#agent-war-security">Security Setup</a> chapter in the reference manual. + </p> + <p> + For closing the XSS vulnerability, nothing extra needs to be configured. + Jolokia now just verifies that only <code>text/plain</code> and <code>application/json</code> is allowed as the + value of the query parameter <code>mimeType</code> and falls back to plain <code>text/plain</code> if something + different is provided. + </p> + <p> + It is <strong>highly recommended</strong> to upgrade to Jolokia 1.5.0 if you are relying on the JMX proxy feature and to + revisit your security setup around the proxy server. + </p> + <p> + Big Kudos go out to GDS (and especially to Olga Barinova and Martin Hopkins) for openly reporting this issue in deep + detail to me and being very cooperative in helping to fix these. Also to R3, for whom GDS was working when these issues + were discovered, who encouraged GDS to report them. Highly appreciated! + </p> + </subsection> <subsection name="2018 Kick-Off with Jolokia 1.4.0"> <div class="news-date">2018-01-23</div> <p> @@ -528,11 +588,11 @@ java -javaagent:jolokia.jar=\ request</a> from <a href="https://github.com/mplonka">Marcin Płonka</a> (Thanks a lot and sorry for the long, long delay, BTW). It's all about simplifying access to JSR-77 enabled - JEE-Servers. You should know that <a + Java EE-Servers. You should know that <a href="https://jcp.org/en/jsr/detail?id=77">JSR 77: J2EE Management</a> was a cool attempt to standardize naming and - JMX exposed metrics for JEE. Unfortunately it was abandoned, - but still lives in quite a bunch of JEE servers. Not at its + JMX exposed metrics for Java EE. Unfortunately it was abandoned, + but still lives in quite a bunch of Java EE servers. Not at its full beauty, but still valuable enough to be supported. Astonishingly, WebSphere, even the latest 8.5 versions, has the best support for it. Using JSR-77 conform
tools/roo-addon/src/main/resources/org/jolokia/roo/configuration.xml+0 −8 modified@@ -92,14 +92,6 @@ <artifactId>jolokia-jsr160</artifactId> <version>${jolokia.version}</version> </dependency> - <init-param> - <description> - Class names (comma separated) of RequestDispatcher used in addition - to the LocalRequestDispatcher - </description> - <param-name>dispatcherClasses</param-name> - <param-value>org.jolokia.jsr160.Jsr160RequestDispatcher</param-value> - </init-param> </jsr160Proxy> </jolokia> </configuration> \ No newline at end of file
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- access.redhat.com/errata/RHSA-2018:2669ghsavendor-advisoryx_refsource_REDHATWEB
- github.com/advisories/GHSA-rhqj-4pp8-vvgfghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2018-1000130ghsaADVISORY
- github.com/rhuss/jolokia/commit/1b360b8889f0ed51165a8d1ac55dd8e0aa2dfd4aghsaWEB
- github.com/rhuss/jolokia/commit/fd7b93da30c61a45bac10d8b311f1b79a74910f5ghsaWEB
- github.com/rhuss/jolokia/releases/tag/v1.5.0ghsaWEB
- jolokia.orgghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.