5.6. Security Options for JMS ObjectMessage Serialization
Overview
The
javax.jms.ObjectMessage
type can be used to send messages containing a serialized Java object. This feature has been available since JMS 1.0 and is supported by Apache ActiveMQ, but use of this feature is generally not recommended, for the following reasons:
- Architecturally, messaging systems enable loose coupling between producers and consumers, but
ObjectMessage
re-introduces tight coupling, thereby negating a key benefit of the message-based architecture. - Using
ObjectMessage
introduces coupling of class paths between producers and consumers. - Using
ObjectMessage
presents a significant security risk, because the serialized objects can be used to transfer malicious code.
Security risks
ObjectMessage
objects depend on Java serialization to marshal and unmarshal their object payload. This process is generally considered unsafe, because a malicious payload can exploit the host system. For this reason, starting from AMQ 6.3, AMQ forces users to explicitly whitelist packages that can be exchanged using ObjectMessage
messages.
Whitelisting Java packages
To whitelist Java packages, so that they can be used in a serialized object message, you are required to list the acceptable packages in the
org.apache.activemq.SERIALIZABLE_PACKAGES
system property. This system property can be used both on the server side (broker) and on the client side.
For example, on the broker side, you can set this property in the
InstallDir/etc/system.properties
file, as follows:
org.apache.activemq.SERIALIZABLE_PACKAGES="java.lang,java.util,org.apache.activemq,org.fusesource.hawtbuf,com.thoughtworks.xstream.mapper,com.mycompany.myapp"
Which adds the
com.mycompany.myapp
package to the list of trusted packages. Note that the other packages listed here are enabled by default, because they are necessary for the regular broker to work.
Bypassing the whitelist mechanism
In case you want to bypass the whitelist mechanism, you can allow all packages to be trusted by specifying the
*
wildcard character—for example:
org.apache.activemq.SERIALIZABLE_PACKAGES="*"
Warning
Disabling the whitelist mechanism can be useful in a testing environment, but it should not be used in a deployed system.
Client-side whitelisting API
On the client side, you can also configure trusted packages using the
org.apache.activemq.SERIALIZABLE_PACKAGES
system property, but this approach is usually not convenient for client applications. An alternative approach is to use the API methods defined on the ActiveMQConnectionFactory
class (where these API settings would override the system property, if it is set). There are two additional methods defined available:
- The
setTrustedPackages()
method allows you to set the list of trusted packages you want to be to unserialize—for example:ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); factory.setTrustedPackages(new ArrayList(Arrays.asList("org.apache.activemq.test,org.apache.camel.test".split(","))));
The list of trusted packages can also be set in XML. For example, a Camel endpoint in a Spring XML file can be configured as follows:<bean id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616"/> <property name="trustedPackages"> <list> <value>org.apache.activemq.test</value> <value>org.apache.camel.test</value> </list> </property> </bean> <bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration"> <property name="connectionFactory" ref="connectionFactory"/> </bean> <bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent"> <property name="configuration" ref="jmsConfig"/> </bean>
- The
setTrustAllPackages()
allows you to turn off the security check and trust all classes. It can be useful for testing purposes. For example:ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); factory.setTrustAllPackages(true);
The whitelist mechanism can also be disabled in Spring XML as follows:<bean id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616"/> <property name="trustAllPackages" value="true"/> </bean> <bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration"> <property name="connectionFactory" ref="connectionFactory"/> </bean> <bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent"> <property name="configuration" ref="jmsConfig"/> </bean>
WarningDisabling the whitelist mechanism can be useful in a testing environment, but it should not be used in a deployed system.