2016-05-13 4 views
0

whereclauseにパラメータを使用しましたが、これは{0}の変数はどうですか? SQLインジェクションを防ぐためにパラメータを作成する必要がありますか?あなたはいけないパラメータとSQLインジェクションasp.net

("...inner join db1.dbo.table1.id on db2.dbo.table2.id = {0}.dbo.table3.id where [email protected]",abc) 

var abc = ddl2.SelectedItem.Text; 

cmd.Parameters.AddWithValue("@name", ddl1.selectedvalue); 

答えて

3

私の知る限り、実際にはデータベース名/テーブル名を「パラメタイズ」することはできません。

この場合、ユーザーがddl2.SelectedItem.Textを希望どおりに変更できるため、String.FormatはSQLインジェクションを解決しません。

データベース名に動的な値が必要な場合は、その値をconstとして保存するか、完全な制御権を持っているか、送信されない、またはクライアント側では解釈されない場所に保存することをお勧めします。

+0

答えをありがとう。私はこれを調べます。 –

-2

は、など(オブジェクト関係マッピング)、すなわち、エンティティフレームワークまたはn休止あなたは私はあなたが任意のORMを使用することをお勧めします。この

var abc = ddl2.SelectedItem.Text; 
string.format("...inner join db1.dbo.table1.id on db2.dbo.table2.id = {0}.dbo.table3.id where [email protected]",abc) 
cmd.Parameters.AddWithValue("@name", ddl1.selectedvalue); 
+0

ご確認いただきありがとうございます。 –

+0

特にSQLインジェクションからの保護についての質問では、これは良い答えではありません。 –

0

ようString.Formatのを使用している場合ABBCのパラメータを作成して必要linqを使ってクエリを書くと、SQLインジェクションからのアプリケーションを防ぐことができます。

+0

私もこれを調べますが、私は今持っているもので安全ですか? –

+0

よく私はそうは思わない、ちょうど例のためにハッカーがSQLを注入しようとしている場合、彼はfirebugからドロップダウンリストを変更することができ、あなたのコードに彼のSQLを注入することができます..あなたが理解することを願って – Harvey

0

残念ながら、Abbathがすでに述べたように、このタイプの構造体はパラメータ化できません。 Abbathが述べたように、最良の解決策は、あなたの絶対的な支配下にそのような議論を残すことですが、そのような構成が必要な時があり、それらを完全に制御することは不可能かもしれません。

この場合、引数をエスケープすることをお勧めします。この場合、サンプルコードで{0}で表されるDB名。 これを達成するには、2つの潜在的なメカニズムがあります。

a)は、クエリに

優位性をパラメータ化することを可能にするメカニズムを作成します:あなたは、などの任意のドライバ(.NET、ODBC、から同じ溶液を再利用することができます)

短所:もう少し作業します。この場合、selectを直接使用することはありません。例えば、(私はあなたのコードのように、内部結合持っている簡単な例を含めています)

:あなたは、通常と同じようにこの時点で

CREATE PROC sp_MyQuery(@target_db_name sysname, @name nvarchar(100)) 
AS 
BEGIN 
    DECLARE @cmd nvarchar(max) 
    DECLARE @parameters nvarchar(max) 
    SELECT @cmd = N'SELECT * FROM msdb.sys.objects inner join ' 
     + quotename(@target_db_name) + N'.sys.sql_modules 
     on msdb.sys.objects.object_id = ' 
     + quotename(@target_db_name) + N'.sys.sql_modules.object_id WHERE name = @name' 
    print @cmd -- See the command before it is executed. 
    set @parameters = N'@name nvarchar(100)' 
    EXEC sp_executesql @cmd, @parameters, @name = @name 
END 
go 

-- Example of usage 
DECLARE @target_db_name sysname = 'msdb' 
DECLARE @name nvarchar(100) = 'sp_help_operator' 
EXEC sp_MyQuery @target_db_name, @name 
go 

、あなたはSqlParameterオブジェクトを使用することができます。たとえば:

sqlcmd.CommandText = @"[dbo].[sp_MyQuery]"; 
sqlcmd.CommandType = System.Data.CommandType.StoredProcedure; 
sqlcmd.Parameters.AddWithValue("@target_db_name", ddl0.selectedvalue); 
sqlcmd.Parameters.AddWithValue("@name", ddl1.selectedvalue); 
SqlDataReader reader = sqlcmd.ExecuteReader(); 

b)は、あなたのCLRコード内

利点をDB名をエスケープ:アプリケーション固有のソリューション、あなたは潜在的なユニコード-DBと注意する必要があります。

デメリットを実装する方が簡単照合翻訳の問題例(上記と同じクエリ)の場合

sqlcmd.CommandText = String.Format(@" 
    SELECT * FROM msdb.sys.objects inner join [{0}].sys.sql_modules on msdb.sys.objects.object_id = [{0}].sys.sql_modules.object_id WHERE name = @name;", 
    ddl0.selectedvalue.Replace("]", "]]")); 
sqlcmd.CommandType = System.Data.CommandType.Text; 
sqlcmd.Parameters.AddWithValue("@name", ddl1.selectedvalue); 
SqlDataReader reader2 = sqlcmd.ExecuteReader(); 

私は通常、(a)は、それは可能ですが、両方のソリューションを使用すると、SQLインジェクションから保護する必要があるたびソリューションを使用することをお勧めします。

BTW。次のリンクもまた役に立つかもしれません:https://blogs.msdn.microsoft.com/raulga/2007/01/04/dynamic-sql-sql-injection/

私は希望情報が役立ちます。

+0

詳細情報をお寄せいただきありがとうございますが、オプションBは実際にどのように機能しますか?私は周りを見回し、まだそれをかなり理解していない。 –

+0

これは、 '['と ']'の中でオブジェクト名を引用することによって行われます。たとえば、 'CREATE TABLE [ta'b]] le](data int) 'です。ご覧のとおり、 'ta'b 'le'テーブルにはエスケープする必要がある文字が含まれています。 パラメータ化できないSQL文を作成する場合は、オブジェクト名の末尾を示す ']'文字をエスケープする必要があります。 'DECLARE @name sysname = N'ta''b 'le'; DECLARE @cmd nvarchar(max)= N'SELECT * FROM '+ quotename(@name);印刷する@cmd ; EXEC(@ cmd); - "SELECT * FROM [ta'b]] le]" ' –

関連する問題