SQL文でのパラメーターの使用については知っていますが、好奇心のために、パラメーターを使用する代わりにFormat関数を使用してSQLインジェクションを防ぐのが安全です。
このサンプルのように
sCustomer : string
begin
AdoSql.CommandText:=Format('Select SUM(value) result from invoices where customer=%s',[QuotedStr(sCustomer)]);
end;
SQL文でのパラメーターの使用については知っていますが、好奇心のために、パラメーターを使用する代わりにFormat関数を使用してSQLインジェクションを防ぐのが安全です。
このサンプルのように
sCustomer : string
begin
AdoSql.CommandText:=Format('Select SUM(value) result from invoices where customer=%s',[QuotedStr(sCustomer)]);
end;
期待どおりに機能し、それを破る可能性のあるエッジケースがないと仮定すると、おそらくSQLインジェクションに対して安全です。QuotedStr
(これは決して保証されているわけではありません。Linas がコメントで指摘したように、MySql では\'
引用符をエスケープするために使用できます。他の DBMS にはおそらく同様の機能があります。システムに関する十分な理論的知識を持つ攻撃者は、それらを悪用することができます。)
ただし、QuotedStr が十分に優れていたとしても、パフォーマンスという別の理由でパラメーターを使用することをお勧めします。パラメーターをクエリから分離すると、異なるパラメーターを使用してまったく同じクエリ コードを複数回送信することになります。これを行うと、データベースはクエリの計算で行う多くの作業をキャッシュできるため、DB アクセスが高速になります。パラメータをクエリコード自体に混在させると、それは機能しません(または少なくとも機能しません)。
文字列を連結して 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;
いいえ、Format
SQL インジェクションに対する安全性はありません。その点では、通常の文字列連結と変わりません。
SQL インジェクションに対して何かを行う問題のコードの部分は、 の呼び出しQuotedStr
であり、 の有無にかかわらず使用できますFormat
。ただし、実際のパラメーター化されたクエリほど信頼性は高くありません。
このコンテキストでの の唯一の利点は、文字列テンプレート全体が 1 か所にあることです。したがって、連続した操作でFormat
文字列を作成する必要がある場合よりも、スペースや句読点を間違える可能性が低くなります。+
Delphi のアポストロフィの間で迷子になります。