Skip to content

Commit 6f302a4

Browse files
authored
Merge pull request github#13297 from atorralba/atorralba/java/playmvc-models
Java: Add models for the Play Framework
2 parents 2266e28 + 8e16a0d commit 6f302a4

File tree

15 files changed

+483
-53
lines changed

15 files changed

+483
-53
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added more dataflow models for the Play Framework.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/java-all
4+
extensible: sinkModel
5+
data:
6+
- ["play.libs.ws", "WSClient", True, "url", "", "", "Argument[0]", "open-url", "manual"]
7+
- ["play.libs.ws", "StandaloneWSClient", True, "url", "", "", "Argument[0]", "open-url", "manual"]

java/ql/lib/ext/play.mvc.model.yml

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,44 @@ extensions:
33
pack: codeql/java-all
44
extensible: sourceModel
55
data:
6-
- ["play.mvc", "Http$RequestHeader", False, "getHeader", "", "", "ReturnValue", "remote", "manual"]
7-
- ["play.mvc", "Http$RequestHeader", False, "getQueryString", "", "", "ReturnValue", "remote", "manual"]
8-
- ["play.mvc", "Http$RequestHeader", False, "header", "", "", "ReturnValue", "remote", "manual"]
9-
- ["play.mvc", "Http$RequestHeader", False, "queryString", "", "", "ReturnValue", "remote", "manual"]
6+
- ["play.mvc", "Http$Request", True, "body", "", "", "ReturnValue", "remote", "manual"]
7+
- ["play.mvc", "Http$RequestHeader", True, "cookie", "", "", "ReturnValue", "remote", "manual"]
8+
- ["play.mvc", "Http$RequestHeader", True, "cookies", "", "", "ReturnValue", "remote", "manual"]
9+
- ["play.mvc", "Http$RequestHeader", True, "getHeader", "", "", "ReturnValue", "remote", "manual"] # v2.4.x
10+
- ["play.mvc", "Http$RequestHeader", True, "getHeaders", "", "", "ReturnValue", "remote", "manual"] # v2.7.x
11+
- ["play.mvc", "Http$RequestHeader", True, "getQueryString", "", "", "ReturnValue", "remote", "manual"]
12+
- ["play.mvc", "Http$RequestHeader", True, "header", "", "", "ReturnValue", "remote", "manual"] # v2.7.x
13+
- ["play.mvc", "Http$RequestHeader", True, "headers", "", "", "ReturnValue", "remote", "manual"] # v2.4.x
14+
- ["play.mvc", "Http$RequestHeader", True, "host", "", "", "ReturnValue", "remote", "manual"]
15+
- ["play.mvc", "Http$RequestHeader", True, "path", "", "", "ReturnValue", "remote", "manual"]
16+
- ["play.mvc", "Http$RequestHeader", True, "queryString", "", "", "ReturnValue", "remote", "manual"]
17+
- ["play.mvc", "Http$RequestHeader", True, "remoteAddress", "", "", "ReturnValue", "remote", "manual"]
18+
- ["play.mvc", "Http$RequestHeader", True, "uri", "", "", "ReturnValue", "remote", "manual"]
19+
- addsTo:
20+
pack: codeql/java-all
21+
extensible: summaryModel
22+
data:
23+
- ["play.mvc", "Http$RequestBody", True, "as", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
24+
- ["play.mvc", "Http$RequestBody", True, "asBytes", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] # v2.7.x
25+
- ["play.mvc", "Http$RequestBody", True, "asFormUrlEncoded", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
26+
- ["play.mvc", "Http$RequestBody", True, "asJson", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
27+
- ["play.mvc", "Http$RequestBody", True, "asMultipartFormData", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
28+
- ["play.mvc", "Http$RequestBody", True, "asRaw", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
29+
- ["play.mvc", "Http$RequestBody", True, "asText", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
30+
- ["play.mvc", "Http$RequestBody", True, "asXml", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
31+
- ["play.mvc", "Http$RequestBody", True, "parseJson", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] # v2.7.x
32+
- ["play.mvc", "Http$MultipartFormData", True, "asFormUrlEncoded", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
33+
- ["play.mvc", "Http$MultipartFormData", True, "getFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
34+
- ["play.mvc", "Http$MultipartFormData", True, "getFiles", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
35+
- ["play.mvc", "Http$MultipartFormData$FilePart", True, "getContentType", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
36+
- ["play.mvc", "Http$MultipartFormData$FilePart", True, "getDispositionType", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] # v2.7.x
37+
- ["play.mvc", "Http$MultipartFormData$FilePart", True, "getFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] # v2.4.x
38+
- ["play.mvc", "Http$MultipartFormData$FilePart", True, "getFilename", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
39+
- ["play.mvc", "Http$MultipartFormData$FilePart", True, "getKey", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
40+
- ["play.mvc", "Http$MultipartFormData$FilePart", True, "getRef", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] # v2.7.x
41+
- ["play.mvc", "Http$RawBuffer", True, "asBytes", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
42+
- ["play.mvc", "Http$RawBuffer", True, "asFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
43+
- ["play.mvc", "Http$Cookie", True, "name", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
44+
- ["play.mvc", "Http$Cookie", True, "value", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
45+
- ["play.mvc", "Http$Cookies", True, "get", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
46+
- ["play.mvc", "Http$Cookies", True, "getCookie", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] # v2.7.x
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import play.mvc.Http;
2+
3+
public class PlayMvc {
4+
5+
private Http.Request request;
6+
private Http.RequestHeader header;
7+
8+
private static void sink(Object o) {}
9+
10+
public void test() throws Exception {
11+
sink(request.body()); // $ hasRemoteValueFlow
12+
sink(header.cookie(null)); // $ hasRemoteValueFlow
13+
sink(header.cookies()); // $ hasRemoteValueFlow
14+
sink(header.getHeader(null)); // $ hasRemoteValueFlow
15+
sink(header.getHeaders()); // $ hasRemoteValueFlow
16+
sink(header.getQueryString(null)); // $ hasRemoteValueFlow
17+
sink(header.header(null)); // $ hasRemoteValueFlow
18+
sink(header.headers()); // $ hasRemoteValueFlow
19+
sink(header.host()); // $ hasRemoteValueFlow
20+
sink(header.path()); // $ hasRemoteValueFlow
21+
sink(header.queryString()); // $ hasRemoteValueFlow
22+
sink(header.remoteAddress()); // $ hasRemoteValueFlow
23+
sink(header.uri()); // $ hasRemoteValueFlow
24+
}
25+
}
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
package generatedtest;
2+
3+
import akka.util.ByteString;
4+
import com.fasterxml.jackson.databind.JsonNode;
5+
import java.io.File;
6+
import java.util.List;
7+
import java.util.Map;
8+
import java.util.Optional;
9+
import org.w3c.dom.Document;
10+
import play.mvc.Http;
11+
12+
// Test case generated by GenerateFlowTestCase.ql
13+
public class Test {
14+
15+
Object source() {
16+
return null;
17+
}
18+
19+
void sink(Object o) {}
20+
21+
public void test() throws Exception {
22+
23+
{
24+
// "play.mvc;Http$Cookie;true;name;;;Argument[this];ReturnValue;taint;manual"
25+
String out = null;
26+
Http.Cookie in = (Http.Cookie) source();
27+
out = in.name();
28+
sink(out); // $ hasTaintFlow
29+
}
30+
{
31+
// "play.mvc;Http$Cookie;true;value;;;Argument[this];ReturnValue;taint;manual"
32+
String out = null;
33+
Http.Cookie in = (Http.Cookie) source();
34+
out = in.value();
35+
sink(out); // $ hasTaintFlow
36+
}
37+
{
38+
// "play.mvc;Http$Cookies;true;get;;;Argument[this];ReturnValue;taint;manual"
39+
Http.Cookie out = null;
40+
Http.Cookies in = (Http.Cookies) source();
41+
out = in.get(null);
42+
sink(out); // $ hasTaintFlow
43+
}
44+
{
45+
// "play.mvc;Http$Cookies;true;getCookie;;;Argument[this];ReturnValue;taint;manual"
46+
Optional out = null;
47+
Http.Cookies in = (Http.Cookies) source();
48+
out = in.getCookie(null);
49+
sink(out); // $ hasTaintFlow
50+
}
51+
{
52+
// "play.mvc;Http$MultipartFormData$FilePart;true;getContentType;;;Argument[this];ReturnValue;taint;manual"
53+
String out = null;
54+
Http.MultipartFormData.FilePart in = (Http.MultipartFormData.FilePart) source();
55+
out = in.getContentType();
56+
sink(out); // $ hasTaintFlow
57+
}
58+
{
59+
// "play.mvc;Http$MultipartFormData$FilePart;true;getDispositionType;;;Argument[this];ReturnValue;taint;manual"
60+
String out = null;
61+
Http.MultipartFormData.FilePart in = (Http.MultipartFormData.FilePart) source();
62+
out = in.getDispositionType();
63+
sink(out); // $ hasTaintFlow
64+
}
65+
{
66+
// "play.mvc;Http$MultipartFormData$FilePart;true;getFilename;;;Argument[this];ReturnValue;taint;manual"
67+
String out = null;
68+
Http.MultipartFormData.FilePart in = (Http.MultipartFormData.FilePart) source();
69+
out = in.getFilename();
70+
sink(out); // $ hasTaintFlow
71+
}
72+
{
73+
// "play.mvc;Http$MultipartFormData$FilePart;true;getKey;;;Argument[this];ReturnValue;taint;manual"
74+
String out = null;
75+
Http.MultipartFormData.FilePart in = (Http.MultipartFormData.FilePart) source();
76+
out = in.getKey();
77+
sink(out); // $ hasTaintFlow
78+
}
79+
{
80+
// "play.mvc;Http$MultipartFormData$FilePart;true;getRef;;;Argument[this];ReturnValue;taint;manual"
81+
Object out = null;
82+
Http.MultipartFormData.FilePart in = (Http.MultipartFormData.FilePart) source();
83+
out = in.getRef();
84+
sink(out); // $ hasTaintFlow
85+
}
86+
{
87+
// "play.mvc;Http$MultipartFormData;true;asFormUrlEncoded;;;Argument[this];ReturnValue;taint;manual"
88+
Map out = null;
89+
Http.MultipartFormData in = (Http.MultipartFormData) source();
90+
out = in.asFormUrlEncoded();
91+
sink(out); // $ hasTaintFlow
92+
}
93+
{
94+
// "play.mvc;Http$MultipartFormData;true;getFile;;;Argument[this];ReturnValue;taint;manual"
95+
Http.MultipartFormData.FilePart out = null;
96+
Http.MultipartFormData in = (Http.MultipartFormData) source();
97+
out = in.getFile(null);
98+
sink(out); // $ hasTaintFlow
99+
}
100+
{
101+
// "play.mvc;Http$MultipartFormData;true;getFiles;;;Argument[this];ReturnValue;taint;manual"
102+
List out = null;
103+
Http.MultipartFormData in = (Http.MultipartFormData) source();
104+
out = in.getFiles();
105+
sink(out); // $ hasTaintFlow
106+
}
107+
{
108+
// "play.mvc;Http$RawBuffer;true;asBytes;;;Argument[this];ReturnValue;taint;manual"
109+
ByteString out = null;
110+
Http.RawBuffer in = (Http.RawBuffer) source();
111+
out = in.asBytes();
112+
sink(out); // $ hasTaintFlow
113+
}
114+
{
115+
// "play.mvc;Http$RawBuffer;true;asBytes;;;Argument[this];ReturnValue;taint;manual"
116+
ByteString out = null;
117+
Http.RawBuffer in = (Http.RawBuffer) source();
118+
out = in.asBytes(0);
119+
sink(out); // $ hasTaintFlow
120+
}
121+
{
122+
// "play.mvc;Http$RawBuffer;true;asFile;;;Argument[this];ReturnValue;taint;manual"
123+
File out = null;
124+
Http.RawBuffer in = (Http.RawBuffer) source();
125+
out = in.asFile();
126+
sink(out); // $ hasTaintFlow
127+
}
128+
{
129+
// "play.mvc;Http$RequestBody;true;as;;;Argument[this];ReturnValue;taint;manual"
130+
Object out = null;
131+
Http.RequestBody in = (Http.RequestBody) source();
132+
out = in.as(null);
133+
sink(out); // $ hasTaintFlow
134+
}
135+
{
136+
// "play.mvc;Http$RequestBody;true;asBytes;;;Argument[this];ReturnValue;taint;manual"
137+
ByteString out = null;
138+
Http.RequestBody in = (Http.RequestBody) source();
139+
out = in.asBytes();
140+
sink(out); // $ hasTaintFlow
141+
}
142+
{
143+
// "play.mvc;Http$RequestBody;true;asFormUrlEncoded;;;Argument[this];ReturnValue;taint;manual"
144+
Map out = null;
145+
Http.RequestBody in = (Http.RequestBody) source();
146+
out = in.asFormUrlEncoded();
147+
sink(out); // $ hasTaintFlow
148+
}
149+
{
150+
// "play.mvc;Http$RequestBody;true;asJson;;;Argument[this];ReturnValue;taint;manual"
151+
JsonNode out = null;
152+
Http.RequestBody in = (Http.RequestBody) source();
153+
out = in.asJson();
154+
sink(out); // $ hasTaintFlow
155+
}
156+
{
157+
// "play.mvc;Http$RequestBody;true;asMultipartFormData;;;Argument[this];ReturnValue;taint;manual"
158+
Http.MultipartFormData out = null;
159+
Http.RequestBody in = (Http.RequestBody) source();
160+
out = in.asMultipartFormData();
161+
sink(out); // $ hasTaintFlow
162+
}
163+
{
164+
// "play.mvc;Http$RequestBody;true;asRaw;;;Argument[this];ReturnValue;taint;manual"
165+
Http.RawBuffer out = null;
166+
Http.RequestBody in = (Http.RequestBody) source();
167+
out = in.asRaw();
168+
sink(out); // $ hasTaintFlow
169+
}
170+
{
171+
// "play.mvc;Http$RequestBody;true;asText;;;Argument[this];ReturnValue;taint;manual"
172+
String out = null;
173+
Http.RequestBody in = (Http.RequestBody) source();
174+
out = in.asText();
175+
sink(out); // $ hasTaintFlow
176+
}
177+
{
178+
// "play.mvc;Http$RequestBody;true;asXml;;;Argument[this];ReturnValue;taint;manual"
179+
Document out = null;
180+
Http.RequestBody in = (Http.RequestBody) source();
181+
out = in.asXml();
182+
sink(out); // $ hasTaintFlow
183+
}
184+
{
185+
// "play.mvc;Http$RequestBody;true;parseJson;;;Argument[this];ReturnValue;taint;manual"
186+
Optional out = null;
187+
Http.RequestBody in = (Http.RequestBody) source();
188+
out = in.parseJson(null);
189+
sink(out); // $ hasTaintFlow
190+
}
191+
192+
}
193+
194+
}

java/ql/test/library-tests/frameworks/play/test.expected

Whitespace-only changes.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import java
2+
import TestUtilities.InlineFlowTest

java/ql/test/query-tests/security/CWE-918/mad/Test.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import org.apache.commons.jelly.JellyContext;
1010
import org.codehaus.cargo.container.installer.ZipURLInstaller;
1111
import org.kohsuke.stapler.HttpResponses;
12+
import play.libs.ws.WSClient;
13+
import play.libs.ws.StandaloneWSClient;
1214

1315
public class Test {
1416

@@ -74,4 +76,14 @@ public void test(HttpResponses r) {
7476
r.staticResource((URL) source()); // $ SSRF
7577
}
7678

79+
public void test(WSClient c) {
80+
// "play.libs.ws;WSClient;true;url;;;Argument[0];open-url;manual"
81+
c.url((String) source()); // $ SSRF
82+
}
83+
84+
public void test(StandaloneWSClient c) {
85+
// "play.libs.ws;StandaloneWSClient;true;url;;;Argument[0];open-url;manual"
86+
c.url((String) source()); // $ SSRF
87+
}
88+
7789
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/projectreactor-3.4.3/:${testdir}/../../../stubs/postgresql-42.3.3/:${testdir}/../../../stubs/HikariCP-3.4.5/:${testdir}/../../../stubs/spring-jdbc-5.3.8/:${testdir}/../../../stubs/jdbi3-core-3.27.2/:${testdir}/../../../stubs/cargo:${testdir}/../../../stubs/javafx-web:${testdir}/../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/stapler-1.263:${testdir}/../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../stubs/saxon-xqj-9.x:${testdir}/../../../stubs/apache-commons-beanutils:${testdir}/../../../stubs/apache-commons-lang:${testdir}/../../../stubs/apache-http-5
1+
//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/projectreactor-3.4.3/:${testdir}/../../../stubs/postgresql-42.3.3/:${testdir}/../../../stubs/HikariCP-3.4.5/:${testdir}/../../../stubs/spring-jdbc-5.3.8/:${testdir}/../../../stubs/jdbi3-core-3.27.2/:${testdir}/../../../stubs/cargo:${testdir}/../../../stubs/javafx-web:${testdir}/../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/stapler-1.263:${testdir}/../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../stubs/saxon-xqj-9.x:${testdir}/../../../stubs/apache-commons-beanutils:${testdir}/../../../stubs/apache-commons-lang:${testdir}/../../../stubs/apache-http-5:${testdir}/../../../stubs/playframework-2.6.x

0 commit comments

Comments
 (0)