11

DB アクセス レイヤーでは、いくつかの動的クエリを作成しています。たとえば、ORDER BY節の一部を構築するための次のメソッドがあります。

protected string BuildSortString(string sortColumn, string sortDirection, string defaultColumn)
{
    if (String.IsNullOrEmpty(sortColumn))
    {
        return defaultColumn;
    }

    return String.Format("{0} {1}", sortColumn, sortDirection);
}

問題は、sortColumnどちらsortDirectionも文字列として外部から来るため、もちろん、インジェクション攻撃の可能性を防ぐために何かを行う必要があります。これを行う方法を知っている人はいますか?

4

5 に答える 5

14

文字列を処理する必要がある場合は、ホワイトリストに登録するのが最善の策です。まず、sortDirectionホワイトリストにはかなり些細なことである必要があります。大文字と小文字を区別しない"asc" /"desc"と比較すると、設定する必要があります。他の人にとっては、おそらくデータに期待されるものを渡して検証することにより、既知の列にホワイトリストに登録することをお勧めします。Typeしかし、絶対的なピンチでは、正規表現を使用して、それらがすべて厳密に英数字(az、AZ、0〜9の範囲-必要に応じてアンダースコア)であることを強制するように制限し、次に追加することができます[]

return string.Format("[{0}] {1}", sortColumn, sortDirection);

ただし、方向の列挙型と同様に、既知の列の厳密なホワイトリストの方がはるかに優れています。

于 2013-01-14T11:15:06.637 に答える
1

パラメータintの代わりに受け入れるようにメソッドを変更できる場合の別の解決策。string

protected string BuildSortString(int sortColumn, int sortDirection, string defaultColumn)
{
    if (String.IsNullOrEmpty(sortColumn))
    {
        return defaultColumn;
    }
//sortdirection 0-> "ASC" else "DESC"
//sorColumn 1 for your firstcolumn, 2 for your second column etc.
    return String.Format("{0} {1}", sortColumn, sortDirection==0? " ASC " : " DESC ");
}

幸運を。

于 2013-01-14T11:31:28.243 に答える
0

You could do something like this:

public string BuildSortString(string sortColumn, SortDirection direction, string defaultColumn)
{
    string sortDirection = direction.ToString();

    if (String.IsNullOrEmpty(sortColumn))
    {
        return VerifyColumn(defaultColumn);
    }

    return String.Format("{0} {1}", VerifyColumn(sortColumn), sortDirection);
}

private string VerifyColumn(string column)
{
    switch (column) // fill this with a whitelist of accepted columns
    {
        case "some_column":
            return column;
    }

    return String.Empty; // the column must be invalid (do whatever you want here)
}

public enum SortDirection
{
    ASC, DESC
}
于 2013-01-14T11:39:22.573 に答える
0

これは、渡された列名と方向に基づいて切り替える大きな CASE ステートメントを使用して行うことができます。ここにはSOの答えがあります。次のようなコードを見ることになります。

SELECT
     *
FROM
     My_Table
WHERE
     Whatever = @something
ORDER BY
     CASE @sort_order
          WHEN 'ASC' THEN
               CASE @order_by
                    WHEN 'surname' THEN surname
                    WHEN 'forename' THEN forename
                    WHEN 'fullname' THEN fullname
                    ELSE surname
               END
          ELSE '1'
     END ASC,
     CASE @sort_order
          WHEN 'DESC' THEN
               CASE @order_by
                    WHEN 'surname' THEN surname
                    WHEN 'forename' THEN forename
                    WHEN 'fullname' THEN fullname
                    ELSE surname
               END
          ELSE '1'
     END DESC
于 2013-01-14T11:15:56.283 に答える
0

解決策: cmd.Parameters またはEscapedString、しかし私は cmd.Parameters を好みます(常に機能し、期待される例外を楽しむことができます)

例:

cmd.CommandText = "SELECT UNIQUE_ID FROM userdetails WHERE USER_ID IN (?, ?)";
cmd.Parameters.Add("?ID1", OdbcType.VarChar, 250).Value = email1;
cmd.Parameters.Add("?ID2", OdbcType.VarChar, 250).Value = email2;

パラメータを含むプリペアド ステートメントを使用すると、最も一般的なケースで SQL インジェクションを防ぐのに役立ちます。そうしないと、信頼できないコンテンツを文字列に補間してから、その文字列を SQL ステートメントとして実行することになります。

ただし、クエリ パラメータは単一の値の代わりになります。動的なテーブル名、列名、値のリスト (IN() 述語など)、式、または SQL キーワードの代わりとしてクエリ パラメータを使用することはできません。

そのような場合は、フィルタリングやホワイトリストなどの手法を使用して、信頼できないコンテンツを SQL 文字列に挿入しないようにすることができます。

フィルタリングは、問題の原因となる文字を取り除く場所です。動的な列名を英数字のみにする必要があることがわかっている場合は、変数を SQL で使用する前にフィルターを適用してください。または、 /^[A-Za-z0-9]*$/ のような正規表現に一致しない場合は変数を拒否します

于 2013-01-14T11:22:38.897 に答える