Skip to content

Commit 9518182

Browse files
committed
Ratpack improve support for parsing types
1 parent 99bae51 commit 9518182

File tree

4 files changed

+200
-2
lines changed

4 files changed

+200
-2
lines changed

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

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,22 @@ private class RatpackHttpSource extends SourceModelCsv {
2424
"Request;true;getRawUri;;;ReturnValue;remote", "Request;true;getUri;;;ReturnValue;remote",
2525
"Request;true;getBody;;;ReturnValue;remote"
2626
]
27+
or
28+
// All Context#parse methods that return a Promise are remote flow sources.
29+
row =
30+
["ratpack.handling;", "ratpack.core.handling;"] + "Context;true;parse;" +
31+
[
32+
"(java.lang.Class);", "(com.google.common.reflect.TypeToken);", "(java.lang.Class,O);",
33+
"(com.google.common.reflect.TypeToken,O);", "(ratpack.core.parse.Parse);",
34+
"(ratpack.parse.Parse);"
35+
] + ";ReturnValue;remote"
2736
}
2837
}
2938

3039
/**
3140
* Ratpack methods that propagate user-supplied request data as tainted.
3241
*/
33-
private class RatpackHttpModel extends SummaryModelCsv {
42+
private class RatpackModel extends SummaryModelCsv {
3443
override predicate row(string row) {
3544
row =
3645
["ratpack.http;", "ratpack.core.http;"] +
@@ -49,6 +58,24 @@ private class RatpackHttpModel extends SummaryModelCsv {
4958
or
5059
row =
5160
["ratpack.form;", "ratpack.core.form;"] +
52-
["UploadedFile;true;getFileName;;;Argument[-1];ReturnValue;taint"]
61+
[
62+
"UploadedFile;true;getFileName;;;Argument[-1];ReturnValue;taint",
63+
"Form;true;file;;;Argument[-1];ReturnValue;taint",
64+
"Form;true;files;;;Argument[-1];ReturnValue;taint"
65+
]
66+
or
67+
row =
68+
["ratpack.handling;", "ratpack.core.handling;"] +
69+
[
70+
"Context;true;parse;(ratpack.http.TypedData,ratpack.parse.Parse);;Argument[0];ReturnValue;taint",
71+
"Context;true;parse;(ratpack.core.http.TypedData,ratpack.core.parse.Parse);;Argument[0];ReturnValue;taint"
72+
]
73+
or
74+
row =
75+
["ratpack.util;", "ratpack.func;"] +
76+
[
77+
"MultiValueMap;true;getAll;;;Argument[-1];ReturnValue;taint",
78+
"MultiValueMap;true;asMultimap;;;Argument[-1];ReturnValue;taint"
79+
]
5380
}
5481
}

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import ratpack.core.handling.Context;
22
import ratpack.core.http.TypedData;
3+
import ratpack.core.form.Form;
34
import ratpack.core.form.UploadedFile;
5+
import ratpack.core.parse.Parse;
46
import ratpack.exec.Promise;
57
import java.io.OutputStream;
68

@@ -67,4 +69,36 @@ void test4() {
6769
.flatMap(a -> Promise.value(a))
6870
.then(this::sink); //$hasTaintFlow
6971
}
72+
73+
void test5(Context ctx) {
74+
ctx
75+
.getRequest()
76+
.getBody()
77+
.map(data -> {
78+
Form form = ctx.parse(data, Form.form());
79+
sink(form); //$hasTaintFlow
80+
return form;
81+
})
82+
.then(form -> {
83+
sink(form.file("questionable_file")); //$hasTaintFlow
84+
sink(form.file("questionable_file").getFileName()); //$hasTaintFlow
85+
sink(form.files("questionable_files")); //$hasTaintFlow
86+
sink(form.files()); //$hasTaintFlow
87+
sink(form.asMultimap()); //$hasTaintFlow
88+
sink(form.asMultimap().asMap()); //$hasTaintFlow
89+
});
90+
}
91+
92+
void test6(Context ctx) {
93+
ctx
94+
.parse(Parse.of(Form.class))
95+
.then(form -> {
96+
sink(form); //$hasTaintFlow
97+
});
98+
ctx
99+
.parse(Form.class)
100+
.then(form -> {
101+
sink(form); //$hasTaintFlow
102+
});
103+
}
70104
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright 2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package ratpack.core.form;
18+
19+
import ratpack.core.handling.Context;
20+
import ratpack.core.parse.Parse;
21+
import ratpack.func.Nullable;
22+
import ratpack.func.MultiValueMap;
23+
24+
import java.util.List;
25+
26+
/**
27+
* An uploaded form.
28+
* <p>
29+
* The form is modelled as a {@link MultiValueMap}, with extra methods for dealing with file uploads.
30+
* That is, uploaded files are not visible via the methods provided by {@link MultiValueMap}.
31+
* <p>
32+
* All instances of this type are <b>immutable</b>.
33+
* Calling any mutative method of {@link MultiValueMap} will result in an {@link UnsupportedOperationException}.
34+
* <h3>Example usage:</h3>
35+
* <pre class="java">{@code
36+
* import ratpack.core.handling.Handler;
37+
* import ratpack.core.handling.Context;
38+
* import ratpack.core.form.Form;
39+
* import ratpack.core.form.UploadedFile;
40+
*
41+
* import java.util.List;
42+
*
43+
* public class Example {
44+
* public static class FormHandler implements Handler {
45+
* public void handle(Context context) throws Exception {
46+
* context.parse(Form.class).then(form -> {
47+
* UploadedFile file = form.file("someFile.txt");
48+
* String param = form.get("param");
49+
* List<String> multi = form.getAll("multi");
50+
* context.render("form uploaded!");
51+
* });
52+
* }
53+
* }
54+
* }
55+
* }</pre>
56+
*
57+
* <p>
58+
* To include the query parameters from the request in the parsed form, use {@link Form#form(boolean)}.
59+
* This can be useful if you want to support both {@code GET} and {@code PUT} submission with a single handler.
60+
*/
61+
public interface Form extends MultiValueMap<String, String> {
62+
63+
/**
64+
* Return the first uploaded file with the given name.
65+
*
66+
* @param name The name of the uploaded file in the form
67+
* @return The uploaded file, or {@code null} if no file was uploaded by that name
68+
*/
69+
@Nullable
70+
UploadedFile file(String name);
71+
72+
/**
73+
* Return all of the uploaded files with the given name.
74+
*
75+
* @param name The name of the uploaded files in the form
76+
* @return The uploaded files, or an empty list if no files were uploaded by that name
77+
*/
78+
List<UploadedFile> files(String name);
79+
80+
/**
81+
* Returns all of the uploaded files.
82+
*
83+
* @return all of the uploaded files.
84+
*/
85+
MultiValueMap<String, UploadedFile> files();
86+
87+
/**
88+
* Creates a {@link Context#parse parseable object} to parse a request body into a {@link Form}.
89+
* <p>
90+
* Default options will be used (no query parameters included).
91+
*
92+
* @return a parse object
93+
*/
94+
static Parse<Form, FormParseOpts> form() {
95+
return null;
96+
}
97+
98+
/**
99+
* Creates a {@link Context#parse parseable object} to parse a request body into a {@link Form}.
100+
*
101+
* @param includeQueryParams whether to include the query parameters from the request in the parsed form
102+
* @return a parse object
103+
*/
104+
static Parse<Form, FormParseOpts> form(boolean includeQueryParams) {
105+
return null;
106+
}
107+
108+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package ratpack.core.form;
18+
19+
/**
20+
* Options for parsing a {@link Form}.
21+
*/
22+
public interface FormParseOpts {
23+
/**
24+
* Whether to include the query parameters from the request in the parsed form.
25+
*
26+
* @return whether to include the query parameters from the request in the parsed form
27+
*/
28+
boolean isIncludeQueryParams();
29+
}

0 commit comments

Comments
 (0)