11

トピックが示唆しているように、.NET (実際には言語は関係ありません) と SQL Server を使用して、テーブル名をパラメーターとして渡すことができるようにしたいと考えています。

値に対してこれを行う方法を知っています。たとえば、クエリでパラメーターを示すために使用しますcommand.Parameters.AddWithValue("whatever", whatever)@whatever問題は、列やテーブル名など、クエリの他の部分でこれを実行できるようにしたい状況にあるということです。

これは理想的な状況ではありませんが、私が使用しなければならない状況です。コードを使用する人だけがこれらのテーブル名を設定でき、エンドユーザーは設定できないため、SQL インジェクションが実際に発生する可能性はありません。しかし、それは面倒です。

それで、私が求めていることは可能ですか?

編集: SQL インジェクションについて明確にするために、状況に応じて、テーブル名はソース コードによってのみ渡されます。これを指定するのは開発者です。いずれにせよ、開発者はデータベース層にアクセスできるので、私が尋ねているのはセキュリティのためではなく、コードをよりきれいにするためです。

4

7 に答える 7

7

テーブル名を直接パラメータ化することはできません。を介して間接的に行うこともできますsp_ExecuteSQLが、C# で (パラメータ化された) TSQL を構築し (テーブル名を連結しますが、他の値は連結しません)、それをコマンドとして送信することもできます。同じセキュリティ モデルが得られます (つまり、明示的な SELECT などが必要で、署名されていないと仮定するなど)。

また、必ずテーブル名をホワイトリストに登録してください。

于 2008-12-16T17:39:13.293 に答える
4

他のパラメーターと同様に、テーブル名をパラメーターとして渡すことができます。重要なのは、動的 SQL ステートメントを作成する必要があることです。次に、アプリケーション層またはプロシージャで作成する方が簡単かどうかを検討する必要があります。

create procedure myProc

@tableName nvarchar(50)

as

sp_executesql N'select * from ' + @tablename

参考までに、このコード サンプルはメモリからのもので、sp_executesql の適切な構文については BOL を参照してください。

また、これは SQL インジェクションの影響を非常に受けやすいですが、これは問題ではありませんが、これを読んでいる人は、ユーザーからの入力を受け入れてこのようなクエリを生成することに非常に注意する必要があります。

于 2008-12-16T17:35:54.517 に答える
4

SQL クエリ パラメータは、リテラル値の代わりにのみ使用できます。テーブル名、列名、値のリスト、またはその他の SQL 構文にパラメーターを使用することはできません。これは、すべてのブランドのデータベースで標準的な SQL の動作です。

テーブル名を動的にする唯一の方法は、その文字列をステートメントとして準備する前に、変数を SQL クエリに挿入することです。

ところで、これが SQL インジェクションのリスクではないと思うなら、あなたはごまかしています。テーブル名をクエリに動的に補間する場合は、変数から補間される文字列リテラルを引用符で囲むのと同様に、テーブル名を区切られた識別子で囲む必要があります。

于 2008-12-16T17:37:09.210 に答える
4

私が見た SQL ダイアレクトでこの機能を見たことはないと思いますが、それは専門分野ではありません。

文字を AZ、az、0-9、'.'、'_'、' ' に制限することをお勧めします。次に、データベースに適切なブラケット (SQL Server の [] など) を使用してラップします。全体を丸くします。次に、SQL に直接配置します。

それが SQL インジェクションのリスクではないということについて、あなたが何を意味していたのかは完全には明らかではありません。名前がソース コードにあり、ソース コードだけにあるということですか? もしそうなら、私はそれが物事をより良くすることに同意します. 開発者がクレチンではないことを信頼している場合(意図的であろうとなかろうと) 、ブラケットを自動的に実行する必要さえないかもしれません。

于 2008-12-16T17:38:02.720 に答える
2

SQL インジェクションの影響を受けにくいという考えは間違っています。フロント エンド ユーザーからの SQL インジェクションの可能性は低くなりますが、それでも SQL インジェクションの可能性は非常に高くなります。データベースに対するほとんどの攻撃は、エンド ユーザーからではなく、攻撃対象の社内から発生します。

従業員は恨みを持っているかもしれませんし、不誠実であるかもしれませんし、不満を持っているかもしれませんし、単にあまり賢くないかもしれませんし、データベースに対して自分がすべきだと思うことは何でもセキュリティを迂回しても大丈夫だと考えているかもしれません。

于 2008-12-16T18:14:43.410 に答える
0

インジェクションを防ぐためのアイデアを確認するだけ select OBJECT_ID(@tablename) です。これはテーブル名でなければならないことを知っています。これが数値を返す場合は、実際のクエリを実行します。

于 2015-02-27T21:57:26.683 に答える
0

ユーザー Vimvq1987 によるこの投稿の回答を参照してください: MySqlParameter as TableName

基本的に、最初にテーブル名をスキーマに対してチェックします。スキーマでは、テーブル名がパラメーター化された方法で使用されます。次に、すべて問題がなければ、テーブル名は正当です。

言い換えた基本的な考え方は次のとおりです。

    SELECT table_name
    FROM information_schema.tables
    WHERE table_schema = 'databasename'
    AND table_name = @table;

    cmd.Parameters.AddWithValue("@table",TableName);

これがテーブル名でOKを返す場合は、メインクエリに進みます...

于 2013-07-11T14:40:56.420 に答える