mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
Merge pull request #8765 from artem-smotrakov/cover-jms
Java: Add flow sources and steps for RabbitMQ and JMS
This commit is contained in:
6
java/ql/lib/change-notes/2022-04-17-jms.md
Normal file
6
java/ql/lib/change-notes/2022-04-17-jms.md
Normal 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.
|
||||
@@ -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) {
|
||||
|
||||
112
java/ql/lib/semmle/code/java/frameworks/JMS.qll
Normal file
112
java/ql/lib/semmle/code/java/frameworks/JMS.qll
Normal 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"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
]
|
||||
|
||||
58
java/ql/lib/semmle/code/java/frameworks/RabbitMQ.qll
Normal file
58
java/ql/lib/semmle/code/java/frameworks/RabbitMQ.qll
Normal 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",
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ class TestIO {
|
||||
sink(ByteStreams.newDataInput(btaint())); // $numTaintFlow=1
|
||||
sink(ByteStreams.newDataInput(btaint(), 0)); // $numTaintFlow=1
|
||||
sink(ByteStreams.newDataInput(btaint())); // $numTaintFlow=1
|
||||
sink(ByteStreams.newDataInput(btaint()).readLine()); // $ MISSING:numTaintFlow=1
|
||||
sink(ByteStreams.newDataInput(btaint()).readLine()); // $numTaintFlow=1
|
||||
sink(ByteStreams.newDataInput(new ByteArrayInputStream(btaint()))); // $numTaintFlow=1
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write(btaint());
|
||||
@@ -136,6 +136,6 @@ class TestIO {
|
||||
new CountingInputStream(itaint()).read(buf, 0, 42);
|
||||
sink(buf); // $numTaintFlow=1
|
||||
sink(new LittleEndianDataInputStream(itaint())); // $numTaintFlow=1
|
||||
sink(new LittleEndianDataInputStream(itaint()).readUTF()); // $ MISSING:numTaintFlow=1
|
||||
sink(new LittleEndianDataInputStream(itaint()).readUTF()); // $numTaintFlow=1
|
||||
}
|
||||
}
|
||||
30
java/ql/test/library-tests/frameworks/jms/FlowTest.ql
Normal file
30
java/ql/test/library-tests/frameworks/jms/FlowTest.ql
Normal file
@@ -0,0 +1,30 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class TestConfig extends TaintTracking::Configuration {
|
||||
TestConfig() { this = "TestConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(MethodAccess call |
|
||||
call.getMethod().hasName("sink") and call.getArgument(0) = sink.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class JmsFlowTest extends InlineExpectationsTest {
|
||||
JmsFlowTest() { this = "JmsFlowTest" }
|
||||
|
||||
override string getARelevantTag() { result = "tainted" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "tainted" and
|
||||
exists(DataFlow::PathNode source, DataFlow::PathNode sink, TestConfig conf |
|
||||
conf.hasFlowPath(source, sink)
|
||||
|
|
||||
location = sink.getNode().getLocation() and element = sink.getNode().toString() and value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import javax.jms.MessageListener;
|
||||
import javax.jms.TextMessage;
|
||||
import javax.jms.BytesMessage;
|
||||
import javax.jms.MapMessage;
|
||||
import javax.jms.ObjectMessage;
|
||||
import javax.jms.StreamMessage;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageConsumer;
|
||||
import javax.jms.QueueReceiver;
|
||||
import javax.jms.QueueRequestor;
|
||||
import javax.jms.TopicRequestor;
|
||||
|
||||
public class MessageListenerImpl implements MessageListener {
|
||||
|
||||
@Override
|
||||
public void onMessage(Message message) { // $source
|
||||
try {
|
||||
if (message instanceof TextMessage) {
|
||||
TextMessage textMessage = (TextMessage) message;
|
||||
String text = textMessage.getText();
|
||||
sink(text); // $tainted
|
||||
} else if (message instanceof BytesMessage) {
|
||||
BytesMessage bytesMessage = (BytesMessage) message;
|
||||
byte[] data = new byte[1024];
|
||||
bytesMessage.readBytes(data, 42);
|
||||
sink(new String(data)); // $tainted
|
||||
sink(bytesMessage.readUTF()); // $tainted
|
||||
} else if (message instanceof MapMessage) {
|
||||
MapMessage mapMessage = (MapMessage) message;
|
||||
sink(mapMessage.getString("data")); // $tainted
|
||||
sink(new String(mapMessage.getBytes("bytes"))); // $tainted
|
||||
} else if (message instanceof ObjectMessage) {
|
||||
ObjectMessage objectMessage = (ObjectMessage) message;
|
||||
sink((String) objectMessage.getObject()); // $tainted
|
||||
} else if (message instanceof StreamMessage) {
|
||||
StreamMessage streamMessage = (StreamMessage) message;
|
||||
byte[] data = new byte[1024];
|
||||
streamMessage.readBytes(data);
|
||||
sink(new String(data)); // $tainted
|
||||
sink(streamMessage.readString()); // $tainted
|
||||
sink((String) streamMessage.readObject()); // $tainted
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void readFromCounsumer(MessageConsumer consumer) throws Exception {
|
||||
TextMessage message = (TextMessage) consumer.receive(5000); // $source
|
||||
String text = message.getText();
|
||||
sink(text); // $tainted
|
||||
message = (TextMessage) consumer.receive(); // $source
|
||||
text = message.getText();
|
||||
sink(text); // $tainted
|
||||
message = (TextMessage) consumer.receiveNoWait(); // $source
|
||||
text = message.getText();
|
||||
sink(text); // $tainted
|
||||
}
|
||||
|
||||
public void readFromQueueRequestor(QueueRequestor requestor, Message message) throws Exception {
|
||||
TextMessage reply = (TextMessage) requestor.request(message); // $source
|
||||
String text = reply.getText();
|
||||
sink(text); // $tainted
|
||||
}
|
||||
|
||||
public void readFromTopicRequestor(TopicRequestor requestor, Message message) throws Exception {
|
||||
TextMessage reply = (TextMessage) requestor.request(message); // $source
|
||||
String text = reply.getText();
|
||||
sink(text); // $tainted
|
||||
}
|
||||
|
||||
private void sink(String data) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class JmsRemoteSourcesTest extends InlineExpectationsTest {
|
||||
JmsRemoteSourcesTest() { this = "JmsRemoteSourcesTest" }
|
||||
|
||||
override string getARelevantTag() { result = "source" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "source" and
|
||||
exists(RemoteFlowSource source |
|
||||
location = source.getLocation() and element = source.toString() and value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
1
java/ql/test/library-tests/frameworks/jms/options
Normal file
1
java/ql/test/library-tests/frameworks/jms/options
Normal file
@@ -0,0 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/jms-api-1
|
||||
20
java/ql/test/library-tests/frameworks/rabbitmq/FlowTest.ql
Normal file
20
java/ql/test/library-tests/frameworks/rabbitmq/FlowTest.ql
Normal file
@@ -0,0 +1,20 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import TestUtilities.InlineFlowTest
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "qltest:frameworks:rabbitmq" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node) { node instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node node) {
|
||||
exists(MethodAccess ma | ma.getMethod().hasName("sink") | node.asExpr() = ma.getAnArgument())
|
||||
}
|
||||
}
|
||||
|
||||
class HasFlowTest extends InlineFlowTest {
|
||||
override DataFlow::Configuration getValueFlowConfig() { none() }
|
||||
|
||||
override DataFlow::Configuration getTaintFlowConfig() { result = any(Conf c) }
|
||||
}
|
||||
19
java/ql/test/library-tests/frameworks/rabbitmq/SourceTest.ql
Normal file
19
java/ql/test/library-tests/frameworks/rabbitmq/SourceTest.ql
Normal file
@@ -0,0 +1,19 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class SourceTest extends InlineExpectationsTest {
|
||||
SourceTest() { this = "SourceTest" }
|
||||
|
||||
override string getARelevantTag() { result = "source" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "source" and
|
||||
exists(RemoteFlowSource source |
|
||||
not source.asParameter().getCallable().getDeclaringType().hasName("DefaultConsumer") and
|
||||
source.getLocation() = location and
|
||||
element = source.toString() and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
34
java/ql/test/library-tests/frameworks/rabbitmq/Test.java
Normal file
34
java/ql/test/library-tests/frameworks/rabbitmq/Test.java
Normal file
@@ -0,0 +1,34 @@
|
||||
import com.rabbitmq.client.DefaultConsumer;
|
||||
import com.rabbitmq.client.Channel;
|
||||
import com.rabbitmq.client.AMQP;
|
||||
import com.rabbitmq.client.Envelope;
|
||||
import com.rabbitmq.client.QueueingConsumer;
|
||||
|
||||
public class Test {
|
||||
|
||||
public void defaultConsumerTest(Channel channel) {
|
||||
DefaultConsumer consumer = new DefaultConsumer(channel) {
|
||||
|
||||
@Override
|
||||
public void handleDelivery(
|
||||
String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
|
||||
byte[] body) { // $source
|
||||
|
||||
sink(body); // $hasTaintFlow
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void queueingConsumerTest(QueueingConsumer consumer) {
|
||||
while (true) {
|
||||
QueueingConsumer.Delivery delivery = consumer.nextDelivery(); // $source
|
||||
sink(delivery.getBody()); // $hasTaintFlow
|
||||
delivery = consumer.nextDelivery(42); // $source
|
||||
sink(delivery.getBody()); // $hasTaintFlow
|
||||
}
|
||||
}
|
||||
|
||||
private void sink(byte[] data) {
|
||||
|
||||
}
|
||||
}
|
||||
1
java/ql/test/library-tests/frameworks/rabbitmq/options
Normal file
1
java/ql/test/library-tests/frameworks/rabbitmq/options
Normal file
@@ -0,0 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/rabbitmq-4.12.0
|
||||
9
java/ql/test/stubs/jms-api-1/javax/jms/BytesMessage.java
generated
Normal file
9
java/ql/test/stubs/jms-api-1/javax/jms/BytesMessage.java
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
package javax.jms;
|
||||
|
||||
public interface BytesMessage extends Message {
|
||||
int readBytes(byte[] value);
|
||||
|
||||
int readBytes(byte[] value, int length);
|
||||
|
||||
String readUTF();
|
||||
}
|
||||
7
java/ql/test/stubs/jms-api-1/javax/jms/MapMessage.java
generated
Normal file
7
java/ql/test/stubs/jms-api-1/javax/jms/MapMessage.java
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
package javax.jms;
|
||||
|
||||
public interface MapMessage extends Message {
|
||||
byte[] getBytes(String name);
|
||||
|
||||
String getString(String name);
|
||||
}
|
||||
5
java/ql/test/stubs/jms-api-1/javax/jms/Message.java
generated
Normal file
5
java/ql/test/stubs/jms-api-1/javax/jms/Message.java
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
package javax.jms;
|
||||
|
||||
public interface Message {
|
||||
|
||||
}
|
||||
9
java/ql/test/stubs/jms-api-1/javax/jms/MessageConsumer.java
generated
Normal file
9
java/ql/test/stubs/jms-api-1/javax/jms/MessageConsumer.java
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
package javax.jms;
|
||||
|
||||
public interface MessageConsumer {
|
||||
Message receive();
|
||||
|
||||
Message receive(long timeout);
|
||||
|
||||
Message receiveNoWait();
|
||||
}
|
||||
5
java/ql/test/stubs/jms-api-1/javax/jms/MessageListener.java
generated
Normal file
5
java/ql/test/stubs/jms-api-1/javax/jms/MessageListener.java
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
package javax.jms;
|
||||
|
||||
public interface MessageListener {
|
||||
void onMessage(Message message);
|
||||
}
|
||||
5
java/ql/test/stubs/jms-api-1/javax/jms/ObjectMessage.java
generated
Normal file
5
java/ql/test/stubs/jms-api-1/javax/jms/ObjectMessage.java
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
package javax.jms;
|
||||
|
||||
public interface ObjectMessage extends Message {
|
||||
java.io.Serializable getObject();
|
||||
}
|
||||
5
java/ql/test/stubs/jms-api-1/javax/jms/QueueReceiver.java
generated
Normal file
5
java/ql/test/stubs/jms-api-1/javax/jms/QueueReceiver.java
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
package javax.jms;
|
||||
|
||||
public interface QueueReceiver {
|
||||
|
||||
}
|
||||
7
java/ql/test/stubs/jms-api-1/javax/jms/QueueRequestor.java
generated
Normal file
7
java/ql/test/stubs/jms-api-1/javax/jms/QueueRequestor.java
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
package javax.jms;
|
||||
|
||||
public class QueueRequestor {
|
||||
public Message request(Message message) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
9
java/ql/test/stubs/jms-api-1/javax/jms/StreamMessage.java
generated
Normal file
9
java/ql/test/stubs/jms-api-1/javax/jms/StreamMessage.java
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
package javax.jms;
|
||||
|
||||
public interface StreamMessage extends Message {
|
||||
int readBytes(byte[] value);
|
||||
|
||||
String readString();
|
||||
|
||||
Object readObject();
|
||||
}
|
||||
5
java/ql/test/stubs/jms-api-1/javax/jms/TextMessage.java
generated
Normal file
5
java/ql/test/stubs/jms-api-1/javax/jms/TextMessage.java
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
package javax.jms;
|
||||
|
||||
public interface TextMessage extends Message {
|
||||
String getText();
|
||||
}
|
||||
7
java/ql/test/stubs/jms-api-1/javax/jms/TopicRequestor.java
generated
Normal file
7
java/ql/test/stubs/jms-api-1/javax/jms/TopicRequestor.java
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
package javax.jms;
|
||||
|
||||
public class TopicRequestor {
|
||||
public Message request(Message message) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
8
java/ql/test/stubs/rabbitmq-4.12.0/com/rabbitmq/client/AMQP.java
generated
Normal file
8
java/ql/test/stubs/rabbitmq-4.12.0/com/rabbitmq/client/AMQP.java
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
package com.rabbitmq.client;
|
||||
|
||||
public class AMQP {
|
||||
|
||||
public static class BasicProperties {
|
||||
|
||||
}
|
||||
}
|
||||
5
java/ql/test/stubs/rabbitmq-4.12.0/com/rabbitmq/client/Channel.java
generated
Normal file
5
java/ql/test/stubs/rabbitmq-4.12.0/com/rabbitmq/client/Channel.java
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
package com.rabbitmq.client;
|
||||
|
||||
public interface Channel {
|
||||
|
||||
}
|
||||
8
java/ql/test/stubs/rabbitmq-4.12.0/com/rabbitmq/client/Consumer.java
generated
Normal file
8
java/ql/test/stubs/rabbitmq-4.12.0/com/rabbitmq/client/Consumer.java
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
package com.rabbitmq.client;
|
||||
|
||||
import java.io.IOException;;
|
||||
|
||||
public interface Consumer {
|
||||
void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
|
||||
throws IOException;
|
||||
}
|
||||
15
java/ql/test/stubs/rabbitmq-4.12.0/com/rabbitmq/client/DefaultConsumer.java
generated
Normal file
15
java/ql/test/stubs/rabbitmq-4.12.0/com/rabbitmq/client/DefaultConsumer.java
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
package com.rabbitmq.client;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DefaultConsumer implements Consumer {
|
||||
|
||||
public DefaultConsumer(Channel channel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
|
||||
throws IOException {
|
||||
}
|
||||
}
|
||||
5
java/ql/test/stubs/rabbitmq-4.12.0/com/rabbitmq/client/Envelope.java
generated
Normal file
5
java/ql/test/stubs/rabbitmq-4.12.0/com/rabbitmq/client/Envelope.java
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
package com.rabbitmq.client;
|
||||
|
||||
public class Envelope {
|
||||
|
||||
}
|
||||
23
java/ql/test/stubs/rabbitmq-4.12.0/com/rabbitmq/client/QueueingConsumer.java
generated
Normal file
23
java/ql/test/stubs/rabbitmq-4.12.0/com/rabbitmq/client/QueueingConsumer.java
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
package com.rabbitmq.client;
|
||||
|
||||
public class QueueingConsumer extends DefaultConsumer {
|
||||
|
||||
public QueueingConsumer(Channel channel) {
|
||||
super(channel);
|
||||
}
|
||||
|
||||
public Delivery nextDelivery() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Delivery nextDelivery(long timeout) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class Delivery {
|
||||
|
||||
public byte[] getBody() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user