1111import java .sql .ResultSet ;
1212import java .sql .SQLException ;
1313import 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