java.lang.security.insecure-jms-deserialization.insecure-jms-deserialization

Author
5,552
Download Count*
License
JMS Object messages depend on Java Serialization for marshalling/unmarshalling of the message payload when ObjectMessage.getObject() is called. Deserialization of untrusted data can lead to security flaws; a remote attacker could via a crafted JMS ObjectMessage to execute arbitrary code with the permissions of the application listening/consuming JMS Messages. In this case, the JMS MessageListener consume an ObjectMessage type received inside the onMessage method, which may lead to arbitrary code execution when calling the $Y.getObject method.
Run Locally
Run in CI
Defintion
rules:
- id: insecure-jms-deserialization
severity: WARNING
languages:
- java
metadata:
cwe:
- "CWE-502: Deserialization of Untrusted Data"
owasp:
- A08:2017 - Insecure Deserialization
- A08:2021 - Software and Data Integrity Failures
asvs:
section: V5 Validation, Sanitization and Encoding
control_id: 5.5.3 Insecue Deserialization
control_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v55-deserialization-prevention
version: "4"
references:
- https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities-wp.pdf
category: security
technology:
- java
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- vuln
likelihood: LOW
impact: MEDIUM
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
message: JMS Object messages depend on Java Serialization for
marshalling/unmarshalling of the message payload when
ObjectMessage.getObject() is called. Deserialization of untrusted data can
lead to security flaws; a remote attacker could via a crafted JMS
ObjectMessage to execute arbitrary code with the permissions of the
application listening/consuming JMS Messages. In this case, the JMS
MessageListener consume an ObjectMessage type received inside the
onMessage method, which may lead to arbitrary code execution when calling
the $Y.getObject method.
patterns:
- pattern-inside: |
public class $JMS_LISTENER implements MessageListener {
...
public void onMessage(Message $JMS_MSG) {
...
}
}
- pattern-either:
- pattern-inside: $X = $Y.getObject(...);
- pattern-inside: $X = ($Z) $Y.getObject(...);
Examples
insecure-jms-deserialization.java
package com.rands.couponproject.ejb;
import java.util.Date;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.TextMessage;
import org.apache.log4j.Logger;
import com.rands.couponproject.jpa.Income;
/**
* Message-Driven Bean implementation class for: IncomeConsumerBean
*/
@MessageDriven(activationConfig = {
@ActivationConfigProperty(
propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(
propertyName = "destination", propertyValue = "java:/jms/queue/MyQueue")
})
public class IncomeConsumerBean implements MessageListener {
static Logger logger = Logger.getLogger(IncomeConsumerBean.class);
@EJB
IncomeServiceBean isb;
/**
* Default constructor.
*/
public IncomeConsumerBean() {
// TODO Auto-generated constructor stub
}
/**
* @see MessageListener#onMessage(Message)
*/
public void onMessage(Message message) {
try {
if (message instanceof TextMessage) {
logger.info("onMessage received a TextMessage at " + new Date());
TextMessage msg = (TextMessage) message;
logger.warn("onMessage ignoring TextMessage : " + msg.getText());
} else if (message instanceof ObjectMessage) {
logger.info("onMessage received an ObjectMessage at " + new Date());
ObjectMessage msg = (ObjectMessage) message;
// ruleid: insecure-jms-deserialization
Object o = msg.getObject(); // variant 1 : calling getObject method directly on an ObjectMessage object
logger.info("o=" + o);
// ruleid: insecure-jms-deserialization
Income income = (Income) msg.getObject(); // variant 2 : calling getObject method and casting to a custom class
logger.info("Message is : " + income);
isb.StoreIncome(income);
} else {
logger.error("onMessage received an invalid message type");
}
} catch (JMSException e) {
logger.error("onMessage failed : " + e.toString());
}
}
}
Short Link: https://sg.run/zvO1