SQL注入及预防

[size=medium][b]SQL注入原理[/b][/size]
以往Web应用程序访问数据库时一般是采取拼接字符串的形式,比如登录的时候就是根据用户名和密码去查询:
string sql = “select * from user where UserName = ‘” + userName + “’ and Password = ‘” + password + “’”;

其中userName和password两个变量的值是由用户输入的。假设password的值是“' ' or ' ' = ' ' ”,userName的值任意,那变量sql的 值就是:
select * from user where UserName = ‘user’ and Password = ‘’ or ‘’ = ‘’;

因 ’’ =’’ 恒为真,因此只要User表中有数据,不管UserName、Password的值是否匹配,这条SQL命令都能查出记录来。

[size=medium][b]预防措施-参数化查询[/b][/size]
参数化查询(Parameterized Query 或 Parameterized Statement)是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值,这个方法目前已被视为最有效可预防SQL注入攻击 (SQL Injection) 的防御方式。
在使用参数化查询的情况下,数据库服务器不会将参数化的内容视为SQL指令的一部分来处理,而是在数据库完成SQL指令的编译后,才套用参数运行。因此即使参数中含恶意指令,因已编译完成,就不会被数据库所运行。

[size=medium][b]带参数的SQL指令[/b][/size]
1)Microsoft SQL Server
Microsoft SQL Server 的参数格式是以 "@" 字符加上参数名称,也支持匿名参数 "?"。
select * from user where sex=@sex
insert into user(c1, c2, c3, c4) VALUES (@c1, @c2, @c3, @c4)

2)Microsoft Access
Microsoft Access 只支持匿名参数 "?"。
update  user  set c1 = ?, c2 = ?, c3 = ? where c4 = ?

3)MySQL
MySQL 的参数格式是以 "?" 字符加上参数名称而成。
update  user  set c1 = ?c1, c2 = ?c2, c3 = ?c3 where c4 = ?c4

备注:匿名参数“?”,在给参数赋值时一定要按顺序赋值,否则可能执行出错。

[size=medium][b]客户端程序[/b][/size]
1)ADO.NET示例
要查找user表中的男性用户,SQL语句是这样:
select * from user where sex=1

用参数化SQL语句表示为:
select * from user where sex=@sex

对SQL语句中的参数赋值,假如我们要查找user表中所有年龄大于30岁的男性用户,这个参数化SQL语句可以这么写:
select * from user where sex=@sex and age>@age


//实例化Connection对象
SqlConnection connect =newSqlConnection("server=localhost;database=test;uid=root;pwd=''");
//实例化Command对象
SqlCommand command =newSqlCommand("select * from user where sex=@sex and age>@age", connect);

//第一种添加查询参数的例子
command.Parameters.AddWithValue("@sex",true);

//第二种添加查询参数的例子
SqlParameter parameter =newSqlParameter("@age", SqlDbType.Int);//User表age字段是int型
parameter.Value = 30;
command.Parameters.Add(parameter);//添加参数

//将查询结果集以DataTable的方式返回
//实例化DataAdapter
SqlDataAdapter adapter =newSqlDataAdapter(command);
DataTable data =newDataTable();

2)PHP
$sex = ‘男’;
$age = ‘27’;
$query = sprintf("select * from user where sex='%s' and age>'%d'",
mysql_real_escape_string($sex),
mysql_real_escape_string($age));
mysql_query($query);

或者:
$db = new mysqli("localhost", "user", "pass", "database");
$stmt = $mysqli -> prepare("select * from user where sex=? and age>?");
$stmt -> bind_param("sd", $sex, $age);
$sex = ‘男’;
$age = ‘27’;
$stmt -> execute();

3)JDBC
PreparedStatement prep = conn.prepareStatement("SELECT * FROM USERS WHERE USERNAME=? AND PASSWORD=?");
prep.setString(1, username);
prep.setString(2, password);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值