服务器 > 网络安全 > 脚本攻防

使用参数化查询防止SQL注入漏洞

53人参与 2011-03-05 脚本攻防

sql注入的原理

以往在web应用程序访问数据库时一般是采取拼接字符串的形式,比如登录的时候就是根据用户名和密码去查询:

string sql = "select top 1 * from [user] where username = '" + username + "' and password = '" + password + "'";

其中username和password两个变量的值是由用户输入的。在username和password都合法的情况下,这自然没有问题,但是用户输入是不可信的,一些恶意用户只要用一些技巧,就可以绕过用户名、密码登录。

假设password的值是"1' or '1' = '1",username的值随便取,比如是"abc",那变量sql的值就是:

"select top 1 * from [user] where username = 'abc' and password = '1' or '1' = '1'"

由于'1' = '1'恒为真,因此只要user表中有数据,不管username、password的值是否匹配,这条sql命令准能查出记录来。就这样,登录系统就被破解了。

以往的防御方式

以前对付这种漏洞的方式主要有三种:

参数化查询

近年来,自从参数化查询出现后,sql注入漏洞已成明日黄花。

参数化查询(parameterized query 或 parameterized statement)是访问数据库时,在需要填入数值或数据的地方,使用参数 (parameter) 来给值。

在使用参数化查询的情况下,数据库服务器不会将参数的内容视为sql指令的一部份来处理,而是在数据库完成sql指令的编译后,才套用参数运行,因此就算参数中含有指令,也不会被数据库运行。access、sql server、mysql、sqlite等常用数据库都支持参数化查询。

在asp程序中使用参数化查询

asp环境下的参数化查询主要由connection对象command对象完成。

access数据库只支持匿名参数,在传入参数的位置用问号代替即可。sql server数据库虽然支持匿名和非匿名的参数,但是在asp中也仅能使用匿名参数。

var conn = server.createobject("adodb.connection");
conn.connectionstring = "provider=microsoft.jet.oledb.4.0;data source=" + server.mappath("test.mdb");
conn.open();

var cmd = server.createobject("adodb.command");
cmd.activeconnection = conn;
cmd.commandtype = 1;
cmd.commandtext = "select top 1 * from [user] where username = ? and password = ?";
cmd.parameters.append(cmd.createparameter("@username", 200, 1, 20, "user01"));
cmd.parameters.append(cmd.createparameter("@password", 200, 1, 16, "123456"));

var rs = cmd.execute();
response.write(rs("userid").value);

rs.close();
conn.close();

在asp.net程序中使用参数化查询

asp.net环境下的查询化查询也是通过connection对象和command对象完成。如果数据库是sql server,就可以用有名字的参数了,格式是“@”字符加上参数名

sqlconnection conn = new sqlconnection("server=(local)\\sql2005;user id=sa;pwd=12345;initial catalog=testdb");
conn.open();

sqlcommand cmd = new sqlcommand("select top 1 * from [user] where username = @username and password = @password");
cmd.connection = conn;
cmd.parameters.addwithvalue("username", "user01");
cmd.parameters.addwithvalue("password", "123456");

sqldatareader reader = cmd.executereader();
reader.read();
int userid = reader.getint32(0);

reader.close();
conn.close();

mysql的参数格式与sql server有点区别,是以“?”加上参数名

mysqlconnection conn = new mysqlconnection("server=127.0.0.1;uid=root;pwd=12345;database=test;");
conn.open();

mysqlcommand cmd = new mysqlcommand("select * from `user` where username = ?username and password = ?password limit 1");
cmd.connection = conn;
cmd.parameters.addwithvalue("username", "user01");
cmd.parameters.addwithvalue("password", "123456");

mysqldatareader reader = cmd.executereader();
reader.read();
int userid = reader.getint32(0);

reader.close();
conn.close();

(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

后台登入框注入拿shell步骤

03-22

IPC$ Password Crack BAT

08-04

PowerShell防止脚本注入攻击分享

03-22

PHPCMS 信息泄露以及任意删除文件漏洞

05-25

反常规and 1=1的or 1=2注入技巧

03-22

phpcms SQL注入漏洞 adsclass.php 页面过滤不严

05-24

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论