public static bool TruncateTable(string dbAlias, string tableName) { string sqlStatement = string.Format("TRUNCATE TABLE {0}", tableName); return ExecuteNonQuery(dbAlias, sqlStatement) > 0; }
P粉4349968452023-11-08 20:39:55
私の知る限り、少なくとも Oracle や SQL Server では、パラメーター化されたクエリを使用して DDL ステートメントを実行したり、テーブル名を指定したりすることはできません。クレイジーな TruncateTable 関数を使用し、SQL インジェクションを回避できなければならない場合、入力が安全に切り捨てられるテーブルかどうかをチェックするストアド プロシージャを作成することになります。
リーリーP粉7383463802023-11-08 09:41:58
SQL インジェクションに対抗するための最も一般的なアドバイスは、SQL クエリ パラメーターを使用することです (このスレッドの何人かの人がこれを行うことを提案しています)。
この場合、これは間違った答えです。 DDL ステートメント内のテーブル名に SQL クエリ パラメーターを使用することはできません。
SQL クエリ パラメーターは、SQL 式のリテラル値の代わりにのみ使用できます。これは、すべての SQL 実装の標準です。
テーブル名がある場合、SQL インジェクションを防ぐための私のお勧めは、既知のテーブル名のリストに対して入力文字列を検証することです。
有効なテーブル名のリストは、INFORMATION_SCHEMA
:
これで、入力変数を SQL パラメーターとしてこのクエリに渡すことができます。クエリが行を返さない場合は、入力が無効であり、テーブルとして使用できないことがわかります。クエリが行を返す場合、その行は一致するため、より安心して使用できます。
@John Buchanan が を提案したように、アプリケーションで切り捨てられるように定義したテーブルの特定のリストに対してテーブル名を検証することもできます。
tableName
が RDBMS にテーブル名として存在することを確認した後でも、スペースや特殊文字を含むテーブル名を使用する場合に備えて、テーブル名を区切ることをお勧めします。デフォルトの識別子の区切り文字は角括弧です:
これで、SQL インジェクションの危険にさらされるのは、tableName
が実際のテーブルと一致し、実際にテーブル名に角括弧を使用している場合のみです!