SQL文字列を予期するAPIを使用します。ユーザー入力を取得し、エスケープしてAPIに渡します。ユーザー入力は非常に簡単です。列の値を要求します。そのようです:
string name = userInput.Value;
次に、SQLクエリを作成します。
string sql = string.Format("SELECT * FROM SOME_TABLE WHERE Name = '{0}'",
name.replace("'", "''"));
これで十分ですか?そうでない場合、列の値を安全にする単純なライブラリ関数があります:
string sql = string.Format("SELECT * FROM SOME_TABLE WHERE Name = '{0}'",
SqlSafeColumnValue(name));
APIはデータベースとしてSQLServerを使用します。
SqlParameterの使用はオプションではないため、文字列リテラルの 'を' '(二重引用符ではなく、2つの単一引用符)で置き換えるだけです。それでおしまい。
ダウンボーターになるには:質問の最初の行を読み直します。 「パラメータを使用する」ことも私の腸の反応でした。
編集:はい、SQLインジェクション攻撃について知っています。この引用がそれらに対して脆弱であると思われる場合は、実用的な反例を提供してください。そうではないと思います。
Sqlパラメーターを使用するのが最善ですが、クエリの2300パラメーターに制限があります。ほとんどの場合、これで十分です。しかし、まれに、この制限を超えた場合、これはオプションとして表示されます。
破損のリスクとテストを最小限に抑えながら、大量のアドホックSQLの問題に短時間で対処する必要がある場合は、パラメーター化する代わりに 'を' 'に置き換えることができます。
SqlCommandとEntity Frameworkはexec sp_executesql...
を使用します。
したがって、おそらく独自のエスケープパターンを持つ生の文字列に代わるものがあります。 SqlCommandでは、技術的にパラメーター化されたクエリを使用していますが、基になるSQLコードのADO.Net抽象化をバイパスしています。
したがって、コードはSQLインジェクションを妨げませんが、究極の答えはSqlCommandではなくsp_executesqlです。
そうは言っても、sp_executesqlを使用するSQLインジェクション防止文字列を生成するには、特別な処理要件があると確信しています。
私は検索機能に動的SQL(射撃隊がライフルをロードしているのが聞こえます)を使用していましたが、ユーザーが「O'Reilly」のような姓を持つ誰かを検索すると必ず壊れます。
私は回避策を見つけました(「ハック」を読んでください):
SQLでスカラー値関数を作成し、単一引用符を2つの単一引用符に置き換え、問題のある単一引用符を効果的にエスケープしました。
"... Surname LIKE '%O'Reilly%' AND ..."は、 "... Surname LIKE '%O''Reilly%' AND ..."になります。
この関数は、フィールドに一重引用符が含まれている可能性があると疑われる場合、sql内から呼び出されます。つまり、firstname、lastnameです。
CREATE FUNCTION [dbo].[fnEscapeSingleQuote]
(@StringToCheck NVARCHAR(MAX))
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @Result NVARCHAR(MAX)
SELECT @Result = REPLACE(@StringToCheck, CHAR(39), CHAR(39) + CHAR(39))
RETURN @Result
END
あまりエレガントでも効率的でもありませんが、ピンチのときに機能します。