我有这个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>
SO,
使用php pdo将数据插入mysql的最佳,安全的方法是什么?
答案 0 :(得分:2)
从数据库中检索值时,您需要将这些值视为 unsafe ,就像它们可能包含HTML特殊字符一样,或者可能包含javascript。
要在网页中显示安全的值,您需要通过正确的转义机制运行该值。
PHP提供 htmlentities
功能,用适当的替换替换HTML特殊字符。举个例子:
$val = htmlentitites("<script>alert('heheheheheheh')</script>");
将这样的内容分配给$val
<script>alert('heheheheheheh')</script>
(它也可能会替换其他一些字符。)但最终的结果是,如果你把那个字符串放在网页上,那么你将会看到&#34;看到&#34;显示在网页上的内容与原始字符串类似。该字符串不会被解释为javascript。
最重要的是,你不能假设因为从数据库中返回了一个字符串,它安全&#34;。您必须将其视为不安全。
PDO&#34;消毒&#34;输入?
总之,没有。 PDO不会清理SQL语句中的值以删除HTML特殊字符或其他可能不安全的值。
准备好的声明与绑定占位符的作用是确保语句中提供的值传递到数据库中,不带解释为SQL文本。
例如,使用带有绑定占位符的PDO预处理语句
$sql='INSERT INTO tab (col) VALUES (:val)';
$sth=$db->prepare($sql);
$sth->bindParam(':val', $value);
$sth->execute();
VS。将值合并到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注入漏洞的一个示例。这就说明了为什么使用准备好的语句和绑定占位符来阻止SQL注入,它可以抵御当我们不将值视为潜在价值时可能发生的一系列肮脏不安全
如果$value
包含字符串:
<script>alert('heheheheheheh')</script>
使用预准备语句和绑定占位符,即将存储在数据库中的值。它只是一个字符串。它不会被解释为SQL语句的一部分。
如果我们在SQL中的字符串文字周围使用双引号而不是单引号,我们可以使用其他模式发生同样的事情,它容易受到SQL注入,例如。
INSERT INTO tab (col) VALUES ("<script>alert('heheheheheheh')</script>")
或者,如果我们使用&#34;转义字符串&#34;功能
INSERT INTO tab (col) VALUES ('<script>alert(''heheheheheheh'')</script>')
同样,该字符串存储在数据库中,因为它是一个有效的字符串。
是否包含HTML特殊字符并不重要从底线开始,PDO不会清理字符串中的HTML字符。您的代码需要处理从数据库返回的所有值,就像它们可能不安全一样,并通过htmlentities
或类似函数运行它们以解除&#34;撤防&#34;来自解释的值,例如作为javascript。
答案 1 :(得分:0)
使用预处理语句是最好的,这就是你正在做的事情(假设你正在执行语句(不在你的代码示例中))。 Prepared语句转义值以防止SQL注入,而不是跨站点脚本。
进入数据库的值不变,这很好(IMO)。如果需要,您应该在输出值时过滤这些值(例如,htmlentities()
)。
您还可以使用execute
方法绑定参数:
$STH = $db->prepare("INSERT INTO racuni (napomene) VALUES (?)");
$STH->execute(array($_POST['napomena']));
答案 2 :(得分:0)
首先,您需要告诉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();
}