1

我试图在我的 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;
}

基本上,我根据传入的值的数量(以及表中有多少列)动态地为语句创建字符串。我觉得它是安全的,因为 PreparedStatement 直到创建此字符串后才真正创建。我可能会制作类似的函数,它们接受实际的列名并将它们合并到 SQL 语句中,但这些将由我的程序生成,而不是基于用户输入。

4

1 回答 1

1

任何时候,只要您将值table插入到查询中而不转义,您就应该针对已知良好值的白名单进行测试。这可以防止人们发挥创造力并造成麻烦。一个简单的字典或有效条目数组通常就足够了。

使用准备好的语句是个好主意,但请确保您准备的语句从一开始就不允许注入。

于 2013-01-30T00:05:59.230 回答