2016-04-19 7 views
0
string[] theParms = ['parm1', 'parm2']; 
string theQuery = "SELECT something, somethingAgain " + 
        "FROM aDBTable " + 
        "WHERE something = '{?}'" + 
        "AND something <> '{?}'"; 

でクエリでパラメータを交換してください。C#が、私は<strong>theParms</strong>で定義されたPARMSで{?}さんを交換する必要が午前定義された値

は、私は、文字列をループするために使用して、見つかったそれぞれを置き換えることができ、{?}対応PARM値とにおけるループの何らかのタイプC#はありますか?このような

何か:

まずループ:

SELECT something, somethingAgain 
FROM aDBTable 
WHERE something = 'parm1' AND something <> '{?}' 

第二のループ:

SELECT something, somethingAgain 
FROM aDBTable 
WHERE something = 'parm1' AND something <> 'parm2' 

REGEX以上を行うことができ、共通のフレームワークの機能のいくつかの種類がありますか?あなたが自分でそれを処理する必要はありません

SQLインジェクションのチェック

bool injectionCheckin = new injectionCheck().inCheck(theFinalQuery); 

public class injectionCheck 
{ 
    public bool inCheck(string queryString) 
    { 
     var badWords = new[] { 
      "EXEC", "EXECUTE", ";", "-", "*", "--", "@", 
      "UNION", "DROP","DELETE", "UPDATE", "INSERT", 
      "MASTER", "TABLE", "XP_CMDSHELL", "CREATE", 
      "XP_FIXEDDRIVES", "SYSCOLUMNS", "SYSOBJECTS", 
      "BC_HOME_ADDRESS1", "BC_HOME_ADDRESS2", "BC_HOME_CITY", "BC_HOME_COUNTY", "BC_HOME_POSTAL", "BC_MAIL_ADDRESS1", 
      "BC_MAIL_ADDRESS2", "BC_MAIL_CITY", "BC_MAIL_COUNTY", "BC_MAIL_POSTAL", "BC_MAIL_STATE", "FLSA_STATUS", "GRADE", 
      "GRADE_ENTRY_DT", "HIGHEST_EDUC_LVL", "LAST_INCREASE_DT", "BC_SALP_DESCR", "BC_SALP_DESCRSHORT", "SAL_ADMIN_PLAN" 
     }; 
     string pattern = "(?<!\\w)(" + Regex.Escape(badWords[0]); 

     foreach (var key in badWords.Skip(1)) 
     { 
      pattern += "|" + Regex.Escape(key); 
     } 

     pattern += ")(?!\\w)"; 

     dynamic _tmpCount = Regex.Matches(queryString, pattern, RegexOptions.IgnoreCase).Count; 

     if (_tmpCount >= 1) 
      return true; 
     else 
      return false; 
    } 
} 
+1

注射の問題を避けるためにパラメータを使うべきでしょうが、 '{?}'の最初のインスタンスをあなたのパラメータに置き換える単純な 'for'ループとは何か? – Adwaenyth

+0

@Adwaenythループでは、{?} ...第3回目の発生などの第2回目の発生はどうですか? – StealthRT

+1

実際には、パラメータ化されたクエリを使用します。 – Pikoh

答えて

2

String.Formatを使用しないのはなぜですか。

string[] theParms = new string[] { "parm1", "parm2" }; 
string theQuery = @"SELECT something, somethingAgain 
        FROM aDBTable 
        WHERE something = '{0}' 
        AND something <> '{1}'"; 
var res = string.Format(theQuery, theParms); 

結果:

SELECT something, somethingAgain 
     FROM aDBTable 
     WHERE something = 'parm1' 
     AND something <> 'parm2' 
+0

ニーステオ。これは、私がやっていることに対してうまくいくはずです。 – StealthRT

+0

{0}、{1}などの代わりに{?}を使用するためにこのコードを変更することは可能でしょうか? – StealthRT

+0

@StealthRTこれは方法がないと思います。 [ここでもう少し詳しく](http://stackoverflow.com/a/1426629/1849444)。 –

-1

。代わりに、ADO.NETでは、パラメータを定義してその値を設定できます。ここのサンプルを参照してください。 MSDN

+0

これは単なるコメントです。その質問に対する真の答えはありません。 – HimBromBeere

1

どちらの場合でも実行したい場合は、次のように耳障りなことなく行うことができます。

string theQuery = String.Format("SELECT something, somethingAgain " + 
           "FROM aDBTable " + 
           "WHERE something = '{0}'" + 
           "AND something <> '{1}'", 
           theParams[0], theParams[1]); 
+2

SqlInjectionの後の臭い。 – HimBromBeere

+1

**良いアイデア** ..それは注射をチェックした後**それは私のケースではクエリを形成します。 – StealthRT

+0

@StealthRT注射の有無はどこから確認できますか? – HimBromBeere

0

あなたはその後、それは間違いなくはるかに良いString.Format

を使用することですあなたは、注射のためにチェックして見てますが、各インスタンスに

for(int i = 0; i < theParms.GetLength(0); i++) 
{ 
    string[] tempStrings = new string[]{ theQuery.Substring(0,theQuery.IndexOf("{?}") - 1), 
    theQuery.Substring(theQuery.IndexOf("{?}"), 3), 
    theQuery.Substring(theQuery.IndexOf("{?}") + 4) } 
    tempStrings[1] = tempStrings[1].Replace("{?}", theParms[i]); 
    theQuery = String.Join("", tempStrings); 
} 

を見つけることIndexOfとサブストリングを使用することができます

1

注射とそのすべてを避けるために、なぜあなたは、クエリがプリコンパイルし、実行時にそれをロードする必要が得ることができない、少なくとも場合...

string[] theParms = // initialization 
string theQuery = // initialization 

SqlCommand cmd = new SqlCommand(/* enter connection string */, theQuery) 

for(int i = 0; i < theParams.Length; i++) 
{ 
    int index = cmd.Text.IndexOf("{?}"); 
    if(index > -1) 
    { 
     string pName = string.Format("@p{0}", i); 
     cmd.Text = cmd.Text.Remove(index, 3).Insert(index, pName); 
     cmd.Parameters.Add(new SqlParameter() { Name = pName, Value = theParms[i] }); 
    } 
} 

alltogether手動注入のチェックを避ける必要があること:あなたはこのようにそれをしません。それ以外の場合は、SqlCommandのテキストを適切に定式化すれば、ループなど何も必要ありません。ただ、簡単な初期設定:

SqlCommand cmd = new SqlCommand(/* enter connection string */, "SELECT something, somethingAgain FROM aDBTable WHERE something = @p0 AND something <> @p1"); 
cmd.Parameters.Add(new SqlParameter() { Name = "@p0", Value = theParms[0] }); 
cmd.Parameters.Add(new SqlParameter() { Name = "@p1", Value = theParms[1] }); 
2

必ずparameterized queriesして、SQL-コマンドを作成:

using (SqlConnection conn = new SqlConnection(DatabaseConnectionString)) 
using (SqlCommand cmd = conn.CreateCommand()) 
{ 
    var @params = new Dictionary<string, object>{ 
     { "something", myValue }, 
     { "somethingDifferent", anotherValue }, 
    }; 

    cmd.CommandText = "SELECT something, somethingAgain " + 
       "FROM aDBTable " + 
       "WHERE something = @something'" + 
       "AND something <> @somethingDifferent'"; 
    foreach (KeyValuePair<string, object> item in values) 
    { 
     cmd.Parameters.AddWithValue("@" + item.Key, item.Value); 
    } 

    DataTable table = new DataTable(); 
    using (var reader = cmd.ExecuteReader()) 
     { 
      table.Load(reader); 
      return table; 
     } 
    } 
} 

これは、SQLインジェクションのすべての並べ替えを防ぎ、あなたは非常に厄介であるbadlistであなたと任意の奇妙なチェックをwon't実際にあなたを妨げることはありません。たとえば、エスケープしてリストを簡単に回避することができます。具体的には、あなたが望むだけの準備ができているメソッドがすでに存在する場合、なぜあなた自身の検証を書くのですか?

+0

私はもっと同意できませんでした – Pikoh

関連する問題