1

私は可変テーブル名を入力する方法を探していましたが、SQLインジェクションにつながる可能性はありますが、動的SQLを使用するのが最善の方法のようです。誰かがこれがC#でどのように行われるかを示すことができますか?たとえば、次のような実装が必要です。

 SqlCommand command= new SqlCommand("SELECT x FROM @table WHERE @column = @y", conn);

これからわか​​るように、テーブル名と列名は変数になります。以前は文字列連結を使用していましたが、セキュリティ上の理由からそれを避けたいと思います。重要かどうかはわかりませんが、テーブルと列はユーザ​​ー入力によって決定されるのではなく、実際にはユーザーが選択したリンクによって決定されるため、SQLインジェクションはここでは問題になりませんか?

4

4 に答える 4

2

私が考えることができる最良の方法は2つの部分です。

  1. 名前をパラメーターとして受け取るストアード・プロシージャーがあります。このprocは、最初にカタログ(Information_Schema.Table)でテーブル名を検索し、適切な名前を取得して、それが有効であることを確認します。

  2. 次に、このルックアップを使用して、ストアドプロシージャは、パラメータからではなく、必要なSQLを構築します。

このルックアップを使用すると、基本的に、無効なテーブル名が渡されるのを防ぐことができます。

CREATE PROCEDURE RunSQL
    (@table NVARCHAR(50))
AS
BEGIN 
    DECLARE @validTableName NVARCHAR(50)

    SELECT 
        @validTableName = TABLE_NAME    
    FROM 
        INFORMATION_SCHEMA.TABLES
    WHERE 
        TABLE_NAME = @table
        AND SCHEMA_NAME = 'dbo' -- here you can limit or customise the schema

    IF @validTableName IS NULL
        RAISE ... raise an exception

    DECLARE @dynamicSql NVARCHAR(100) = REPLACE('SELECT * FROM dbo.[#TABLE#]', '#TABLE' @validTableName) 

    EXECUTE sp_executesql .... @dynamicSql ....
END

これを拡張して、検証、スキーマ、列などを使用できます。

最終的には、独自のSQLを構築し、インジェクションに対する保護を行う必要があります。それを回避することはできません。

于 2012-12-25T00:52:10.793 に答える
0

最も簡単な方法は、単純に文字列連結を使用してテーブル名を SQL クエリに入れることです。ただし、悪意のあるユーザーが任意の文字列をクエリに挿入できる限り、SQL インジェクションに対しては無防備です。たとえば、API URL がhttp://example.org/all?table_name=customer&order=descで、ユーザー名の URL から「table_name」を抽出しているとします。

有効なテーブル名の静的なサーバー側のホワイトリストを用意することで、SQL インジェクションの可能性を防ぐ必要があります (たとえばString[] ValidTableNames = new String[] { "customer", "purchase", ... }、table_name パラメータ値が SQL クエリに追加する前にこれらの値の 1 つであることを確認します)。

于 2012-12-25T01:07:28.100 に答える
0

私はかつて、特定のユーザーが特定のテーブルにアクセスできるようにする Web サイトを作成しました。ASP メンバーシップとユーザー ID を使用して、ユーザー アカウントが作成されたときにユーザー ID との関係を構築するテーブルを作成しました。アクセスを許可されたテーブル名はその時点で割り当てられました。テーブル名はハードコーディングされ、プロジェクトのパラメーターに基づいて動的に構築されました。そのため、tblCustomersNew や tlbInventoryOld などのテーブルが UserID にリンクされていました。

ユーザーがログインすると、SQL テーブルに対して UserID を照会してテーブル名を取得し、それをクエリに追加するか、ストアド プロシージャに渡しました。

すべてが認証されたユーザー アカウントの背後でも行われます。

編集:テーブル名はプロジェクトで事前定義され、データベースに保存されるため、これによりSQLインジェクションが回避されることを追加したかっただけです。ユーザーが権限を持っているテーブルにアクセスするには、認証されたユーザー アカウントでクエリを実行するだけで済みます。

于 2013-04-04T15:51:39.907 に答える