5

我刚开始使用 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;

我很感激我能得到的所有帮助。

-=解决方案=-

我不得不使用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

4

1 回答 1

1

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

通过仅回显$user['fname']$user['lname']原始值(包含先前提交的双引号),您会在绘制时无意中允许过早关闭 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手册页以确保您正确使用它。

于 2013-09-15T00:11:40.353 回答