ADO.NET笔记——SQL注入攻击
2015-03-20 15:22
211 查看
相关知识:
可以通过字符串的拼接来构造一个SQL命令字符串,但是SQL命令字符串的拼接确是造成“SQL注入攻击”的重要原因。
考虑下列例子:从ProductCategory表中检索出Name为“Bikes”的类别信息。(示例数据库采用红皮书的数据库:AdventureWorks_WroxSSRS2012)
如果要凭借字符串,将写成:
请注意:单引号是字符串的起止标记。
但是,如果name变量不是由程序硬编码,而是由用户输入(比如,从页面输入框),那么就有可能有“非法”输入。例如:
请注意:在Bikes之后添加了一个单引号,以便与"… Name='" + name + "'"构成一个语句合法的SQL语句,成为下面的样子而被执行:
在这种情况下,strCmd将首先执行SELECT语句,然后执行DELETE语句。
这种情况极其危险。其根源在于单引号作为字符串的起止标记,用户非法输入的字符串被程序的SQL字符串拼接后,对数据库造成了严重威胁。这被称为SQL注入攻击。
因为注入攻击是由于单引号引起的,所以,很自然的一种缓解的办法就是,不要让单引号解释成为“字符串的起止符”,而是仅仅作为单引号符号。
在SQL中,如果要表示一个单引号符号,需要使用:''。(这不是一个双引,而是两个单引连这写。)
因此,如果把命令字符串中的所有单引号都替换成为两个单引号,就能有效减少SQL注入攻击:
代码示例:
程序分析:
程序本意是:如果userName和password在数据中匹配存在,那就返回该用户对应的AccountID,表示登陆成功;如果不匹配,那就表示失败。
但是经过设计一个SQL注入攻击的字符串(见示例代码),无论输入怎么样的用户名和密码,最终都会登陆成功。
取消strCmd = strCmd.Replace("'", "''");的注释,再次运行程序,将抛出一个SQL异常,这就表明SQL语句被认为不符合语法要求,SQL注入攻击失败。
可以通过字符串的拼接来构造一个SQL命令字符串,但是SQL命令字符串的拼接确是造成“SQL注入攻击”的重要原因。
考虑下列例子:从ProductCategory表中检索出Name为“Bikes”的类别信息。(示例数据库采用红皮书的数据库:AdventureWorks_WroxSSRS2012)
如果要凭借字符串,将写成:
string name = "Bikes"; string strCmd = "SELECT ProductCategoryID, Name FROM Production.ProductCategory WHERE Name='" + name + "'";
请注意:单引号是字符串的起止标记。
但是,如果name变量不是由程序硬编码,而是由用户输入(比如,从页面输入框),那么就有可能有“非法”输入。例如:
string name = "Bikes'; DELETE FROM Production.ProductCategory;'"; string strCmd = "SELECT ProductCategoryID, Name FROM Production.ProductCategory WHERE Name='" + name + "'";
请注意:在Bikes之后添加了一个单引号,以便与"… Name='" + name + "'"构成一个语句合法的SQL语句,成为下面的样子而被执行:
"SELECT ProductCategoryID, Name FROM Production.ProductCategory WHERE Name='Bikes'; DELETE FROM Production.ProductCategory;";
在这种情况下,strCmd将首先执行SELECT语句,然后执行DELETE语句。
这种情况极其危险。其根源在于单引号作为字符串的起止标记,用户非法输入的字符串被程序的SQL字符串拼接后,对数据库造成了严重威胁。这被称为SQL注入攻击。
因为注入攻击是由于单引号引起的,所以,很自然的一种缓解的办法就是,不要让单引号解释成为“字符串的起止符”,而是仅仅作为单引号符号。
在SQL中,如果要表示一个单引号符号,需要使用:''。(这不是一个双引,而是两个单引连这写。)
因此,如果把命令字符串中的所有单引号都替换成为两个单引号,就能有效减少SQL注入攻击:
string strCmd = "SELECT ProductCategoryID, Name FROM Production.ProductCategory WHERE Name='" + name + "'"; string strCmdEncoded = strCmd.Replace("'", "''");
代码示例:
static void Main(string[] args) { string userName = "xxx"; string password = "xxx' OR '1'='1"; //构造一个可能产生SQL注入攻击的字符串 string strCmd = "SELECT AccountID FROM Account WHERE AccountName='" + userName + "' AND Password='" + password + "'"; //下面的语句把单引号替换为两个单引号,从而使之不再代表字符串的起止,进而消除了SQL注入攻击 //strCmd = strCmd.Replace("'", "''"); string strConn = @"server=Joe-PC;database=AccountDBforSQLInjection;uid=sa;pws=root"; SqlConnection conn = new SqlConnection(strConn); conn.Open(); SqlCommand cmd = new SqlCommand(strCmd, conn); SqlDataReader dr = cmd.ExecuteReader(); if (dr.Read()) { Console.WriteLine("登录成功!"); } else { Console.WriteLine("用户名或密码错误!"); } conn.Close(); }
程序分析:
程序本意是:如果userName和password在数据中匹配存在,那就返回该用户对应的AccountID,表示登陆成功;如果不匹配,那就表示失败。
但是经过设计一个SQL注入攻击的字符串(见示例代码),无论输入怎么样的用户名和密码,最终都会登陆成功。
取消strCmd = strCmd.Replace("'", "''");的注释,再次运行程序,将抛出一个SQL异常,这就表明SQL语句被认为不符合语法要求,SQL注入攻击失败。
相关文章推荐
- ADO.NET笔记——带参数的查询防止SQL注入攻击
- ADO.NET的数据提供程序和数据连接——ADO.NET学习&应用笔记之二
- 有关存储过程和ADO.Net的笔记
- ADO.NET学习笔记
- C#学习笔记之五(ADO.net)
- ADO.NET 学习笔记
- [2004-8-4]VB.Net学习笔记,使用ADO.Net对象访问数据库,将结果写入ListView
- ADO.net 2.0 学习笔记
- ado.net 学习笔记
- ADO.net学习笔记
- C#学习笔记之五(ADO.net)
- ASP.NET学习笔记之ADO.NET(一)
- ADO.NET的数据提供程序和数据连接——ADO.NET学习&应用笔记之二
- 转摘:ADO.NET 学习笔记
- ADO.NET开发总结(学习笔记)
- 执行数据库命令(Command对象)——ADO.NET学习&应用笔记之三
- [随笔]有关存储过程和ADO.Net的笔记
- [ASP.NET学习笔记之三]ADO.NET开发最佳实践
- C#-ADO.NET 笔记(一直补充...)
- ADO.NET 相关笔记(2008-5-25)