2010-02-24 48 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注入攻击的最佳解决方案。