【问题标题】:PDO UPDATE doesn't seem to store quotes?PDO UPDATE 似乎没有存储报价?
【发布时间】:2013-09-14 19:38:34
【问题描述】:

我刚刚开始使用 PDO 方法,现在我遇到了一个小问题。如果我创建一个将名字和姓氏插入数据库的表单,我可以使用以下代码插入所有类型的特殊字符:

try {
    $db = new PDO('mysql:dbhost=' . $dbhost . ';dbname=' . $dbname, $dbuser, $dbpass);
    $db -> exec("SET CHARACTER SET utf8");
} catch(PDOException $e) {
    echo $e->getMessage();
}
$query = $db->prepare("INSERT INTO users(fname, lname) VALUES(:fname, :lname)");
$insert_array = array(
    ":fname" => $fname,
    ":lname" => $lname
);
$query->execute($insert_array);
$db = NULL;

我可以毫无问题地插入":;,-!"#¤%&&(%)?{][]}£$€{{{$@@_--",甚至插入SQL 注入。但是当我尝试使用类似的代码更新数据库时,它确实接受所有类型的特殊字符,引号除外。这是为什么?我用来更新的代码是:

try {
    $db = new PDO('mysql:dbhost=' . $dbhost . ';dbname=' . $dbname, $dbuser, $dbpass);
    $db -> exec("SET CHARACTER SET utf8");
} catch(PDOException $e) {
    echo $e->getMessage();
}
$query = $db->prepare("UPDATE users SET fname=:fname, lname=:lname WHERE userid=:userid");
$update_array = array(
    ":fname" => $fname,
    ":lname" => $lname,
    ":userid" => $_GET['userid']
);
$query->execute($update_array);
$db = NULL;

感谢我能得到的所有帮助。

-=SOLUTION=-

我必须使用htmlspecialchars() 来“解码”字符串。像这样:

<form action="" method="post">
    First name<br><input type="text" name="fname" value="'.htmlspecialchars($user['fname']).'">
    Last name: <br><input type="text" name="lname" value="'.htmlspecialchars($user['lname']).'">
    <input type="submit">
</form>

现在各种特殊字符都可以完美运行。 感谢大家的帮助,真的很感激! :D

【问题讨论】:

  • 这不应该发生,参数化查询应该允许任何字符。你有错误吗?
  • 在这两个脚本中设置$fname$lname 有什么不同吗?
  • “引号除外”是什么意思?哪种报价?单/双/智能/…?另外,试试$db-&gt;setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
  • 您如何检查它是否已正确更新?可能是你的查看方法有问题,而不是你的 SQL。
  • 看起来你自己不小心被 XSS 攻击了。每当您将数据输出到 HTML 中时,您都应该通过htmlentitieshtml_special_chars 运行它。否则攻击者可以选择像&lt;script&gt;// run malicious code...&lt;/script&gt; 这样的名称,当然在你的情况下你会不小心破坏你的表单数据。

标签: php mysql sql pdo sql-update


【解决方案1】:

我相信瓦利德汗是正确的。在这种情况下不一定要对自己进行 xssing(尽管这是您在此处展示的一个明显漏洞,并且为此类攻击敞开了大门),而是据我所知只是破坏了您的 html。

通过仅回显 $user['fname']$user['lname'] 值 raw - 其中包含上一次提交的双引号 - 您在绘制时无意中允许过早关闭 html 元素属性值,从而破坏您的 HTML 表单。很惊讶它仍然提交。在您的浏览器中,检查诸如 Firebug 之类的内容并检查表单 - 您应该会看到输入的格式很奇怪,并且可能在其后绘制了一些额外的字符。

在直接在 HTML 中回显它们之前,始终对 PHP 值使用 htmlentities() 或其他类似的转义帮助函数。总是。

例子:

<form action="" method="post">
    First name<br><input type="text" name="fname" value="<?php echo htmlentities( $user['fname'], ENT_COMPAT, 'UTF-8' ); ?>">
    Last name: <br><input type="text" name="lname" value="<?php echo htmlentities( $user['lname'], ENT_COMPAT ); ?>">
    <input type="submit">
</form>

编辑:关于您声称“如果我删除表单值中的引号,它正在使用引号进行更新”,我认为这意味着您使用单引号而不是双引号设置 HTML 元素属性值-引号,它真的根本不起作用。

如果用户提交了带有单引号的值,它同样会破坏您的固定示例,因为值中的单引号会过早关闭您的 HTML 元素属性值声明。使用双引号来声明 HTML 元素的属性值是最好的,但如果您在构建 HTML 元素时选择使用单引号,那么在 PHP 中,使用 htmlentities($string, ENT_QUOTES)

请阅读 htmlentities 手册页,以确保您正确使用它。

【讨论】:

  • 啊哈,谢谢伙计。它对htmlentities( $user['username'], ENT_COMPAT ) 有所帮助。现在我可以像":;',-!"#¤%&amp;&amp;(%)?{][]}£$€{{{$@@_--" 这样插入,但它显示为":;',-!"#¤%&amp;&amp;(%)?{][]}£$â?¬{{{$@@_--"。你知道为什么吗?
  • @Treps: htmlentities 函数有一个字符串参数来设置文本编码。尝试传入字符串“UTF-8”,因为那是你想要的集合。
  • @Treps:如果仍然失败,您的浏览器可能会向服务器发送与您的服务器期望不同的字符集。您可以通过在页面标题中设置类似于以下 HTML 标记的内容来提示浏览器客户端使用 UTF8:&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;。这绝对不能防止误译。这只是对客户端在与 HTML 文档交互时使用首选 UTF8 编码的建议。不过,这个新问题是一个单独的问题,您应该能够在 SE 的其他地方找到答案。
  • 很少需要htmlentities(),只需使用htmlspecialchars()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-02
  • 2011-11-14
  • 2014-01-03
  • 2021-12-16
  • 2017-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多