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 に答える