2010-02-24 47 views
4

我不想緩存輸入,這看起來像SQL注入。所以我寫的方法:用於在WinForms中檢測SQL注入的正則表達式

 public static bool IsInjection(string inputText) 
    { 


     bool isInj = false; 


     string regexForTypicalInj = @"/\w*((\%27)|(\'))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix"; 
     Regex reT = new Regex(regexForTypicalInj); 
     if (reT.IsMatch(inputText)) 
      isInj = true; 


     string regexForUnion = @"/((\%27)|(\'))union/ix"; 
     Regex reUn = new Regex(regexForUnion); 
     if (reUn.IsMatch(inputText)) 
      isInj = true; 



     string regexForSelect = @"/((\%27)|(\'))select/ix"; 
     Regex reS = new Regex(regexForSelect); 
     if (reS.IsMatch(inputText)) 
      isInj = true; 

     string regexForInsert = @"/((\%27)|(\'))insert/ix"; 
     Regex reI = new Regex(regexForInsert); 
     if (reI.IsMatch(inputText)) 
      isInj = true; 

     string regexForUpdate = @"/((\%27)|(\'))update/ix"; 
     Regex reU = new Regex(regexForUpdate); 
     if (reU.IsMatch(inputText)) 
      isInj = true; 

     string regexForDelete = @"/((\%27)|(\'))delete/ix"; 
     Regex reDel = new Regex(regexForDelete); 
     if (reDel.IsMatch(inputText)) 
      isInj = true; 

     string regexForDrop = @"/((\%27)|(\'))drop/ix"; 
     Regex reDr = new Regex(regexForDrop); 
     if (reDr.IsMatch(inputText)) 
      isInj = true; 

     string regexForAlter = @"/((\%27)|(\'))alter/ix"; 
     Regex reA = new Regex(regexForAlter); 
     if (reA.IsMatch(inputText)) 
      isInj = true; 

     string regexForCreate = @"/((\%27)|(\'))create/ix"; 
     Regex reC = new Regex(regexForCreate); 
     if (reC.IsMatch(inputText)) 
      isInj = true; 

     return isInj; 

    } 

但似乎我犯了一些錯誤,因爲我的代碼沒有檢測到注入。我做錯了什麼?我猜在定義Regex表達式時會出現錯誤嗎?

+1

您首先不使用參數化查詢的原因是什麼?確切地說,是 – JasonTrue 2010-02-24 21:09:40

+0

http://xkcd.com/327/ – Ken 2010-02-24 21:11:50

+1

。參數化查詢=已消毒。用正則表達式來完成解析器的工作=瘋狂。 – JasonTrue 2010-02-24 21:19:59

回答

15

不要試圖用RegEx來做到這一點 - 周圍有太多的方法。請參閱this classic SO有關使用RegEx進行分析的答案 - 它只針對HTML,但仍適用。

你應該使用Parameters,這些都是在BCL和內置了防SQL注入措施

更新:(以下評論)

如果你真的必須分析SQL,不要使用RegEx出於鏈接文章中列出的原因。 RegEx不是解析器,不應該作爲一個使用。

使用SQL解析器 - 這應該有助於消毒嘗試。這裏是one,這裏是another

您可以繼續您的科學調查與這些。

+0

+100,如果我可以:參數化,參數化,參數化.... – davek 2010-02-24 21:09:32

+0

我這樣做是爲了調查(科學)目的。我以後的框架將用於開發勝利形式的應用程序。其他開發人員通常是開發人員,有時不使用參數。所以首先我需要以某種方式在C#代碼中進行保護。 – Vytas999 2010-02-24 21:27:35

+0

@ Vytas999 - 我已經更新了我的回答,請在您的評論之後。 – Oded 2010-02-24 21:42:58

3

不要使用字符串解析或正則表達式來處理這類事情。 SQL語法太複雜,無法用正則表達式可靠地解析。

改用參數化查詢佔位符並避免字符串連接。這將在其根上擊敗SQL注入。

var command = new SqlCommand(connection); 
command.Text = "INSERT INTO foo (a, b, c) VALUES (@a, @b, @c)"; 
command.Parameters.AddWithValue("a", "this is invulnerable"); 
command.Parameters.AddWithValue("b", "to any sort of SQL injection"); 
command.Parameters.AddWithValue("c", "--'; DROP DATABASE"); 
command.ExecuteNonQuery(); 
2

如果你真的想幫助你的「不那麼有經驗的程序員」,你會好起來的嘗試,當他們在他們的代碼做內聯SQL來檢測。編寫一個FxCop規則來發現它不應該太困難。如果將其作爲後期構建過程的一部分,或者如果您有團隊系統,請將規則設置爲構建失敗,他們很快就會掌握它。

0

SQL注入的問題是,用戶輸入被用作SQL語句的一部分。通過使用預準備語句,您可以強制將用戶輸入作爲參數的內容進行處理(而不是作爲SQL命令的一部分)。通過從SQL語法中分離字面值,查詢參數有助於避免此風險。

大多數客戶端API(包括.NET)支持查詢參數化。這允許嵌入用戶輸入作爲參數。參數是用戶輸入值的佔位符,在執行時將被替換。這樣用戶無法注入SQL代碼,因爲整個用戶條目被視爲參數的值,而不是作爲附加到查詢的字符串。

參數化是SQL注入攻擊的最佳解決方案。