我是PDO的新手,对不起,如果你觉得我在问愚蠢的问题。 没有Bind_param的普通和简单的PDO Prepared语句:
$sql = $db->prepare('SELECT * FROM employees WHERE name = ?');
$sql->execute(array($name));
$rows = $sql->fetchAll();
与Bind_param:
$sql->bind_param("s", $name); //s means the database expects a string
我听人说:“保护来自于使用绑定参数,而不是使用预处理语句”。我可以知道什么是绑定参数? Bind_param是绑定参数?如果是,那么没有Bind_param的正常和简单的PDO Prepared语句不能完全阻止SQL注入?
你说得对。绑定参数是使用?在“预准备语句”中声明的参数。然后使用execute()绑定它们,并将它们的值作为绑定到语句的参数。
那是真实的。
我没有关于此的专家信息,但据我所知,SQL注入的问题是SQL服务器收到一个字符串并将其视为true。例如,服务器无法知道DUMP
命令是否是故意制作的。
使用绑定参数,你对SQL服务器说“嘿看,这是查询,我希望参数在这里,这里和那里。哦,顺便说一下,这里是值”。这种方法不同,因为SQL现在知道它必须执行的实际表达式以及值是什么。这允许SQL将值插入表达式,而无需修改表达式本身。
保护来自使用绑定参数,而不是使用预准备语句
意味着仅使用prepare()是不够的,但保持查询中包含所有变量,如下所示:
$sql = $db->prepare("SELECT * FROM employees WHERE name ='$name'");
$sql->execute();
$rows = $sql->fetchAll();
有人说这意味着虽然你在技术上使用的是预处理语句,但是你没有将变量绑定到它。因此它使查询易受攻击。
要受到保护,您必须使用占位符替换查询中的所有变量,然后绑定这些变量:
$sql = $db->prepare("SELECT * FROM employees WHERE name = ?");
$sql->bindParam(1, $name);
$sql->execute();
$rows = $sql->fetchAll();
但PDO有一个很好的绑定速记,允许你避免重复调用pindParam(),在execute()中发送变量时在内部执行所有这些调用:
$sql = $db->prepare('SELECT * FROM employees WHERE name = ?');
$sql->execute(array($name));
$rows = $sql->fetchAll();
它与bindParam()的绑定基本相同。因此,您的代码使用绑定,因此是安全的
最后,bind_param()实际上是一个mysqli函数,它根本与PDO无关。
OWASP给了我同样的疑问,他们遵循针对SQL注入“SQL_Injection_Prevention_Cheat_Sheet”的指导他们说:
防御选项1:准备好的语句(带参数化查询):
所以好像你应该一直使用bind_param()。我没有使用它,因为我使用自动脚本转换了数千个易受攻击的DAO,而bind_param()需要我手动编辑它们。
我还没有看到没有使用bind_param()的注入示例,所以我相信没有必要。
你说得对。
错误的方法:
$sql = $db->query('SELECT * FROM employees WHERE name = '.$name); //WRONG WRONG HORRIBLE
是的,您不必绑定参数以确保您免受SQL注入攻击。手册告诉我们:“另外,调用PDO :: prepare()和PDOStatement :: execute()有助于防止SQL注入攻击,无需手动引用和转义参数。” - PDO::prepare。说够了。
绑定参数只是使SQL查询可重用的一种方便方法 - 一旦将它们放入SQL查询中,就可以将任何内容绑定到“占位符” - 这里有一个很好的例子:W3school example。
但是再一次,这项工作是使用prepare
和execute
完成的。