1

How to protect user specified table name from SQL Injection in C#, using MySQLの拡張として、 SQL インジェクションからuser-specified-table-query を保護する方法を見つけようとしています:

string createEventSQL = "INSERT INTO " + TableNameFromUser +
        " (" + TableColumnNames + ") " +
        "VALUES(" + ParametrizedTableColumnParams + ")";

明確にするために:入力をパラメータ化するために定義済みのライブラリを使用したいのですが、見つかりません

SHOW TABLES LIKE @TableNameFromUser;パフォーマンスが問題になるため、これを保護するために追加のクエリ (例: ) を使用したくありません。

多くの人が 100% 安全なソリューションを作成することは不可能だと主張しているように思えますが、それは私には意味がありません。 . 基本的に、パラメータ化されたテーブル名をサポートしている場合に、 MySQL コネクタが行うことを複製したいだけです。

私はまだSQLの経験があまりありませんが、これまでのところ、次のことが必要であることがわかりました。

SQL インジェクションから保護するために他に何ができますか?

4

2 に答える 2

1

MySQL Ado コネクタは、パラメータ on -here をサポートしてMySqlCommandます。あなたが特定したように、一般に、アドホック SQL をマングリングする代わりに、常にパラメーターを渡す必要があります。

残念ながら、この SO 投稿のように、これはテーブル名をパラメータ化しません: MySqlParameter as TableName

そのため、テーブル名を検証してサニタイズする必要があるようです。

テーブル名をホワイト リストと比較できますか? または、データベース内の別の場所に有効なテーブル名のリストを保持している可能性がありますか?

于 2012-11-22T12:38:47.387 に答える
1

データ値をパラメータ化できますし、パラメータ化する必要があります。あなたはそれを知っています。

SQL のプリペアド ステートメント機能を使用して、テーブル名と列名をパラメーター化することはできません。ただし、ユーザー提供のテーブル名と列名に何が含まれるかについては、制約を確立して適用する必要があります。たとえば、テーブルと列の名前はすべて文字で始まり、文字、数字、およびアンダースコアのセットから 3 ~ 15 文字で構成されていると主張できます。制約を破るユーザー提供の名前に対して例外をスローするチェッカー関数を簡単に作成し、クエリを作成するときに常にその関数で名前をチェックできます。

パフォーマンスのために、データベースのスキーマに対してテーブルと列の名前をチェックすることを除外しました。その決定を再考することをお勧めします。これらのクエリは、あなたが思っているほど遅くはありません。MySQL 情報スキーマを使用すると、次のようなクエリを実行できます。

SELECT COLUMN_NAME
  FROM information_schema.COLUMNS
 WHERE TABLE_SCHEMA = 'zip'
   AND TABLE_NAME= 'zip'

これにより、指定したテーブル内の列の適切なリストが表示されます。

于 2012-11-22T12:40:06.790 に答える