如何使用 php pdo 安全地将数据插入 mysql
How to safely insert data to mysql using php pdo
我有这个 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 的最佳、安全方法是什么?
最好使用准备好的语句,这就是您正在做的(假设您正在执行该语句(不在您的代码示例中))。准备好的语句转义值以防止 SQL 注入,而不是跨站点脚本。
进入数据库时值不变,这很好(IMO)。如果需要,您应该在输出值时过滤值(例如,htmlentities()
)。
你也可以在execute
方法中绑定参数:
$STH = $db->prepare("INSERT INTO racuni (napomene) VALUES (?)");
$STH->execute(array($_POST['napomena']));
首先你需要告诉 PDO 抛出异常如下:
$pdo = new PDO("mysql:host={$dbhost};dbname={$dbname}", $dbuser, $dbpass);
// add this:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
现在将您的数据库操作包装在一个 try - catch
块中:
try
{
$statement = $pdo->prepare("INSERT INTO racuni (napomene) VALUES (:12)");
$statement->bindParam(':12', $_POST['napomena'], PDO::PARAM_STR);
// etc.
$statement->execute();
}
catch ( PDOException $exception )
{
echo "PDO error :" . $exception->getMessage();
}
从数据库中检索值时,您需要将这些值视为 不安全 ,就好像它们可能包含 HTML 特殊字符,或者可能包含javascript.
要在网页中安全显示该值,您需要通过适当的转义机制运行该值。
PHP 提供了 htmlentities
功能来做到这一点,将 HTML 特殊字符替换为合适的替换字符。例如:
$val = htmlentitites("<script>alert('heheheheheheh')</script>");
会把这样的东西分配给 $val
<script>alert('heheheheheheh')</script>
(它可能还会替换一些其他字符。)但是最终结果是,如果您将 that 字符串放在网页上,您将要 "see" 显示在网页上看起来像原始字符串。该字符串不会被解释为 javascript.
最重要的是,您不能假设因为从数据库返回的字符串是 "safe"。您必须将其视为潜在的不安全。
PDO"sanitize"是否输入?
一句话,没有。 PDO 不会清理 SQL 语句中的值以删除 HTML 特殊字符或其他可能不安全的值。
带有绑定占位符的准备语句所做的是确保语句中提供的值被传递到数据库中,没有被解释为SQL文本。
例如,使用带有绑定占位符的 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; --
使用第一个模式(带绑定占位符的准备语句),该字符串值被传递到数据库,并存储在列中。
在第二个例子中,将该值合并到 SQL 语句的文本中,我们得到潜在危险的 SQL 语句提交:
INSERT INTO tab (col) VALUES ('foo'); DROP TABLE tab; --')
这是一个 SQL 注入漏洞的例子。这说明了为什么使用 prepared statements 和 bind placeholders 会阻止 SQL 注入,它可以抵御当我们不会将值视为潜在 不安全.
如果 $value
包含字符串:
<script>alert('heheheheheheh')</script>
使用准备好的语句和绑定占位符,这就是将要存储在数据库中的值。它只是一个字符串。它不会被解释为 SQL 语句的一部分。
如果我们在 SQL 中的字符串文字周围使用双引号而不是单引号,那么我们可以在另一个模式中发生同样的事情,这很容易受到 SQL 注入,例如
INSERT INTO tab (col) VALUES ("<script>alert('heheheheheheh')</script>")
或者,如果我们使用 "escape string" 函数
INSERT INTO tab (col) VALUES ('<script>alert(''heheheheheheh'')</script>')
同样,该字符串被存储在数据库中,因为它是一个有效的字符串。里面是否有 HTML 个特殊字符并不重要。
最重要的是,PDO 不会清理字符串中的 HTML 个字符。您的代码需要处理从数据库返回的 all 值,就好像它们可能不安全一样,并且 运行 通过 htmlentities
或与 [=101 类似的函数=] 被解释的值,例如作为 javascript.
我有这个 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 的最佳、安全方法是什么?
最好使用准备好的语句,这就是您正在做的(假设您正在执行该语句(不在您的代码示例中))。准备好的语句转义值以防止 SQL 注入,而不是跨站点脚本。
进入数据库时值不变,这很好(IMO)。如果需要,您应该在输出值时过滤值(例如,htmlentities()
)。
你也可以在execute
方法中绑定参数:
$STH = $db->prepare("INSERT INTO racuni (napomene) VALUES (?)");
$STH->execute(array($_POST['napomena']));
首先你需要告诉 PDO 抛出异常如下:
$pdo = new PDO("mysql:host={$dbhost};dbname={$dbname}", $dbuser, $dbpass);
// add this:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
现在将您的数据库操作包装在一个 try - catch
块中:
try
{
$statement = $pdo->prepare("INSERT INTO racuni (napomene) VALUES (:12)");
$statement->bindParam(':12', $_POST['napomena'], PDO::PARAM_STR);
// etc.
$statement->execute();
}
catch ( PDOException $exception )
{
echo "PDO error :" . $exception->getMessage();
}
从数据库中检索值时,您需要将这些值视为 不安全 ,就好像它们可能包含 HTML 特殊字符,或者可能包含javascript.
要在网页中安全显示该值,您需要通过适当的转义机制运行该值。
PHP 提供了 htmlentities
功能来做到这一点,将 HTML 特殊字符替换为合适的替换字符。例如:
$val = htmlentitites("<script>alert('heheheheheheh')</script>");
会把这样的东西分配给 $val
<script>alert('heheheheheheh')</script>
(它可能还会替换一些其他字符。)但是最终结果是,如果您将 that 字符串放在网页上,您将要 "see" 显示在网页上看起来像原始字符串。该字符串不会被解释为 javascript.
最重要的是,您不能假设因为从数据库返回的字符串是 "safe"。您必须将其视为潜在的不安全。
PDO"sanitize"是否输入?
一句话,没有。 PDO 不会清理 SQL 语句中的值以删除 HTML 特殊字符或其他可能不安全的值。
带有绑定占位符的准备语句所做的是确保语句中提供的值被传递到数据库中,没有被解释为SQL文本。
例如,使用带有绑定占位符的 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; --
使用第一个模式(带绑定占位符的准备语句),该字符串值被传递到数据库,并存储在列中。
在第二个例子中,将该值合并到 SQL 语句的文本中,我们得到潜在危险的 SQL 语句提交:
INSERT INTO tab (col) VALUES ('foo'); DROP TABLE tab; --')
这是一个 SQL 注入漏洞的例子。这说明了为什么使用 prepared statements 和 bind placeholders 会阻止 SQL 注入,它可以抵御当我们不会将值视为潜在 不安全.
如果 $value
包含字符串:
<script>alert('heheheheheheh')</script>
使用准备好的语句和绑定占位符,这就是将要存储在数据库中的值。它只是一个字符串。它不会被解释为 SQL 语句的一部分。
如果我们在 SQL 中的字符串文字周围使用双引号而不是单引号,那么我们可以在另一个模式中发生同样的事情,这很容易受到 SQL 注入,例如
INSERT INTO tab (col) VALUES ("<script>alert('heheheheheheh')</script>")
或者,如果我们使用 "escape string" 函数
INSERT INTO tab (col) VALUES ('<script>alert(''heheheheheheh'')</script>')
同样,该字符串被存储在数据库中,因为它是一个有效的字符串。里面是否有 HTML 个特殊字符并不重要。
最重要的是,PDO 不会清理字符串中的 HTML 个字符。您的代码需要处理从数据库返回的 all 值,就好像它们可能不安全一样,并且 运行 通过 htmlentities
或与 [=101 类似的函数=] 被解释的值,例如作为 javascript.