Skip to content

Commit 859b99f

Browse files
committed
Add test
1 parent daaa187 commit 859b99f

File tree

2 files changed

+107
-29
lines changed

2 files changed

+107
-29
lines changed

java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTainted.expected

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,19 @@ edges
1414
| Test.java:60:29:60:46 | toString(...) : String | Test.java:62:47:62:61 | querySbToString | provenance | Sink:MaD:43208 |
1515
| Test.java:183:33:183:45 | args : String[] | Test.java:209:47:209:68 | queryWithUserTableName | provenance | Sink:MaD:43208 |
1616
| Test.java:213:34:213:46 | args : String[] | Test.java:221:81:221:111 | ... + ... | provenance | Sink:MaD:43208 |
17-
| Test.java:227:26:227:38 | args : String[] | Test.java:228:11:228:14 | args : String[] | provenance | |
18-
| Test.java:227:26:227:38 | args : String[] | Test.java:232:14:232:17 | args : String[] | provenance | |
19-
| Test.java:227:26:227:38 | args : String[] | Test.java:233:15:233:18 | args : String[] | provenance | |
20-
| Test.java:228:11:228:14 | args : String[] | Test.java:29:30:29:42 | args : String[] | provenance | |
21-
| Test.java:232:14:232:17 | args : String[] | Test.java:183:33:183:45 | args : String[] | provenance | |
22-
| Test.java:233:15:233:18 | args : String[] | Test.java:213:34:213:46 | args : String[] | provenance | |
17+
| Test.java:227:32:227:44 | args : String[] | Test.java:236:48:236:52 | query | provenance | Sink:MaD:43208 |
18+
| Test.java:227:32:227:44 | args : String[] | Test.java:246:48:246:52 | query | provenance | Sink:MaD:43208 |
19+
| Test.java:227:32:227:44 | args : String[] | Test.java:257:48:257:52 | query | provenance | Sink:MaD:43208 |
20+
| Test.java:227:32:227:44 | args : String[] | Test.java:268:48:268:52 | query | provenance | Sink:MaD:43208 |
21+
| Test.java:227:32:227:44 | args : String[] | Test.java:281:48:281:52 | query | provenance | Sink:MaD:43208 |
22+
| Test.java:286:26:286:38 | args : String[] | Test.java:287:11:287:14 | args : String[] | provenance | |
23+
| Test.java:286:26:286:38 | args : String[] | Test.java:291:14:291:17 | args : String[] | provenance | |
24+
| Test.java:286:26:286:38 | args : String[] | Test.java:292:15:292:18 | args : String[] | provenance | |
25+
| Test.java:286:26:286:38 | args : String[] | Test.java:293:13:293:16 | args : String[] | provenance | |
26+
| Test.java:287:11:287:14 | args : String[] | Test.java:29:30:29:42 | args : String[] | provenance | |
27+
| Test.java:291:14:291:17 | args : String[] | Test.java:183:33:183:45 | args : String[] | provenance | |
28+
| Test.java:292:15:292:18 | args : String[] | Test.java:213:34:213:46 | args : String[] | provenance | |
29+
| Test.java:293:13:293:16 | args : String[] | Test.java:227:32:227:44 | args : String[] | provenance | |
2330
nodes
2431
| Mongo.java:10:29:10:41 | args : String[] | semmle.label | args : String[] |
2532
| Mongo.java:17:45:17:67 | parse(...) | semmle.label | parse(...) |
@@ -40,19 +47,31 @@ nodes
4047
| Test.java:209:47:209:68 | queryWithUserTableName | semmle.label | queryWithUserTableName |
4148
| Test.java:213:34:213:46 | args : String[] | semmle.label | args : String[] |
4249
| Test.java:221:81:221:111 | ... + ... | semmle.label | ... + ... |
43-
| Test.java:227:26:227:38 | args : String[] | semmle.label | args : String[] |
44-
| Test.java:228:11:228:14 | args : String[] | semmle.label | args : String[] |
45-
| Test.java:232:14:232:17 | args : String[] | semmle.label | args : String[] |
46-
| Test.java:233:15:233:18 | args : String[] | semmle.label | args : String[] |
50+
| Test.java:227:32:227:44 | args : String[] | semmle.label | args : String[] |
51+
| Test.java:236:48:236:52 | query | semmle.label | query |
52+
| Test.java:246:48:246:52 | query | semmle.label | query |
53+
| Test.java:257:48:257:52 | query | semmle.label | query |
54+
| Test.java:268:48:268:52 | query | semmle.label | query |
55+
| Test.java:281:48:281:52 | query | semmle.label | query |
56+
| Test.java:286:26:286:38 | args : String[] | semmle.label | args : String[] |
57+
| Test.java:287:11:287:14 | args : String[] | semmle.label | args : String[] |
58+
| Test.java:291:14:291:17 | args : String[] | semmle.label | args : String[] |
59+
| Test.java:292:15:292:18 | args : String[] | semmle.label | args : String[] |
60+
| Test.java:293:13:293:16 | args : String[] | semmle.label | args : String[] |
4761
subpaths
4862
#select
4963
| Mongo.java:17:45:17:67 | parse(...) | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:17:45:17:67 | parse(...) | This query depends on a $@. | Mongo.java:10:29:10:41 | args | user-provided value |
5064
| Mongo.java:21:49:21:52 | json | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:21:49:21:52 | json | This query depends on a $@. | Mongo.java:10:29:10:41 | args | user-provided value |
51-
| Test.java:36:47:36:52 | query1 | Test.java:227:26:227:38 | args : String[] | Test.java:36:47:36:52 | query1 | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value |
52-
| Test.java:42:57:42:62 | query2 | Test.java:227:26:227:38 | args : String[] | Test.java:42:57:42:62 | query2 | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value |
53-
| Test.java:50:62:50:67 | query3 | Test.java:227:26:227:38 | args : String[] | Test.java:50:62:50:67 | query3 | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value |
54-
| Test.java:62:47:62:61 | querySbToString | Test.java:227:26:227:38 | args : String[] | Test.java:62:47:62:61 | querySbToString | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value |
55-
| Test.java:70:40:70:44 | query | Test.java:227:26:227:38 | args : String[] | Test.java:70:40:70:44 | query | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value |
56-
| Test.java:78:46:78:50 | query | Test.java:227:26:227:38 | args : String[] | Test.java:78:46:78:50 | query | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value |
57-
| Test.java:209:47:209:68 | queryWithUserTableName | Test.java:227:26:227:38 | args : String[] | Test.java:209:47:209:68 | queryWithUserTableName | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value |
58-
| Test.java:221:81:221:111 | ... + ... | Test.java:227:26:227:38 | args : String[] | Test.java:221:81:221:111 | ... + ... | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value |
65+
| Test.java:36:47:36:52 | query1 | Test.java:286:26:286:38 | args : String[] | Test.java:36:47:36:52 | query1 | This query depends on a $@. | Test.java:286:26:286:38 | args | user-provided value |
66+
| Test.java:42:57:42:62 | query2 | Test.java:286:26:286:38 | args : String[] | Test.java:42:57:42:62 | query2 | This query depends on a $@. | Test.java:286:26:286:38 | args | user-provided value |
67+
| Test.java:50:62:50:67 | query3 | Test.java:286:26:286:38 | args : String[] | Test.java:50:62:50:67 | query3 | This query depends on a $@. | Test.java:286:26:286:38 | args | user-provided value |
68+
| Test.java:62:47:62:61 | querySbToString | Test.java:286:26:286:38 | args : String[] | Test.java:62:47:62:61 | querySbToString | This query depends on a $@. | Test.java:286:26:286:38 | args | user-provided value |
69+
| Test.java:70:40:70:44 | query | Test.java:286:26:286:38 | args : String[] | Test.java:70:40:70:44 | query | This query depends on a $@. | Test.java:286:26:286:38 | args | user-provided value |
70+
| Test.java:78:46:78:50 | query | Test.java:286:26:286:38 | args : String[] | Test.java:78:46:78:50 | query | This query depends on a $@. | Test.java:286:26:286:38 | args | user-provided value |
71+
| Test.java:209:47:209:68 | queryWithUserTableName | Test.java:286:26:286:38 | args : String[] | Test.java:209:47:209:68 | queryWithUserTableName | This query depends on a $@. | Test.java:286:26:286:38 | args | user-provided value |
72+
| Test.java:221:81:221:111 | ... + ... | Test.java:286:26:286:38 | args : String[] | Test.java:221:81:221:111 | ... + ... | This query depends on a $@. | Test.java:286:26:286:38 | args | user-provided value |
73+
| Test.java:236:48:236:52 | query | Test.java:286:26:286:38 | args : String[] | Test.java:236:48:236:52 | query | This query depends on a $@. | Test.java:286:26:286:38 | args | user-provided value |
74+
| Test.java:246:48:246:52 | query | Test.java:286:26:286:38 | args : String[] | Test.java:246:48:246:52 | query | This query depends on a $@. | Test.java:286:26:286:38 | args | user-provided value |
75+
| Test.java:257:48:257:52 | query | Test.java:286:26:286:38 | args : String[] | Test.java:257:48:257:52 | query | This query depends on a $@. | Test.java:286:26:286:38 | args | user-provided value |
76+
| Test.java:268:48:268:52 | query | Test.java:286:26:286:38 | args : String[] | Test.java:268:48:268:52 | query | This query depends on a $@. | Test.java:286:26:286:38 | args | user-provided value |
77+
| Test.java:281:48:281:52 | query | Test.java:286:26:286:38 | args : String[] | Test.java:281:48:281:52 | query | This query depends on a $@. | Test.java:286:26:286:38 | args | user-provided value |

java/ql/test/query-tests/security/CWE-089/semmle/examples/Test.java

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
import java.sql.ResultSet;
1212
import java.sql.SQLException;
1313
import java.sql.Statement;
14-
15-
14+
import java.util.ArrayList;
15+
import java.util.List;
1616

1717

1818

@@ -50,7 +50,7 @@ private static void tainted(String[] args) throws IOException, SQLException {
5050
PreparedStatement statement = connection.prepareStatement(query3);
5151
ResultSet results = statement.executeQuery();
5252
}
53-
// BAD: an injection using a StringBuilder instead of string append
53+
// BAD: an injection using a StringBuilder instead of string append
5454
{
5555
String category = args[1];
5656
StringBuilder querySb = new StringBuilder();
@@ -88,7 +88,7 @@ private static void tainted(String[] args) throws IOException, SQLException {
8888
ResultSet results = statement.executeQuery(query1);
8989
}
9090
}
91-
91+
9292
private static void unescaped() throws IOException, SQLException {
9393
// BAD: the category might have SQL special characters in it
9494
{
@@ -97,7 +97,7 @@ private static void unescaped() throws IOException, SQLException {
9797
+ categoryName + "' ORDER BY PRICE";
9898
ResultSet results = statement.executeQuery(queryFromField);
9999
}
100-
// BAD: unescaped code using a StringBuilder
100+
// BAD: unescaped code using a StringBuilder
101101
{
102102
StringBuilder querySb = new StringBuilder();
103103
querySb.append("SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='");
@@ -107,7 +107,7 @@ private static void unescaped() throws IOException, SQLException {
107107
Statement statement = connection.createStatement();
108108
ResultSet results = statement.executeQuery(querySbToString);
109109
}
110-
// BAD: a StringBuilder with appends of + operations
110+
// BAD: a StringBuilder with appends of + operations
111111
{
112112
StringBuilder querySb2 = new StringBuilder();
113113
querySb2.append("SELECT ITEM,PRICE FROM PRODUCT ");
@@ -118,7 +118,7 @@ private static void unescaped() throws IOException, SQLException {
118118
ResultSet results = statement.executeQuery(querySb2ToString);
119119
}
120120
}
121-
121+
122122
private static void good(String[] args) throws IOException, SQLException {
123123
// GOOD: use a prepared query
124124
{
@@ -127,9 +127,9 @@ private static void good(String[] args) throws IOException, SQLException {
127127
PreparedStatement statement = connection.prepareStatement(query2);
128128
statement.setString(1, category);
129129
ResultSet results = statement.executeQuery();
130-
}
130+
}
131131
}
132-
132+
133133
private static void controlledStrings() throws IOException, SQLException {
134134
// GOOD: integers cannot have special characters in them
135135
{
@@ -179,7 +179,7 @@ private static void controlledStrings() throws IOException, SQLException {
179179
ResultSet results = statement.executeQuery(queryWithDoubleToString);
180180
}
181181
}
182-
182+
183183
private static void tableNames(String[] args) throws IOException, SQLException {
184184
// GOOD: table names cannot be replaced by a wildcard
185185
{
@@ -224,13 +224,72 @@ private static void bindingVars(String[] args) throws IOException, SQLException
224224
}
225225
}
226226

227+
private static void allowlist(String[] args) throws IOException, SQLException {
228+
String tainted = args[1];
229+
// GOOD: an allowlist is used with constant strings
230+
{
231+
Statement statement = connection.createStatement();
232+
List<String> allowlist = List.of("allowed1", "allowed2", "allowed3");
233+
if(allowlist.contains(tainted)){
234+
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
235+
+ tainted + "' ORDER BY PRICE";
236+
ResultSet results = statement.executeQuery(query);
237+
}
238+
}
239+
// BAD: an allowlist is used but one of the entries is not a compile-time constant
240+
{
241+
Statement statement = connection.createStatement();
242+
List<String> allowlist = List.of("allowed1", "allowed2", args[2]);
243+
if(allowlist.contains(tainted)){
244+
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
245+
+ tainted + "' ORDER BY PRICE";
246+
ResultSet results = statement.executeQuery(query);
247+
}
248+
}
249+
// GOOD: an allowlist is used with constant strings
250+
{
251+
Statement statement = connection.createStatement();
252+
String[] allowedArray = {"allowed1", "allowed2", "allowed3"};
253+
List<String> allowlist = List.of(allowedArray);
254+
if(allowlist.contains(tainted)){
255+
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
256+
+ tainted + "' ORDER BY PRICE";
257+
ResultSet results = statement.executeQuery(query);
258+
}
259+
}
260+
// BAD: an allowlist is used but one of the entries is not a compile-time constant
261+
{
262+
Statement statement = connection.createStatement();
263+
String[] allowedArray = {"allowed1", "allowed2", args[2]};
264+
List<String> allowlist = List.of(allowedArray);
265+
if(allowlist.contains(tainted)){
266+
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
267+
+ tainted + "' ORDER BY PRICE";
268+
ResultSet results = statement.executeQuery(query);
269+
}
270+
}
271+
// GOOD: an allowlist is used with constant string, but we currently miss this case
272+
{
273+
Statement statement = connection.createStatement();
274+
List<String> allowlist = new ArrayList<String>();
275+
allowlist.add("allowed1");
276+
allowlist.add("allowed2");
277+
allowlist.add("allowed3");
278+
if(allowlist.contains(tainted)){
279+
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
280+
+ tainted + "' ORDER BY PRICE";
281+
ResultSet results = statement.executeQuery(query);
282+
}
283+
}
284+
}
285+
227286
public static void main(String[] args) throws IOException, SQLException {
228287
tainted(args);
229288
unescaped();
230289
good(args);
231290
controlledStrings();
232291
tableNames(args);
233292
bindingVars(args);
293+
allowlist(args);
234294
}
235295
}
236-

0 commit comments

Comments
 (0)