Deserialization of Untrusted Data in JMS Security Issue - java

I am using a bean for sending mails in my Java EE application. My class for sending mails is generated through xDoclet. Class code is given below
public void onMessage(javax.jms.Message message) {
MapMessage mapMsg = (MapMessage) message;
String toEmailAddress = mapMsg.getString("toAddress");
String ccEmailAddress = mapMsg.getString("ccAddress");
String from = mapMsg.getString("from");
String subject = mapMsg.getString("subject");
String content = mapMsg.getString("body");
}
Now, I have got some security issues in checkmarx for this class as - Deserialization of Untrusted Data in JMS at lines
String toEmailAddress = mapMsg.getString("toAddress");
String ccEmailAddress = mapMsg.getString("ccAddress");

Base on the Checkmarx query for Deserialization of Untrusted Data in JMS, add a try catch block when casting and check if message is not an instance of ObjectMessage:
public void onMessage(javax.jms.Message message) {
try {
if !(message instanceOf ObjectMessage){
MapMessage mapMsg = (MapMessage) message;
String toEmailAddress = mapMsg.getString("toAddress");
String ccEmailAddress = mapMsg.getString("ccAddress");
String from = mapMsg.getString("from");
String subject = mapMsg.getString("subject");
String content = mapMsg.getString("body");
}
}
catch {}
finally {}
}

I solved this issue in checkmarx adding the validation instanceof TextMessage in onMessage implementation:
public void onMessage(Message message) {
if (message instanceof TextMessage) {
try {
....
catch (JMSException ex) {
throw new RuntimeException(ex);
}
}
else {
throw new IllegalArgumentException("Message must be of type TextMessage");
}
}

Related

How to catch errors in spring-integration socket server?

I have the following working socket server configuration, and would like to add a handler if any exception occurs, eg inside the Deserializer during read of the message.
Therefore I added a #ServiceActivator(inputChannel = "errorChannel"). But the method is never invoked. Why?
#MessageEndpoint
public class SocketEndpoint {
#ServiceActivator(inputChannel = "mainChannel")
public String handleMessage(String message) {
return "normal response";
}
#ServiceActivator(inputChannel = "errorChannel")
public String handleError(MessagingException message) {
//TODO this is never invoked!
return "some error";
}
}
#Bean
public TcpInboundGateway mainGateway(
#Qualifier("tcpFactory") TcpConnectionFactoryFactoryBean factory,
#Qualifier("mainChannel") MessageChannel mainChannel,
#Qualifier("errorChannel") MessageChannel errorChannel) throws Exception {
TcpInboundGateway g = new TcpInboundGateway();
g.setConnectionFactory(factory.getObject());
g.setRequestChannel(mainChannel);
g.setErrorChannel(errorChannel);
return g;
}
#Bean
public TcpConnectionFactoryFactoryBean fact() {
TcpConnectionFactoryFactoryBean f = new TcpConnectionFactoryFactoryBean();
f.setType("server");
//....
f.setDeserializer(new MyDeserializer());
return f;
}
class MyDeserializer implements Deserializer<String> {
#Override
public String deserialize(InputStream inputStream)
throw new RuntimeException("catch me in error-channel");
}
}
throw new RuntimeException("catch me in error-channel");
It can't go to the error channel since there's no message yet (messages sent to error channels are messages that fail downstream processing).
The standard deserializers (that extend AbstractByteArraySerializer) publish a TcpDeserializationExceptionEvent when deserialization fails. See the ByteArrayCrLfSerializer for an example:
https://github.com/spring-projects/spring-integration/blob/master/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/serializer/ByteArrayCrLfSerializer.java#L78
public int fillToCrLf(InputStream inputStream, byte[] buffer) throws IOException {
int n = 0;
int bite;
if (logger.isDebugEnabled()) {
logger.debug("Available to read: " + inputStream.available());
}
try {
...
}
catch (SoftEndOfStreamException e) {
throw e;
}
catch (IOException e) {
publishEvent(e, buffer, n);
throw e;
}
catch (RuntimeException e) {
publishEvent(e, buffer, n);
throw e;
}
}
See the documentation. The Deserializer needs to be a bean so that it gets an event publisher.
You can then listen for the event(s) with an ApplicationListener< TcpDeserializationExceptionEvent> or an #EventListener method.

Mockito Error in test case while sending message to activeMQ onMessage()

Iam writing an application using ActiveMQ and unit test cases using Mockito where i have a asynchronous onMessage() listener and a method to test the same.The test case fails if i add any if condition in the onMessage().How to avoid this
The code snippet is as below
Main.java
//Initialize boolean here
boolean flag=false;
public void onMessage(final Message message) {
//getting error in the below if condition
if(flag) //Not executing at all Null pointer here
{
if (!(message instanceof TextMessage)) {
//Log error
}
try {
final String messageType = message.getStringProperty("messageType");
_LOG.info("The MessageType is {}", messageType);
final String msg = ((TextMessage) message).getText();
_LOG.debug(msg);
} catch (final JMSException e) {
_LOG.error("We could not read the message", e);
}
}
else //not able to execute if or else conditions
{
//do Something else
}
}
MockTest.java
//Call Main here
#InjectMocks
private Main listener;
#Test
public void shouldProcessMessage() throws JMSException {
final String messageType = "Hello";
final String messageBody ="Hi";
final ActiveMQTextMessage message = new ActiveMQTextMessage();
message.setStringProperty("messageType", messageType);
message.setText(messageBody);
// The below line does not execute at all
// iam getting null pointer exception here
listener.onMessage(message);
}
Has the Boolean value flag been instantiated somewhere in this class?
If you are getting an NPE, it's probably because you have not instantiated the flag variable.

Send message to single client in tomcat websockets

In tomcat-8 examples I have seen a example on chat using HTML5 web sockets.
The code is shown below
public class ChatAnnotation {
private static final Log log = LogFactory.getLog(ChatAnnotation.class);
private static final String GUEST_PREFIX = "Guest";
private static final AtomicInteger connectionIds = new AtomicInteger(0);
private static final Set<ChatAnnotation> connections =
new CopyOnWriteArraySet<>();
private final String nickname;
private Session session;
public ChatAnnotation() {
nickname = GUEST_PREFIX + connectionIds.getAndIncrement();
}
#OnOpen
public void start(Session session) {
this.session = session;
connections.add(this);
String message = String.format("* %s %s", nickname, "has joined.");
broadcast(message);
}
#OnClose
public void end() {
connections.remove(this);
String message = String.format("* %s %s",
nickname, "has disconnected.");
broadcast(message);
}
#OnMessage
public void incoming(String message) {
// Never trust the client
String filteredMessage = String.format("%s: %s",
nickname, HTMLFilter.filter(message.toString()));
broadcast(filteredMessage);
}
private static void broadcast(String msg) {
for (ChatAnnotation client : connections) {
try {
synchronized (client) {
client.session.getBasicRemote().sendText(msg);
}
} catch (IOException e) {
log.debug("Chat Error: Failed to send message to client", e);
connections.remove(client);
try {
client.session.close();
} catch (IOException e1) {
// Ignore
}
String message = String.format("* %s %s",
client.nickname, "has been disconnected.");
broadcast(message);
}
}
}
}
This code send a message to all the clients who connected to server .
But I want to send message to only "Guest1".
I think for loop has to be change.
How to send message to only "Guest1".
Convert connections from set into a map:
ConcurrentHashMap< String, ChatAnnotation> connections = new ConcurrentHashMap<>();
Keep user or whatever identifier you have to identify user as key in the map. They get the connection object from map using user key in broadcast method and send message only to that user, instead of iterating over all connection objects.

Missing value in SNMP

I use snmp4j ver 1.10.1 from org.snmp4j and this is my trap receiver code to catch data from snmp trap.
public class TrapReceiver extends Thread implements CommandResponder {
//#Autowired
private CarService carService;
List<PDUv1> listPdu = new ArrayList<PDUv1>();
List<PDUv1> temp = new ArrayList<PDUv1>();
String message = "";
int totReceivedTrap = 0;
public TrapReceiver(CarService carService){
this.carService = carService;
}
public synchronized void processPdu(CommandResponderEvent cmdRespEvent) {
PDUv1 pdu = (PDUv1) cmdRespEvent.getPDU();
if (pdu != null) {
System.out.println(pdu.getVariableBindings().toString());
}
totReceivedTrap++;
System.out.println("total received trap "+totReceivedTrap);
}
public void run() {
while (true) {
try {
this.listen(new UdpAddress("192.168.1.5/162")); //alamat PDU akan listen
} catch (Exception e) {
e.printStackTrace();
}
}
}
public synchronized void listen(TransportIpAddress address) throws IOException {
AbstractTransportMapping transport;
if (address instanceof TcpAddress) {
transport = new DefaultTcpTransportMapping((TcpAddress) address);
} else {
transport = new DefaultUdpTransportMapping((UdpAddress) address);
}
ThreadPool threadPool = ThreadPool.create("DispatcherPool", 10);
MessageDispatcher mDispathcher = new MultiThreadedMessageDispatcher(
threadPool, new MessageDispatcherImpl());
// add message processing models
mDispathcher.addMessageProcessingModel(new MPv1());
mDispathcher.addMessageProcessingModel(new MPv2c());
// add all security protocols
SecurityProtocols.getInstance().addDefaultProtocols();
SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES());
// Create Target
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
Snmp snmp = new Snmp(mDispathcher, transport);
snmp.addCommandResponder(this);
transport.listen();
message ="Listening on " + address;
System.out.println(message);
try {
this.wait();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
public String getMessage(){
return this.message;
}
}
But one variable value is missing, the value of this variable is latitude and longitude (format : -903849323.20384;+230349402.03000). And when i catch the data using wireshark, I got the value is missing too.
The screenshot
http://www.mediafire.com/view/?kjz1drb9jhda88a
http://www.mediafire.com/view/?ov6lqn6u9n669my
Why the data is null, what wrong.
If you do not see the value inside the packet captured by wireshark, then it is completely valid that you get the null value in the code. What else would you expect?
This seems to be more likely a problem/feature of the SNMP agent running on the device (e.g. geo location was not set, GPS signal is not available, etc.)

JSON sending class A goes in class B

I am starting out on Restful web services and learning through JSON google gson. Though till now i have just made my server producer and json consumer application.
and i am loving it.
Now this is my consumer code: it has a TextMessages class object message
private void submitButtonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
InputStreamReader reader = null;
String name = nameTextfield.getText();
String url = "http://myurl/" + name;
try {
try {
reader = new InputStreamReader(new URL(url).openStream());
} catch (MalformedURLException ex) {
Logger.getLogger(StartClient.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (IOException ex) {
Logger.getLogger(StartClient.class.getName()).log(Level.SEVERE, null, ex);
}
TextMessages message = new Gson().fromJson(reader, TextMessages.class);
JOptionPane.showMessageDialog(this, message.getMessage(), "Welcome" + message.sumAllIntegers(),
JOptionPane.INFORMATION_MESSAGE);
}
// class TextMessages
package use;
public class TextMessages{
private String message;
private int a,b,c,d,wee;
public TextMessages(String __message){
message = __message;
}
public TextMessages(){
}
public String getMessage(){
return message;
}
public void setMessage(String __message){
message = __message;
}
}
Now server is sending JSON of class OtherTestMessage
public class TextMessage {
private String message;
//getter and setter functions
// no int a,b
.....
Why is it working right ? Shoule it be working right ? is it again languages philosophy? how does JSON convert things. Or is it donot ? Just copying data ?
The gson library is looking at the JSON and mapping what it can to the class you provide.
Both of your classes have a String called message in them. gson is taking the message element in the JSON and storing the value in both cases. In your TextMessages class, it will also store the values for a, b, etc if those elements are present in the JSON.
In the case of your TextMessage class that only has String message, the additional elements in the JSON (a,b, etc) are silently ignored if they are present.

Categories