Skip to content

Commit 7510ca1

Browse files
committed
Refactor Ratpack to use CSV format
1 parent 1ac510a commit 7510ca1

File tree

4 files changed

+59
-123
lines changed

4 files changed

+59
-123
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ private module Frameworks {
7777
private import semmle.code.java.frameworks.ApacheHttp
7878
private import semmle.code.java.frameworks.apache.Lang
7979
private import semmle.code.java.frameworks.guava.Guava
80+
private import semmle.code.java.frameworks.ratpack.Ratpack
8081
private import semmle.code.java.security.ResponseSplitting
8182
private import semmle.code.java.security.XSS
8283
private import semmle.code.java.security.LdapInjection

java/ql/src/semmle/code/java/dataflow/FlowSources.qll

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -114,25 +114,6 @@ private class PlayParameterSource extends RemoteFlowSource {
114114
override string getSourceType() { result = "Play Query Parameters" }
115115
}
116116

117-
private class RatpackHttpMethodSource extends RemoteFlowSource {
118-
RatpackHttpMethodSource() {
119-
this.asExpr().(MethodAccess).getMethod() instanceof RatpackGetRequestDataMethod
120-
}
121-
122-
override string getSourceType() { result = "Ratpack request method" }
123-
}
124-
125-
private class RatpackHttpStreamSource extends RemoteFlowSource {
126-
RatpackHttpStreamSource() {
127-
exists(MethodAccess ma |
128-
ma.getMethod() instanceof RatpackHttpTypedDataWriteMethod and
129-
ma.getArgument(0) = this.asExpr()
130-
)
131-
}
132-
133-
override string getSourceType() { result = "Ratpack request stream" }
134-
}
135-
136117
private class SpringServletInputParameterSource extends RemoteFlowSource {
137118
SpringServletInputParameterSource() {
138119
this.asParameter() = any(SpringRequestMappingParameter srmp | srmp.isTaintedInput())

java/ql/src/semmle/code/java/frameworks/ratpack/Ratpack.qll

Lines changed: 41 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -5,97 +5,52 @@
55
import java
66
private import semmle.code.java.dataflow.DataFlow
77
private import semmle.code.java.dataflow.FlowSteps
8+
private import semmle.code.java.dataflow.ExternalFlow
89

910
/**
1011
* Ratpack methods that access user-supplied request data.
1112
*/
1213
abstract class RatpackGetRequestDataMethod extends Method { }
1314

14-
/**
15-
* The interface `ratpack.http.Request`.
16-
* https://ratpack.io/manual/current/api/ratpack/http/Request.html
17-
*/
18-
class RatpackRequest extends RefType {
19-
RatpackRequest() {
20-
hasQualifiedName("ratpack.http", "Request") or
21-
hasQualifiedName("ratpack.core.http", "Request")
22-
}
23-
}
24-
25-
/**
26-
* Methods on `ratpack.http.Request` that return user tainted data.
27-
*/
28-
class RatpackHttpRequestGetMethod extends RatpackGetRequestDataMethod {
29-
RatpackHttpRequestGetMethod() {
30-
getDeclaringType() instanceof RatpackRequest and
31-
hasName([
32-
"getContentLength", "getCookies", "oneCookie", "getHeaders", "getPath", "getQuery",
33-
"getQueryParams", "getRawUri", "getUri"
34-
])
15+
private class RatpackHttpSource extends SourceModelCsv {
16+
override predicate row(string row) {
17+
row =
18+
["ratpack.http;", "ratpack.core.http;"] +
19+
[
20+
"Request;true;getContentLength;;;ReturnValue;remote",
21+
"Request;true;getCookies;;;ReturnValue;remote",
22+
"Request;true;oneCookie;;;ReturnValue;remote",
23+
"Request;true;getHeaders;;;ReturnValue;remote",
24+
"Request;true;getPath;;;ReturnValue;remote", "Request;true;getQuery;;;ReturnValue;remote",
25+
"Request;true;getQueryParams;;;ReturnValue;remote",
26+
"Request;true;getRawUri;;;ReturnValue;remote", "Request;true;getUri;;;ReturnValue;remote",
27+
"Request;true;getBody;;;ReturnValue;remote"
28+
]
29+
}
30+
}
31+
32+
/**
33+
* Ratpack methods that propagate user-supplied request data as tainted.
34+
*/
35+
private class RatpackHttpModel extends SummaryModelCsv {
36+
override predicate row(string row) {
37+
row =
38+
["ratpack.http;", "ratpack.core.http;"] +
39+
[
40+
"TypedData;true;getBuffer;;;Argument[-1];ReturnValue;taint",
41+
"TypedData;true;getBytes;;;Argument[-1];ReturnValue;taint",
42+
"TypedData;true;getContentType;;;Argument[-1];ReturnValue;taint",
43+
"TypedData;true;getInputStream;;;Argument[-1];ReturnValue;taint",
44+
"TypedData;true;getText;;;Argument[-1];ReturnValue;taint",
45+
"TypedData;true;writeTo;;;Argument[-1];Argument[0];taint",
46+
"Headers;true;get;;;Argument[-1];ReturnValue;taint",
47+
"Headers;true;getAll;;;Argument[-1];ReturnValue;taint",
48+
"Headers;true;getNames;;;Argument[-1];ReturnValue;taint",
49+
"Headers;true;asMultiValueMap;;;Argument[-1];ReturnValue;taint"
50+
]
51+
or
52+
row =
53+
["ratpack.form;", "ratpack.core.form;"] +
54+
["UploadedFile;true;getFileName;;;Argument[-1];ReturnValue;taint"]
3555
}
3656
}
37-
38-
/**
39-
* The interface `ratpack.http.TypedData`.
40-
* https://ratpack.io/manual/current/api/ratpack/http/TypedData.html
41-
*/
42-
class RatpackTypedData extends RefType {
43-
RatpackTypedData() {
44-
hasQualifiedName("ratpack.http", "TypedData") or
45-
hasQualifiedName("ratpack.core.http", "TypedData")
46-
}
47-
}
48-
49-
/**
50-
* Methods on `ratpack.http.TypedData` that return user tainted data.
51-
*/
52-
class RatpackHttpTypedDataGetMethod extends RatpackGetRequestDataMethod {
53-
RatpackHttpTypedDataGetMethod() {
54-
getDeclaringType() instanceof RatpackTypedData and
55-
hasName(["getBuffer", "getBytes", "getContentType", "getInputStream", "getText"])
56-
}
57-
}
58-
59-
/**
60-
* Methods on `ratpack.http.TypedData` that taint the parameter passed in.
61-
*/
62-
class RatpackHttpTypedDataWriteMethod extends Method {
63-
RatpackHttpTypedDataWriteMethod() {
64-
getDeclaringType() instanceof RatpackTypedData and
65-
hasName("writeTo")
66-
}
67-
}
68-
69-
/**
70-
* The interface `ratpack.form.UploadedFile`.
71-
* https://ratpack.io/manual/current/api/ratpack/form/UploadedFile.html
72-
*/
73-
class RatpackUploadFile extends RefType {
74-
RatpackUploadFile() {
75-
hasQualifiedName("ratpack.form", "UploadedFile") or
76-
hasQualifiedName("ratpack.core.form", "UploadedFile")
77-
}
78-
}
79-
80-
class RatpackUploadFileGetMethod extends RatpackGetRequestDataMethod {
81-
RatpackUploadFileGetMethod() {
82-
getDeclaringType() instanceof RatpackUploadFile and
83-
hasName("getFileName")
84-
}
85-
}
86-
87-
class RatpackHeader extends RefType {
88-
RatpackHeader() {
89-
hasQualifiedName("ratpack.http", "Headers") or
90-
hasQualifiedName("ratpack.core.http", "Headers")
91-
}
92-
}
93-
94-
private class RatpackHeaderTaintPropagatingMethod extends Method, TaintPreservingCallable {
95-
RatpackHeaderTaintPropigatingMethod() {
96-
getDeclaringType() instanceof RatpackHeader and
97-
hasName(["get", "getAll", "getNames", "asMultiValueMap"])
98-
}
99-
100-
override predicate returnsTaintFrom(int arg) { arg = -1 }
101-
}

java/ql/test/library-tests/frameworks/ratpack/resources/Resource.java

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,25 +30,24 @@ void test1(Context ctx) {
3030
sink(ctx.getRequest().getUri()); //$hasTaintFlow
3131
}
3232

33-
void test2(TypedData td) {
34-
sink(td.getText()); //$hasTaintFlow
35-
sink(td.getBuffer()); //$hasTaintFlow
36-
sink(td.getBytes()); //$hasTaintFlow
37-
sink(td.getContentType()); //$hasTaintFlow
38-
sink(td.getInputStream()); //$hasTaintFlow
33+
void test2(Context ctx, OutputStream os) {
34+
ctx.getRequest().getBody().then(td -> {
35+
sink(td.getText()); //$hasTaintFlow
36+
sink(td.getBuffer()); //$hasTaintFlow
37+
sink(td.getBytes()); //$hasTaintFlow
38+
sink(td.getContentType()); //$hasTaintFlow
39+
sink(td.getInputStream()); //$hasTaintFlow
40+
sink(os);
41+
td.writeTo(os);
42+
sink(os); //$hasTaintFlow
43+
if (td instanceof UploadedFile) {
44+
UploadedFile uf = (UploadedFile) td;
45+
sink(uf.getFileName()); //$hasTaintFlow
46+
}
47+
});
3948
}
4049

41-
void test3(TypedData td, OutputStream os) throws java.io.IOException {
42-
sink(os);
43-
td.writeTo(os);
44-
sink(os); //$hasTaintFlow
45-
}
46-
47-
void test4(UploadedFile uf) {
48-
sink(uf.getFileName()); //$hasTaintFlow
49-
}
50-
51-
void test5(Context ctx) {
50+
void test3(Context ctx) {
5251
sink(ctx.getRequest().getBody().map(TypedData::getText)); //$hasTaintFlow
5352
ctx.getRequest().getBody().map(TypedData::getText).then(this::sink); //$hasTaintFlow
5453
ctx
@@ -59,7 +58,7 @@ void test5(Context ctx) {
5958
.then(this::sink); //$hasTaintFlow
6059
}
6160

62-
void test6() {
61+
void test4() {
6362
String tainted = taint();
6463
Promise.value(tainted);
6564
sink(Promise.value(tainted)); //$hasTaintFlow

0 commit comments

Comments
 (0)