Merge pull request #8765 from artem-smotrakov/cover-jms

Java: Add flow sources and steps for RabbitMQ and JMS
This commit is contained in:
Chris Smowton
2022-04-27 21:27:05 +01:00
committed by GitHub
35 changed files with 515 additions and 2 deletions

View File

@@ -0,0 +1,6 @@
---
category: minorAnalysis
---
* Added flow sources and steps for JMS versions 1 and 2.
* Added flow sources and steps for RabbitMQ.
* Added flow steps for `java.io.DataInput` and `java.io.ObjectInput` implementations.

View File

@@ -138,6 +138,8 @@ private module Frameworks {
private import semmle.code.java.frameworks.MyBatis
private import semmle.code.java.frameworks.Hibernate
private import semmle.code.java.frameworks.jOOQ
private import semmle.code.java.frameworks.JMS
private import semmle.code.java.frameworks.RabbitMQ
}
private predicate sourceModelCsv(string row) {

View File

@@ -0,0 +1,112 @@
/**
* This model covers JMS API versions 1 and 2.
*
* https://docs.oracle.com/javaee/6/api/javax/jms/package-summary.html
* https://docs.oracle.com/javaee/7/api/javax/jms/package-summary.html
*/
import java
private import semmle.code.java.dataflow.ExternalFlow
/** Defines sources of tainted data in JMS 1. */
private class Jms1Source extends SourceModelCsv {
override predicate row(string row) {
row =
[
// incoming messages are considered tainted
"javax.jms;MessageListener;true;onMessage;(Message);;Parameter[0];remote",
"javax.jms;MessageConsumer;true;receive;;;ReturnValue;remote",
"javax.jms;MessageConsumer;true;receiveNoWait;();;ReturnValue;remote",
"javax.jms;QueueRequestor;true;request;(Message);;ReturnValue;remote",
"javax.jms;TopicRequestor;true;request;(Message);;ReturnValue;remote",
]
}
}
/** Defines taint propagation steps in JMS 1. */
private class Jms1FlowStep extends SummaryModelCsv {
override predicate row(string row) {
row =
[
// if a message is tainted, then it returns tainted data
"javax.jms;Message;true;getBody;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getJMSCorrelationIDAsBytes;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getJMSCorrelationID;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getJMSReplyTo;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getJMSDestination;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getJMSType;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getBooleanProperty;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getByteProperty;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getShortProperty;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getIntProperty;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getLongProperty;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getFloatProperty;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getDoubleProperty;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getStringProperty;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getObjectProperty;();;Argument[-1];ReturnValue;taint",
"javax.jms;Message;true;getPropertyNames;();;Argument[-1];ReturnValue;taint",
"javax.jms;BytesMessage;true;readBoolean;();;Argument[-1];ReturnValue;taint",
"javax.jms;BytesMessage;true;readByte;();;Argument[-1];ReturnValue;taint",
"javax.jms;BytesMessage;true;readUnsignedByte;();;Argument[-1];ReturnValue;taint",
"javax.jms;BytesMessage;true;readShort;();;Argument[-1];ReturnValue;taint",
"javax.jms;BytesMessage;true;readUnsignedShort;();;Argument[-1];ReturnValue;taint",
"javax.jms;BytesMessage;true;readChar;();;Argument[-1];ReturnValue;taint",
"javax.jms;BytesMessage;true;readInt;();;Argument[-1];ReturnValue;taint",
"javax.jms;BytesMessage;true;readLong;();;Argument[-1];ReturnValue;taint",
"javax.jms;BytesMessage;true;readFloat;();;Argument[-1];ReturnValue;taint",
"javax.jms;BytesMessage;true;readDouble;();;Argument[-1];ReturnValue;taint",
"javax.jms;BytesMessage;true;readUTF;();;Argument[-1];ReturnValue;taint",
"javax.jms;BytesMessage;true;readBytes;;;Argument[-1];Argument[0];taint",
"javax.jms;MapMessage;true;getBoolean;(String);;Argument[-1];ReturnValue;taint",
"javax.jms;MapMessage;true;getByte;(String);;Argument[-1];ReturnValue;taint",
"javax.jms;MapMessage;true;getShort;(String);;Argument[-1];ReturnValue;taint",
"javax.jms;MapMessage;true;getChar;(String);;Argument[-1];ReturnValue;taint",
"javax.jms;MapMessage;true;getInt;(String);;Argument[-1];ReturnValue;taint",
"javax.jms;MapMessage;true;getLong;(String);;Argument[-1];ReturnValue;taint",
"javax.jms;MapMessage;true;getFloat;(String);;Argument[-1];ReturnValue;taint",
"javax.jms;MapMessage;true;getDouble;(String);;Argument[-1];ReturnValue;taint",
"javax.jms;MapMessage;true;getString;(String);;Argument[-1];ReturnValue;taint",
"javax.jms;MapMessage;true;getBytes;(String);;Argument[-1];ReturnValue;taint",
"javax.jms;MapMessage;true;getObject;(String);;Argument[-1];ReturnValue;taint",
"javax.jms;MapMessage;true;getMapNames;();;Argument[-1];ReturnValue;taint",
"javax.jms;ObjectMessage;true;getObject;();;Argument[-1];ReturnValue;taint",
"javax.jms;StreamMessage;true;readBoolean;();;Argument[-1];ReturnValue;taint",
"javax.jms;StreamMessage;true;readByte;();;Argument[-1];ReturnValue;taint",
"javax.jms;StreamMessage;true;readShort;();;Argument[-1];ReturnValue;taint",
"javax.jms;StreamMessage;true;readChar;();;Argument[-1];ReturnValue;taint",
"javax.jms;StreamMessage;true;readInt;();;Argument[-1];ReturnValue;taint",
"javax.jms;StreamMessage;true;readLong;();;Argument[-1];ReturnValue;taint",
"javax.jms;StreamMessage;true;readFloat;();;Argument[-1];ReturnValue;taint",
"javax.jms;StreamMessage;true;readDouble;();;Argument[-1];ReturnValue;taint",
"javax.jms;StreamMessage;true;readString;();;Argument[-1];ReturnValue;taint",
"javax.jms;StreamMessage;true;readBytes;(byte[]);;Argument[-1];Argument[0];taint",
"javax.jms;StreamMessage;true;readObject;();;Argument[-1];ReturnValue;taint",
"javax.jms;TextMessage;true;getText;();;Argument[-1];ReturnValue;taint",
// if a destination is tainted, then it returns tainted data
"javax.jms;Queue;true;getQueueName;();;Argument[-1];ReturnValue;taint",
"javax.jms;Queue;true;toString;();;Argument[-1];ReturnValue;taint",
"javax.jms;Topic;true;getTopicName;();;Argument[-1];ReturnValue;taint",
"javax.jms;Topic;true;toString;();;Argument[-1];ReturnValue;taint",
]
}
}
/** Defines additional sources of tainted data in JMS 2. */
private class Jms2Source extends SourceModelCsv {
override predicate row(string row) {
row =
[
"javax.jms;JMSConsumer;true;receive;;;ReturnValue;remote",
"javax.jms;JMSConsumer;true;receiveBody;;;ReturnValue;remote",
"javax.jms;JMSConsumer;true;receiveNoWait;();;ReturnValue;remote",
"javax.jms;JMSConsumer;true;receiveBodyNoWait;();;ReturnValue;remote",
]
}
}
/** Defines additional taint propagation steps in JMS 2. */
private class Jms2FlowStep extends SummaryModelCsv {
override predicate row(string row) {
row = "javax.jms;Message;true;getBody;();;Argument[-1];ReturnValue;taint"
}
}

View File

@@ -13,6 +13,10 @@ private class JavaIoSummaryCsv extends SummaryModelCsv {
"java.io;Writer;true;write;;;Argument[0];Argument[-1];taint",
"java.io;Writer;true;toString;;;Argument[-1];ReturnValue;taint",
"java.io;CharArrayWriter;true;toCharArray;;;Argument[-1];ReturnValue;taint",
"java.io;ObjectInput;true;read;;;Argument[-1];Argument[0];taint",
"java.io;DataInput;true;readFully;;;Argument[-1];Argument[0];taint",
"java.io;DataInput;true;readLine;();;Argument[-1];ReturnValue;taint",
"java.io;DataInput;true;readUTF;();;Argument[-1];ReturnValue;taint",
"java.nio.channels;ReadableByteChannel;true;read;(ByteBuffer);;Argument[-1];Argument[0];taint",
"java.nio.channels;Channels;false;newChannel;(InputStream);;Argument[0];ReturnValue;taint"
]

View File

@@ -0,0 +1,58 @@
/**
* Provides classes and predicates related to RabbitMQ.
*/
import java
private import semmle.code.java.dataflow.ExternalFlow
/**
* Defines remote sources in RabbitMQ.
*/
private class RabbitMQSource extends SourceModelCsv {
override predicate row(string row) {
row =
[
// soruces for RabbitMQ 4.x
"com.rabbitmq.client;Command;true;getContentHeader;();;ReturnValue;remote",
"com.rabbitmq.client;Command;true;getContentBody;();;ReturnValue;remote",
"com.rabbitmq.client;Consumer;true;handleDelivery;(String,Envelope,BasicProperties,byte[]);;Parameter[3];remote",
"com.rabbitmq.client;QueueingConsumer;true;nextDelivery;;;ReturnValue;remote",
"com.rabbitmq.client;RpcServer;true;handleCall;(Delivery,BasicProperties);;Parameter[0];remote",
"com.rabbitmq.client;RpcServer;true;handleCall;(BasicProperties,byte[],BasicProperties);;Parameter[1];remote",
"com.rabbitmq.client;RpcServer;true;handleCall;(byte[],BasicProperties);;Parameter[0];remote",
"com.rabbitmq.client;RpcServer;true;preprocessReplyProperties;(Delivery,Builder);;Parameter[0];remote",
"com.rabbitmq.client;RpcServer;true;postprocessReplyProperties;(Delivery,Builder);;Parameter[0];remote",
"com.rabbitmq.client;RpcServer;true;handleCast;(Delivery);;Parameter[0];remote",
"com.rabbitmq.client;RpcServer;true;handleCast;(BasicProperties,byte[]);;Parameter[1];remote",
"com.rabbitmq.client;RpcServer;true;handleCast;(byte[]);;Parameter[0];remote",
"com.rabbitmq.client;StringRpcServer;true;handleStringCall;;;Parameter[0];remote",
"com.rabbitmq.client;RpcClient;true;doCall;;;ReturnValue;remote",
"com.rabbitmq.client;RpcClient;true;primitiveCall;;;ReturnValue;remote",
"com.rabbitmq.client;RpcClient;true;responseCall;;;ReturnValue;remote",
"com.rabbitmq.client;RpcClient;true;stringCall;(String);;ReturnValue;remote",
"com.rabbitmq.client;RpcClient;true;mapCall;;;ReturnValue;remote",
"com.rabbitmq.client.impl;Frame;true;getInputStream;();;ReturnValue;remote",
"com.rabbitmq.client.impl;Frame;true;getPayload;();;ReturnValue;remote",
"com.rabbitmq.client.impl;FrameHandler;true;readFrame;();;ReturnValue;remote",
]
}
}
/**
* Defines flow steps in RabbitMQ.
*/
private class RabbitMQSummaryCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
// flow steps for RabbitMQ 4.x
"com.rabbitmq.client;GetResponse;true;GetResponse;;;Argument[2];Argument[-1];taint",
"com.rabbitmq.client;GetResponse;true;getBody;();;Argument[-1];ReturnValue;taint",
"com.rabbitmq.client;RpcClient$Response;true;getBody;();;Argument[-1];ReturnValue;taint",
"com.rabbitmq.client;QueueingConsumer$Delivery;true;getBody;();;Argument[-1];ReturnValue;taint",
"com.rabbitmq.client.impl;Frame;false;fromBodyFragment;(int,byte[],int,int);;Argument[1];ReturnValue;taint",
"com.rabbitmq.client.impl;Frame;false;readFrom;(DataInputStream);;Argument[0];ReturnValue;taint",
"com.rabbitmq.client.impl;Frame;true;writeTo;(DataOutputStream);;Argument[-1];Argument[0];taint",
]
}
}