7

SQL文でのパラメーターの使用については知っていますが、好奇心のために、パラメーターを使用する代わりにFormat関数を使用してSQLインジェクションを防ぐのが安全です。

このサンプルのように

sCustomer : string
begin
 AdoSql.CommandText:=Format('Select SUM(value) result from invoices where customer=%s',[QuotedStr(sCustomer)]);
end;
4

3 に答える 3

11

期待どおりに機能し、それを破る可能性のあるエッジケースがないと仮定すると、おそらくSQLインジェクションに対して安全です。QuotedStr(これは決して保証されているわけではありません。Linas がコメントで指摘したように、MySql では\'引用符をエスケープするために使用できます。他の DBMS にはおそらく同様の機能があります。システムに関する十分な理論的知識を持つ攻撃者は、それらを悪用することができます。)

ただし、QuotedStr が十分に優れていたとしても、パフォーマンスという別の理由でパラメーターを使用することをお勧めします。パラメーターをクエリから分離すると、異なるパラメーターを使用してまったく同じクエリ コードを複数回送信することになります。これを行うと、データベースはクエリの計算で行う多くの作業をキャッシュできるため、DB アクセスが高速になります。パラメータをクエリコード自体に混在させると、それは機能しません(または少なくとも機能しません)。

于 2012-06-20T21:14:54.963 に答える
6

文字列を連結して SQL 文字列を構築するときはいつでも、それらの文字列へのアクセスがどれほど安全だと考えていても、インジェクション攻撃の可能性があります。ご存じのとおり、誰かがデバッガー内でアプリを実行し、 の結果にブレークポイントを設定し、表示QuotedStr()を許可する前にその内容を変更する可能性Format()があります。

実際の SQL パラメータを使用するのが最も安全な方法です。インジェクションを回避するだけでなく、SQL エンジンが独自のニーズに合わせてパラメーターをフォーマットする最善の方法を決定できるようになるため、独自のコードで値をフォーマットすることを心配する必要がなくなります。言語 (Delphi など)。サーバー側で SQL ステートメントを事前に準備してからコードで実行できるというパフォーマンス上の利点は言うまでもありません。これにより、クライアントとサーバー間のトラフィックが大幅に削減され、全体的なパフォーマンスが向上します。

var
  sCustomer : string 
begin 
  AdoSql.CommandText := 'Select SUM(value) result from invoices where customer=:Customer'; 
  AdoSql.Prepared := True;
  ... 
  AdoSql.Parameters['Customer'].Value := sCustomer; 
  AdoSql1.ExecSQL;
  ...
  AdoSql.Parameters['Customer'].Value := sCustomer;
  AdoSql1.ExecSQL;
  ...
  AdoSql.Prepared := False;
end; 
于 2012-06-20T22:11:56.633 に答える
5

いいえ、FormatSQL インジェクションに対する安全性はありません。その点では、通常の文字列連結と変わりません。

SQL インジェクションに対して何かを行う問題のコードの部分は、 の呼び出しQuotedStrであり、 の有無にかかわらず使用できますFormat。ただし、実際のパラメーター化されたクエリほど信頼性は高くありません。

このコンテキストでの の唯一の利点は、文字列テンプレート全体が 1 か所にあることです。したがって、連続した操作でFormat文字列を作成する必要がある場合よりも、スペースや句読点を間違える可能性が低くなります。+Delphi のアポストロフィの間で迷子になります。

于 2012-06-21T04:04:13.180 に答える