Skip to content

Commit 269143a

Browse files
artem-smotrakovsmowton
authored andcommitted
Java: Added sources and flow steps for RabbitMQ
1 parent fb39e0f commit 269143a

File tree

15 files changed

+198
-0
lines changed

15 files changed

+198
-0
lines changed

java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ private module Frameworks {
138138
private import semmle.code.java.frameworks.MyBatis
139139
private import semmle.code.java.frameworks.Hibernate
140140
private import semmle.code.java.frameworks.jOOQ
141+
private import semmle.code.java.frameworks.RabbitMQ
141142
}
142143

143144
private predicate sourceModelCsv(string row) {

java/ql/lib/semmle/code/java/dataflow/FlowSteps.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ private module Frameworks {
2121
private import semmle.code.java.frameworks.guava.Guava
2222
private import semmle.code.java.frameworks.apache.Lang
2323
private import semmle.code.java.frameworks.ApacheHttp
24+
private import semmle.code.java.frameworks.RabbitMQ
2425
}
2526

2627
/**
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* Provides classes and predicates related to RabbitMQ.
3+
*/
4+
5+
import java
6+
private import semmle.code.java.dataflow.ExternalFlow
7+
8+
/**
9+
* Defines remote sources in RabbitMQ.
10+
*/
11+
private class RabbitMQSource extends SourceModelCsv {
12+
override predicate row(string row) {
13+
row =
14+
[
15+
// soruces for RabbitMQ 4.x
16+
"com.rabbitmq.client;Command;true;getContentHeader;();;ReturnValue;remote",
17+
"com.rabbitmq.client;Command;true;getContentBody;();;ReturnValue;remote",
18+
"com.rabbitmq.client;Consumer;true;handleDelivery;(String,Envelope,BasicProperties,byte[]);;Parameter[3];remote",
19+
"com.rabbitmq.client;QueueingConsumer;true;nextDelivery;;;ReturnValue;remote",
20+
"com.rabbitmq.client;RpcServer;true;handleCall;(Delivery,BasicProperties);;Parameter[0];remote",
21+
"com.rabbitmq.client;RpcServer;true;handleCall;(BasicProperties,byte[],BasicProperties);;Parameter[1];remote",
22+
"com.rabbitmq.client;RpcServer;true;handleCall;(byte[],BasicProperties);;Parameter[0];remote",
23+
"com.rabbitmq.client;RpcServer;true;preprocessReplyProperties;(Delivery,Builder);;Parameter[0];remote",
24+
"com.rabbitmq.client;RpcServer;true;postprocessReplyProperties;(Delivery,Builder);;Parameter[0];remote",
25+
"com.rabbitmq.client;RpcServer;true;handleCast;(Delivery);;Parameter[0];remote",
26+
"com.rabbitmq.client;RpcServer;true;handleCast;(BasicProperties,byte[]);;Parameter[1];remote",
27+
"com.rabbitmq.client;RpcServer;true;handleCast;(byte[]);;Parameter[0];remote",
28+
"com.rabbitmq.client;StringRpcServer;true;handleStringCall;;;Parameter[0];remote",
29+
"com.rabbitmq.client;RpcClient;true;doCall;;;ReturnValue;remote",
30+
"com.rabbitmq.client;RpcClient;true;primitiveCall;;;ReturnValue;remote",
31+
"com.rabbitmq.client;RpcClient;true;responseCall;;;ReturnValue;remote",
32+
"com.rabbitmq.client;RpcClient;true;stringCall;(String);;ReturnValue;remote",
33+
"com.rabbitmq.client;RpcClient;true;mapCall;;;ReturnValue;remote",
34+
"com.rabbitmq.client.impl;Frame;true;getInputStream;();;ReturnValue;remote",
35+
"com.rabbitmq.client.impl;Frame;true;getPayload;();;ReturnValue;remote",
36+
"com.rabbitmq.client.impl;FrameHandler;true;readFrame;();;ReturnValue;remote",
37+
]
38+
}
39+
}
40+
41+
/**
42+
* Defines flow steps in RabbitMQ.
43+
*/
44+
private class RabbitMQSummaryCsv extends SummaryModelCsv {
45+
override predicate row(string row) {
46+
row =
47+
[
48+
// flow steps for RabbitMQ 4.x
49+
"com.rabbitmq.client;GetResponse;true;GetResponse;;;Argument[2];Argument[-1];taint",
50+
"com.rabbitmq.client;GetResponse;true;getBody;();;Argument[-1];ReturnValue;taint",
51+
"com.rabbitmq.client;RpcClient$Response;true;getBody;();;Argument[-1];ReturnValue;taint",
52+
"com.rabbitmq.client;QueueingConsumer$Delivery;true;getBody;();;Argument[-1];ReturnValue;taint",
53+
"com.rabbitmq.client.impl;Frame;false;fromBodyFragment;(int,byte[],int,int);;Argument[1];ReturnValue;taint",
54+
"com.rabbitmq.client.impl;Frame;false;readFrom;(DataInputStream);;Argument[0];ReturnValue;taint",
55+
"com.rabbitmq.client.impl;Frame;true;writeTo;(DataOutputStream);;Argument[-1];Argument[0];taint",
56+
]
57+
}
58+
}

java/ql/test/library-tests/rabbitmq/FlowTest.expected

Whitespace-only changes.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import java
2+
import semmle.code.java.dataflow.TaintTracking
3+
import semmle.code.java.dataflow.FlowSources
4+
import TestUtilities.InlineFlowTest
5+
6+
class Conf extends TaintTracking::Configuration {
7+
Conf() { this = "qltest:frameworks:rabbitmq" }
8+
9+
override predicate isSource(DataFlow::Node node) { node instanceof RemoteFlowSource }
10+
11+
override predicate isSink(DataFlow::Node node) {
12+
exists(MethodAccess ma | ma.getMethod().hasName("sink") | node.asExpr() = ma.getAnArgument())
13+
}
14+
}
15+
16+
class HasFlowTest extends InlineFlowTest {
17+
override DataFlow::Configuration getValueFlowConfig() { none() }
18+
19+
override DataFlow::Configuration getTaintFlowConfig() { result = any(Conf c) }
20+
}

java/ql/test/library-tests/rabbitmq/SourceTest.expected

Whitespace-only changes.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import java
2+
import semmle.code.java.dataflow.FlowSources
3+
import TestUtilities.InlineExpectationsTest
4+
5+
class SourceTest extends InlineExpectationsTest {
6+
SourceTest() { this = "SourceTest" }
7+
8+
override string getARelevantTag() { result = "source" }
9+
10+
override predicate hasActualResult(Location location, string element, string tag, string value) {
11+
tag = "source" and
12+
exists(RemoteFlowSource source |
13+
not source.asParameter().getCallable().getDeclaringType().hasName("DefaultConsumer") and
14+
source.getLocation() = location and
15+
element = source.toString() and
16+
value = ""
17+
)
18+
}
19+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import com.rabbitmq.client.DefaultConsumer;
2+
import com.rabbitmq.client.Channel;
3+
import com.rabbitmq.client.AMQP;
4+
import com.rabbitmq.client.Envelope;
5+
import com.rabbitmq.client.QueueingConsumer;
6+
7+
public class Test {
8+
9+
public void defaultConsumerTest(Channel channel) {
10+
DefaultConsumer consumer = new DefaultConsumer(channel) {
11+
12+
@Override
13+
public void handleDelivery(
14+
String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
15+
byte[] body) { // $source
16+
17+
sink(body); // $hasTaintFlow
18+
}
19+
};
20+
}
21+
22+
public void queueingConsumerTest(QueueingConsumer consumer) {
23+
while (true) {
24+
QueueingConsumer.Delivery delivery = consumer.nextDelivery(); // $source
25+
sink(delivery.getBody()); // $hasTaintFlow
26+
delivery = consumer.nextDelivery(42); // $source
27+
sink(delivery.getBody()); // $hasTaintFlow
28+
}
29+
}
30+
31+
private void sink(byte[] data) {
32+
33+
}
34+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//semmle-extractor-options: --javac-args -cp ${testdir}/../../stubs/rabbitmq-4.12.0

java/ql/test/stubs/rabbitmq-4.12.0/com/rabbitmq/client/AMQP.java

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)