php - 如何使用php pdo安全地将数据插入mysql

标签 php mysql pdo escaping

我有这个 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

&lt;script&gt;alert('heheheheheheh')&lt;/script&gt;

(它也可能会替换一些其他字符。)但最终结果是,如果您将那个字符串放在网页上,您将在网页上“看到”显示的内容就会出现就像原来的字符串一样。该字符串不会被解释为 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/

相关文章:

php - CREATE TABLE 和 INSERT,相同的查询

php - 登录表单 POST 上的 Laravel 5.1 token 不匹配

php - 如何使用 php 在数据库中插入 ISO-8859-1 字符集值

php - 将函数的参数直接传递给另一个函数

java - 哪些方法可以减少 JDBC 线程暂停?

php - 如何防止 PHP PDO 通过 jQuery AJAX 插入的 MySQL varchar 中的转义字符

php - 你如何调试 php "Out of Memory"问题?

php - 当尝试按关系中的多个记录进行排序时,GROUP BY 子句并包含非聚合列

mysql - 为什么这些表大小相同?

php - 解析由 PDO 语句创建的 JSON 对象