PHP代码如何防范SQL注入

SQL注入是个常见却又很严重的问题,根源来自于对SQL语句的拼接。使用PDO参数绑定可以从根本上解决SQL注入,例如:

$id = 1;
$sql = 'select * from user where id = :id';
$pdo = $dbh->prepare($sql);
$pdo->bindValue(':id', $id, \PDO::PARAM_INT);
$pdo->excute();
$result = $pdo->fetch(\PDO::FETCH_ASSOC);

但是,很多时候我们不得不拼接字符串,比如使用IN操作的时候,参数绑定就会显得不够灵活,你无法预知参数的个数。下面的方式是不支持的:

$ids = "1,2,3,4";
$sql = 'select * from user where id IN (:ids)';
$pdo = $dbh->prepare($sql);
$pdo->bindValue(':ids', $ids, \PDO::PARAM_INT);
$pdo->excute();
$result = $pdo->fetch(\PDO::FETCH_ASSOC);

所以,我们有些场景下还是需要拼接SQL语句的。如何在拼接SQL语句的情况下确保安全呢?

有人可能会想到,使用htmlspecialchars转换单双引号是不是就可以?例如:

$ids = htmlspecialchars("1,2,3,4", ENT_QUOTES);
$sql = 'select * from user where id IN (' . $ids . ')';
$pdo = $dbh->prepare($sql);
$pdo->excute();
$result = $pdo->fetch(\PDO::FETCH_ASSOC);

仅仅这样就可以吗?显然是不行的,如果$id为:

$ids = htmlspecialchars("1,2,3,4) OR 1=1 ", ENT_QUOTES);
$sql = 'select * from user where id IN (' . $ids . ')';
$pdo = $dbh->prepare($sql);
$pdo->excute();
$result = $pdo->fetch(\PDO::FETCH_ASSOC);

SQL注入就成功了!

简单的认为防SQL注入就是过滤单双引号,是非常错误的认识。

其实,SQL拼接导致注入成功,根本原因在于,拼接的内容中除了参数外,混入了SQL片段或者表达式。如果保证拼接的仅仅只有参数,就能解决这个问题了。

具体做法是:

1 所有参数过滤引号

2 所有参数使用引号包裹

只要遵循以上原则,SQL拼接也可以安全了。

代码示例:

$sql = " select * from user where id = '". htmlspecialchars($id). "' ";

 

转载于:https://my.oschina.net/crazymus/blog/3086087

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值