我试图在我的Java程序中阻止SQL注入。我想使用PreparedStatements来执行此操作,但我事先不知道列数或其名称(该程序允许管理员在表中添加和删除列)。我是新手,所以这可能是一个愚蠢的问题,但我想知道这种方法是否安全:
public static int executeInsert( String table, Vector<String> values)
{
Connection con;
try {
con = connect();
// Construct INSERT statement
int numCols = values.size();
String selectStatement = "INSERT INTO " + table + " VALUES (?";
for (int i=1; i<numCols; i++) {
selectStatement += ", ?";
}
selectStatement += ")";
PreparedStatement prepStmt = con.prepareStatement(selectStatement);
// Set the parameters for the statement
for (int j=0; j<numCols; j++) {
prepStmt.setString(j, values.get(j));
}
System.out.println( "SQL: " + prepStmt) ;
int result = prepStmt.executeUpdate();
con.close() ;
return( result) ;
} catch (SQLException e) {
System.err.println( "SQL EXCEPTION" ) ;
System.err.println( "Inserting values " + values + " into " + table);
e.printStackTrace();
}
return -1;
}
基本上我是根据传入的值来动态创建语句的String(因此表中有多少列)。我觉得它很安全,因为PreparedStatement实际上并不是在这个字符串生成之后创建的。我可以创建类似的函数来接受实际的列名并将它们合并到SQL语句中,但这些函数将由我的程序生成,而不是基于用户输入。
答案 0 :(得分:2)
每当您将table
等值插入查询而不进行转义时,您应该针对已知良好值的白名单进行测试。这可以防止人们创造性并造成麻烦。一个简单的字典或有效条目数组通常就足够了。
使用准备好的陈述是个好主意,但请确保您准备的陈述不允许从一开始就进行注射。