[ ODP.NET ] パラメータをバインドしてクエリをセキュアに発行する ( OracleParameter )

Pocket

クエリにパラメーター変数(:userid、:usertype) に OracleParameter オブジェクトを使って値をバインドしクエリを発行するサンプルになります。まずは、サンプルコードをご確認ください。

スポンサーリンク

OracleParameter のサンプルコード

VB.NET

    Dim user As String = "userid"        'ユーザー
    Dim passwd As String = "password"    'パスワード
    Dim ds As String = "ds"              'データソース

    Dim uid As String = "UID0001"
    Dim utype As Char = "0"

    ' クエリ作成(変数を使用)
    Dim sql As String = "select user_name from user_mst_table where user_id = :userid and user_type = :usertype"

    ' Oracle接続文字列を組み立てる
    Dim connectstring As String = "User Id=" + user + "; " + "Password=" + passwd + "; " + "Data Source=" + ds

    Using cnn As OracleConnection = New OracleConnection(connectstring)
        ' Oracleへのコネクションの確立
        cnn.Open()

        Dim myCmd As OracleCommand = New OracleCommand(sql, cnn)

        ' パラメーター変数に値をバインドする
        myCmd.Parameters.Add(New OracleParameter(":userid", OracleDbType.Varchar2, uid, ParameterDirection.Input))
        myCmd.Parameters.Add(New OracleParameter(":usertype", OracleDbType.Char, utype, ParameterDirection.Input))

        Dim myDa As OracleDataAdapter = New OracleDataAdapter(myCmd)
        Dim myDs As DataSet = New DataSet()
        ' 結果取得
        myDa.Fill(myDs)

        ' 結果を取得する
        'Dim result As String = myDs.Tables(0).Rows(0).ItemArray.GetValue(0).ToString()

        '接続を閉じる
        cnn.Close()
    End Using

C#

    string user   = "userid";     // ユーザー
    string passwd = "password";   // パスワード
    string ds     = "ds";         // データソース

    string uid = "UID0001";
    char utype = '0';

    // クエリ作成
    string sql = "select user_name from user_mst_table where user_id = :userid and user_type = :usertype";

    // Oracle接続文字列を組み立てる
    string connectstring = "User Id=" + user + "; " + "Password=" + passwd + "; " + "Data Source=" + ds;

    using (OracleConnection cnn = new OracleConnection(connectstring))
    {
        // コネクションの確立
        cnn.Open();

        OracleCommand myCmd = new OracleCommand(sql, cnn);

        // パラメーターに値をバインドする
        myCmd.Parameters.Add(new OracleParameter(":userid", OracleDbType.Varchar2, uid, ParameterDirection.Input));
        myCmd.Parameters.Add(new OracleParameter(":usertype", OracleDbType.Char, utype, ParameterDirection.Input));

        OracleDataAdapter myDa = new OracleDataAdapter(myCmd);
        DataSet myDs = new DataSet();
        // 結果取得
        myDa.Fill(myDs);

        // 接続を閉じる
        cnn.Close();
    }

パラメーターを追加する順番

パラメータに値をバインドする場合は、上記の場合はその順番に注意しなければなりません。変数名と値を持つ OracleParameter オブジェクトをパラメーターにしているのでパラメーターを追加する順番は関係ないと思ってしまいますが、上記のクエリでは

  1. :userid
  2. :usertype

の順番でパラメーター変数が出現していますので、パラメーターの追加も同一順序で行わなければなりません。

順序ではなく、クエリ中の変数と OracleParameter オブジェクトの変数名でバインドしたい場合は、OracleCommand.BindByName プロパティを true にすることで変数名によってバインドするようになり、パラメーターの追加順序は問われなくなります。おそらく、処理スピードが順序で制御したほうが早いのだと思います。

バインドする利点

シングルクォーテーション(‘) を含んでいる文字列を変数にバインドしても正常に文字として扱ってくれるため プログラミングミスやテスト不足によるセキュリティ面の脆弱性を埋め込む可能性を軽減させることができるでしょう。

通常、OracleParameter を使用しないときにシングルクォーテーション(‘) を含む文字列を扱う場合は String.Replace メソッドなどでシングルクォーテーションの置換処理などを行いクエリを作成したりしなければなりませんが、忘れた場合には脆弱性のあるシステムになってしまうかもしれません。テストで発見できなければの話ですが。

masao はなかなか発見できません。ザルチェックです

スポンサーリンク


Pocket

Leave a Comment

Your email address will not be published. Required fields are marked *