1. ホーム
  2. asp.net

[解決済み] Sqlインジェクションを防ぐには、本当にパラメータだけで良いのでしょうか?

2023-07-10 11:06:25

質問

私は同僚とSOの両方で、SQLクエリ、特に.NETアプリケーションでパラメータを使用することの良さについて説教してきました。私は、SQL インジェクション攻撃に対する免疫力を与えるものとして、それらを約束するところまで行きました。

しかし、これが本当に真実なのかどうか、疑問に思い始めています。パラメータ化されたクエリに対して成功する既知の SQL インジェクション攻撃はあるのでしょうか? たとえば、サーバー上でバッファ オーバーフローを引き起こすような文字列を送ることはできるでしょうか?

もちろん、Web アプリケーションが安全であることを保証するための他の考慮事項 (ユーザー入力のサニタイズやその他諸々) がありますが、今は SQL インジェクションについて考えています。私は、MsSQL 2005 と 2008 が私の主要なデータベースであるため、これらに対する攻撃に特に興味がありますが、すべてのデータベースが興味深いものです。

編集:私がパラメータとパラメータ化されたクエリによって何を意味するのかを明確にするために。パラメータを使用することで、私は SQL クエリを文字列で構築する代わりに、quot;変数" を使用することを意味します。

だから、これを行う代わりに

SELECT * FROM Table WHERE Name = 'a name'

こうするんです。

SELECT * FROM Table WHERE Name = @Name

で、クエリ/コマンドオブジェクトの @Name パラメータの値を設定します。

どのように解決するのですか?

プレースホルダー はインジェクションを防ぐのに十分です。 それでもバッファオーバーフローの危険性はありますが、これは SQL インジェクションとはまったく異なる種類の攻撃です (攻撃ベクトルは SQL 構文ではなくバイナリです)。 渡されるパラメータはすべて適切にエスケープされるので、攻撃者が「生きたSQL」のように扱われるデータを渡す方法は何もありません。

プレースホルダーの内部で関数を使用することはできません。また、プレースホルダーは文字列リテラルとしてエスケープされ引用されるため、カラムやテーブル名として使用することはできません。

しかし、もしあなたが パラメータ の一部として 文字列連結 を動的クエリの中で使用した場合、文字列はエスケープされずにリテラルとなるため、インジェクションの対象となります。 パラメータに他の型(例えば整数)を使うのは安全です。

のような値を設定するために use input を使用している場合、そのようなことはありません。 security_level のような値を設定するために use input を使用している場合、誰かがあなたのシステムの管理者になり、自由に使えるようにすることができます。 しかし、これは単なる基本的な入力検証であり、SQL インジェクションとは何の関係もありません。