如何准备语句再次保护下面的语句中的SQL注入

我已经阅读了各种文档(SO post),以及PDO的Prepared语句如何保护用户免于SQL注入。

虽然,我知道它保护用户,因为在准备好的语句中,用户记录直接不在服务器上执行insted我们正在发送位置/命名参数(?/:名称),然后我们发送实际数据在执行语句中,因此它节省我们从SQL注入。

那么,现在,如果我有下面的SQL代码:

$query = "select * from user where id = $user_input_id";

和用户输入id = 1

所以查询将会是这样的:

$query = "select * from user where id = 1"; 

到现在为止,这是完美的。 但是,如果用户entre $ id =“1; DROP TABLE用户;” 所以查询将如下所示:

$query    = "SELECT * FROM users where id=$id";

因此它会执行

$query = "SELECT * FROM users where id=1; DROP TABLE users;";

它的工作原理和用户表将会因为这个查询直接执行而下降:

那么,我已经阅读了准备好的声明可以从这里保存用户:

并准备好如下声明:

$data = "1; DROP TABLE users;"

$db->prepare("SELECT * FROM users where id=?");

$db->execute($data);

在执行语句中,使用Drop table记录正在传递,那么它将不会执行drop table statament? 也执行一些服务器上的部分权利?

任何人都可以请解释如何准确的声明在这里保存用户从SQL注入?

谢谢


如果没有显式设置类型(例如,请参阅PDOStatement::bindValue() ),它会将传递的值视为一个字符串,因此它会有效地执行此操作:

SELECT * FROM users where id='1; DROP TABLE users;'

顺便说一句,这实际上会发生,如果你使用模拟预处理语句( PDO::ATTR_EMULATE_PREPARES ); 没有这个,它会首先发送参数化查询,然后是实际数据。


这就是为什么您可以另外将绑定数据的类型设置为您需要的类型。

$stm->bindParam(":id", $id, PDO:PARAM_INT)

此外,PDO会对数据进行一些转义,并且您提供的字符串不会中断查询; ,但会在数据库中以纯字符串的形式插入。


SQL注入是针对SQL解析步骤的攻击,而不是语句执行步骤。 在这方面,它与其他解析攻击(如跨站脚本攻击和XML注入攻击)具有相似之处。

因为通过使用字符串连接操作符将单个字符串中的代码和(不可信)数据组合在一起的创建SQL语句的常见(破坏)技术允许特制字符串违反语句数据协议的可能性(通常由使用数据中嵌入的字符串分隔符突破数据上下文),并允许攻击者操纵SQL解析器,以执行与最初预期不同的代码。

当使用准备好的语句时,人们告诉解析器'将语句纯粹视为可信代码,并提供一些插槽,我将其插入执行的数据。

当你放下字符串'1; 将表用户'拖放到您使用'?'创建的数据槽中 占位符,该字符串不会被解析器处理,因此它没有机会影响字符串的解析:您使字符串的内容不可能脱离数据上下文。

使用你的例子,数据库将执行相应的语句:

SELECT * FROM users where id =“1; drop table users;”

这是一个非常有效的select语句,根据表中的数据可能返回或不返回行,但几乎肯定不会正常工作。

尽管如此,该方法绕过了SQL注入的尝试。

请注意:使用预准备语句是避免SQL注入攻击的唯一通用方法。 通常,尝试过滤不可信的输入数据会被破坏。

链接地址: http://www.djcxy.com/p/93799.html

上一篇: How prepared statement protect again SQL injection in below statement

下一篇: PGSQL driver support prepared statement?