国足踢进世界杯 / 2025-08-12 13:43:19

2.要查询的原SQL语句。

3.注入的SQL语句

分析示例:

原SQL语句

select COUNT(*) from T_Users where UserName = 'a' and Password ='b'1

语义:要查找(用户名为‘a’,密码为‘b’) 的用户总共有几个. 查询结果为1

注入后的SQL语句

select COUNT(*) from T_Users where UserName = 'a' and Password = 'b' or 1=1 --'1

注入后的语义:查找 (密码是a的,并且用户名是b的,) 或者1=1 的所有用户的数量。 这时候语义发生了改变,查询结果为4

分析:如果用户在输入密码时, 输入的不是b 而是b’ or 1=1- - ,语义将会发生改变,(- -在数据库中是注释的标记)最后查询的结果当然也就不相同了。原语句的查询结果为1,注入后的查询结果为4。

SQL注入的危害

我们刚刚示范了SQL注入带来的查询结果的改变,这个可能会让别有用心的用户熟知我们数据库中的记录条数。或者如果输入的是b’ delect T_Users - - 这时候我们整张表都被删除了,这个带来的后果可想而知。

防止SQL注入–参数化查询

我们的机房重构中D层一直在用参数化查询,但是我当时没有完全理解用参数化查询的用意。直到现在才理解了为什么要用参数化查询和参数化查询如何防止SQL注入的。

public int checkUser(Users user)

{

string sql = "select COUNT(*) from T_Users where UserName = @UserName and Password = @Password";

SqlParameter[] paras ={new SqlParameter ("@UserName",User.username) ,

new SqlParameter ("@Password",User.password)};

int num = sqlhelper.ExecuteNonQuery(sql, paras);

return num ;

}12345678

这是我们用了参数化查询后的效果,我们来分析一下参数化查询是如何防止sql注入的。

select count(*) from T_Users where UserName = ‘a’ and Password = ‘b’ or 1=1- -‘, 是等到 UserName 参数传过来,才会去编译这条 sql语句(sql语句是编译后执行的),而这个时候, 这个拼接的sql 多了 or 选项,这改变了sql语句的本意。

参数化查询:是先编译 这样一条sql, select count (*) from T_Users where = UserName = @UserName and Password = @Password ,和函数的编译一样, 这样的话,以后’b’ or 1=1- - ’ 只能作为 Password 的参数了,,,相当于你去查 ” ‘b’ or 1=1—’ ” 这个密码,而不是 查 “b” 这个密码 或者 ” 1=1 ” 了。 相当于把 or 给屏蔽掉了。or 原来是sql的一项(普通的拼接),现在就是个普通字符串参数(参数化查询) ,不能改变sql语义,也不能改变编译执行计划,所以防止了SQL注入。

示例小结:

正常的命令是程序中的“常量”,能动手脚的只能是可输入的用户名、密码这些可输入的“变量”。 拼接方式是将常量、变量拼在一起编译,才可以在正常的命令后追加命令。参数化的方式仅常量参与编译,就无法追加命令,防止了sql注入。

总结:

参数化查询的方式简单来说就是指用参数参与编译,这样就全是常量了,编译执行计划时没有用到参数,所以命令是确定的。编译后计划便确定了,编译后传参数知识为了运行执行计划,执行计划不变,就不会多出命令,SQL语义就无法改变,防止了sql注入。

2025年一伏二伏三伏表来了!三伏天如何养生?
陵园内的墓碑材质有哪些选择?各有什么优缺点?