mysql prepare 防注入_使用 PDO 的 prepare 预处理,能 100%防止 SQL 注入吗?

ovear

2017-05-20 22:02:29 +08:00

但为什么你不翻译完?或者我们通过同一个链接看到的版本不是一个? LOL

>翻译完你给钱? 还有一种可能,要么是我的语文水平太差,要么是你英语太差

要点是这样的,这是那个 PO 主的 Demo:

$pdo->query('SET NAMES gbk');

$var = "\xbf\x27 OR 1=1 /*";

$query = 'SELECT * FROM test WHERE name = ? LIMIT 1';

$stmt = $pdo->prepare($query);

$stmt->execute(array($var));

注意,他没有用 $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

> 根据 https://secure.php.net/manual/zh/pdo.setattribute.php

> PDO::ATTR_EMULATE_PREPARES 启用或禁用预处理语句的模拟。 有些驱动不支持或有限度地支持本地预处理。使用此设置强制 PDO 总是模拟预处理语句(如果为 TRUE ),或试着使用本地预处理语句(如果为 FALSE )。如果驱动不能成功预处理当前查询,它将总是回到模拟预处理语句上。 需要 bool 类型。

> 默认情况为 true,存在我翻译的问题

其实到这就不用看了,因为后面肯定会有问题:服务器所认为的链接字符集被设置成了 gbk,本地的未改变,而且 prepare 是在本地。

> 所以你想表达生命,再复述我的内容一遍?

然后那个 PO 主就挑了个 Easy Target,0xbf27 => addslashes() => 0xbf5c27 ( 0x5c == '\') => 字符串:縗'。

所以自然注入了。

这就是问题。所以这是一种 Charset Attack,利用字符串变形进行攻击。防御的方式也说了:

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

> However, be aware that PDO will silently fallback to emulating statements that MySQL can't prepare natively

> This will usually result in a true prepared statement (i.e. the data being sent over in a separate packet from the query). However, be aware that PDO will silently fallback to emulating statements that MySQL can't prepare natively: those that it can are listed in the manual, but beware to select the appropriate server version).

下面是废话, 对 beware to select the appropriate server version 理解有问题,这不是解决方案,是让你注意看文档的时候选择正确的文档去看,因为不同版本的 MySQL fallback 的条件不同。

我们再看回答主的第一句话

>> I'm adapting this answer to talk about PDO...

>> adapting this answer

>>The short answer is yes, yes there is a way to get around mysql_real_escape_string().

所以这个问题产生的过程是

1)用了会 fallback 的 sql 语句,PDO 认为不能进行 MySQL native prepare,进行本地摸你

2)PHP 调用 mysql_real_escape_string()

3)mysql_real_escape_string 在某些版本下有 BUG,会导致过滤失败

4)PDO 直接把拼接的 SQL 发过去了

5)被注入了

另外,PHP 官方已经写得很清楚了,设置 charset 的时候,要在初始化的时候进行。你错误的使用了 PDO,导致 PDO 本身失效,能怪谁呢?

> https://secure.php.net/manual/zh/ref.pdo-mysql.connection.php

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值