我有这个 php pdo:
try {
$STH = $db->prepare("INSERT INTO racuni (napomene) VALUES (:12)");
$STH->bindParam(':12', $_POST['napomena'], PDO::PARAM_STR);
} catch (PDOException $e) {
echo $e->getMessage();
}
现在当我尝试将此数据添加到 mysql 时:
<script>alert('heheheheheheh')</script>
没有字符串转义?在数据库中我有相同的数据:<script>alert('heheheheheheh')</script>
所以,
使用 php pdo 将数据插入 mysql 的最佳、安全方法是什么?
最佳答案
从数据库检索值时,您需要将这些值视为不安全,就好像它们可能包含 HTML 特殊字符或可能包含 javascript。
为了让该值在网页中安全显示,您需要通过适当的转义机制运行该值。
PHP 提供了 htmlentities
函数来做到这一点,用合适的替换字符替换 HTML 特殊字符。举个例子:
$val = htmlentitites("<script>alert('heheheheheheh')</script>");
会将这样的内容分配给$val
<script>alert('heheheheheheh')</script>
(它也可能会替换一些其他字符。)但最终结果是,如果您将那个字符串放在网页上,您将在网页上“看到”显示的内容就会出现就像原来的字符串一样。该字符串不会被解释为 javascript。
底线,您不能因为从数据库返回字符串就认为它是“安全的”。您必须将其视为潜在不安全。
<小时/>PDO 是否“净化”输入?
一句话,不。 PDO 不会清理 SQL 语句中的值以删除 HTML 特殊字符或其他潜在不安全的值。
带有绑定(bind)占位符的准备语句的作用是确保语句中提供的值被传递到数据库中,不解释为 SQL 文本。
作为示例,使用带绑定(bind)占位符的 PDO 准备语句
$sql='INSERT INTO tab (col) VALUES (:val)';
$sth=$db->prepare($sql);
$sth->bindParam(':val', $value);
$sth->execute();
对比将值合并到 SQL 语句中
$sql = "INSERT INTO tab (col) VALUES ('" ,. $value ."')";
$db->query($sql);
考虑当 $value
包含此字符串时每种情况会发生什么
foo'); DROP TABLE tab; --
使用第一个模式(带有绑定(bind)占位符的准备语句),该字符串值将传递到数据库,并存储在列中。
在第二个示例中,将该值合并到 SQL 语句的文本中,我们得到了提交的潜在危险 SQL 语句:
INSERT INTO tab (col) VALUES ('foo'); DROP TABLE tab; --')
这是 SQL 注入(inject)漏洞的一个示例。这说明了为什么使用准备好的语句和绑定(bind)占位符可以阻止 SQL 注入(inject),它可以防止当我们不将值视为潜在的值时可能发生的一系列令人讨厌的事情不安全。
<小时/>如果$value
包含字符串:
<script>alert('heheheheheheh')</script>
使用准备好的语句和绑定(bind)占位符,这就是将存储在数据库中的值。它只是一个字符串。它不会被解释为 SQL 语句的一部分。
如果我们在 SQL 中的字符串文字周围使用双引号而不是单引号,那么我们可以用其他模式发生同样的事情,这很容易受到 SQL 注入(inject)的攻击,例如
INSERT INTO tab (col) VALUES ("<script>alert('heheheheheheh')</script>")
或者,如果我们使用“转义字符串”函数
INSERT INTO tab (col) VALUES ('<script>alert(''heheheheheheh'')</script>')
同样,该字符串会存储在数据库中,因为它是有效的字符串。其中是否包含 HTML 特殊字符并不重要。
<小时/>底线是,PDO 不会清理字符串中的 HTML 字符。您的代码需要处理从数据库返回的所有值,就好像它们可能不安全一样,并通过 htmlentities
或类似的函数运行它们,以“解除”这些值的安全状态。解释为例如作为 JavaScript。
关于php - 如何使用php pdo安全地将数据插入mysql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30575500/