2

C# の odbc ドライバーへの OdbcConnection へのパラメーター化された SQL クエリを実行する際に問題があります。列名とテーブル名は Web GUI から設定できるので、インジェクションから保護したい

using (OdbcCommand command = connection.CreateCommand())
{
    command.CommandText = "SELECT ? FROM ?";
    command.CommandTimeout = SynchTimeout;
    command.CommandType = CommandType.Text;

    command.Parameters.Add(new OdbcParameter(string.Empty, "User"));
    command.Parameters.Add(new OdbcParameter(string.Empty, "TableName"));

    OdbcDataReader reader = command.ExecuteReader();
    while (reader.Read())
    {
      // TODO: Do something clever..
    }
}

columnname "User" に odcparameters を使用しても問題ないようです。しかし、プレースホルダー「?」を使用してテーブル名をパラメーターとして追加すると、次のエラーが表示されます: ERROR [HY000] [Microsoft][ODBC Excel Driver] パラメータ 'Pa_RaM002' がテーブル名が必要な場所に指定されました。

OdbcParameterにできない場合、この状況でテーブル名を安全に渡す方法を知っている人はいますか?

4

1 に答える 1

1

SQL でテーブル名と列名をパラメータ化することはできないと思います。そのため、動的 SQL ステートメントを作成するために何らかの方法で文字列連結を使用することになります。

ただし、可能なことは、ステートメントを実行する前にいくつかのチェックを行うことです。実行できるチェックは 2 種類あります。

1. ホワイトリストチェック (より良い解決策)

可能であれば、この方法での使用を許可するテーブルと列のリストを用意してください。ユーザーがテーブルと列を指定するときは、リスト内の要素のみを許可するようにしてください。

2. 動的チェック (危険なソリューション)

このアプローチは、テーブル/列の名前が事前にわかっておらず (動的に作成された場合など)、ホワイトリストを作成できない場合にのみ適用してください。それ以外の場合は、ホワイトリスト アプローチを使用します。

構成されたテーブルと列がデータベースに存在することを確認できます。

たとえば、SQL Server を使用している場合は、次のように情報スキーマ ビューを照会することでこれを行うことができます。

select top 1 COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @tableNameParameter
and COLUMN_NAME = @columnNameParameter
and <additional criteria*>

チェックをあまり頻繁に実行しないようにするために、これらのチェックを、テーブルと列の名前を構成できる Web ページで検証として実行できます。

*警告:テーブルと列が存在することのみを検証すると、ユーザーはデータベース内のすべてのテーブルを検出できるようになります。これを回避するには、SQL に追加の条件を追加して、この方法で使用することを意図したテーブルのみを選択するようにすることができます。たとえば、すべての動的テーブルに特定のプレフィックスを付けることができるため、次のようにすることができます[...] and TABLE_NAME like 'prefix%'


どちらのソリューションを選択する場合でも、セキュリティの観点から重要であることに注意してください。システムのどのコンポーネントがカスタムのテーブル/列の値を書き込んで、これらの各ポイントで検証を適用できるかを十分に注意する必要があります。

于 2013-01-02T15:34:15.110 に答える