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>
    Warning
    Disabling the whitelist mechanism can be useful in a testing environment, but it should not be used in a deployed system.