Prenderò l'esempio simile dal link citato . Nell'esempio otterrò l'ID utente (intero) come argomento e cercherò di convalidarlo sul database.
class ListUtility {
private static void addToList(List list, Object obj) {
list.add(obj); // Unchecked warning
}
private static boolean validateUser(List list){
boolean isValidUser=false;
Statement stmt = conn.createStatement(); //conn is a jdbc Connection
String Query="SELECT userid FROM Customers WHERE userid='"+list.get(0)+"'"; //developer expects list.get(0) is a integer
ResultSet rs = stmt.executeQuery(Query);
if (rs.next()) {
System.out.println("Valid User");
isValidUser=true;
}
return isValidUser; //returns true for args[0]=something' or '1'='1
}
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer> ();
addToList(list, args[0]); //arg[0] is expected to be a valid userid of type Integer(say)
validateuser(list);
}
}
Ora Se invoco il programma con l'argomento something' or '1'='1
verrà stampato "Valid User"
. Questa è una tipica iniezione Sql. Ma questo è successo a causa dell'inquinamento da heap in cui abbiamo aggiunto args[0]
a list
anche se il tipo non corrisponde.
L'inquinamento da heap è possibile in questo caso perché le informazioni sul tipo parametrizzato vengono scartate prima dell'esecuzione.
La chiamata a addToList(list,args[0])
riesce ad aggiungere una stringa da elencare, sebbene l'elenco sia di tipo List<Integer>
. Inoltre, la chiamata a validateUser(List list)
prende l'elenco di tipo List<Object>
anziché strict List<Integer>
.
Questo runtime Java non genera una classe ClassCastException poiché l'elenco valori non è stato letto con un tipo non valido in questo esempio.
Perché la lista non viene mai letta rigorosamente come List<Integer>
.