PHP 与 PDO:将经过处理的输入 (filter_var) 与准备好的语句数据进行比较

PHP with PDO: Compare santized input (filter_var) with prepared statement data

我正在使用 PDO 'prepared statements' 将未经处理的数据插入 mySQL 数据库。据我了解,这是减轻 sql 注入的最佳做法,因为它本身就是一个消毒步骤。

如果我在此步骤之前使用 filter_var 进行冗余清理,我会在数据库中获得带有转义字符的用户输入,当然,稍后输出时看起来很难看。

我担心,如果我想稍后将用户输入与数据库数据进行比较,我会在那个阶段通过 santizing 修改输入,使其不再匹配数据库数据。

示例:

$email = $_POST['email'];

//Insert the user supplied email (and other details) into the db
$sql = 'INSERT INTO author SET
        name = :userName,
        email = :email,
        password = :password';
    $s = $pdo->prepare($sql);
    $s->bindValue(':userName', $userName);
    $s->bindValue(':email', $email);
    $s->bindValue(':password', password_hash($password, PASSWORD_DEFAULT));
    $s->execute();

然后稍后在代码中...

//Call a function that will use the provided email to lookup the username
getUserName($email);

getUserName 函数当然会再次使用准备好的语句来访问数据库。但是 php 会评估函数调用中的 $email var 吗? (我不是 100% 清楚变量何时或是否在 php 内部被解释和执行)。如果用户电子邮件地址(或我正在评估的任何输入)是:

);Header('Location: evilsite.com');exit();@example.com

是否会php 关闭 getUserName 函数,然后执行头指令?

所以如果此时我改为..

getUserName(filter_var($email, FILTER_SANITIZE_STRING));

..然后我觉得我一直在努力清理用户输入,但我不能再用它来与数据库中的信息进行比较,因为它可能在清理过程中被修改了。

我在这里以电子邮件为例,但这同样适用于任何输入。

理想情况下,我想简单地清理我收到的每个输入,只是为了安全起见,这样我就可以在我的代码中不受惩罚地使用这些变量。但是我相信我需要对输出进行解码以使其格式正确,这样做会使我的用户暴露于 XSS 攻击对吗?

感谢您的建议。

不,PHP 不能那样工作。变量内容不会插入到源代码中,源代码也不会使用插入的变量内容重新计算。它在 shell 脚本 (在此处插入大量星号和说明) 中是这样工作的,但在 PHP 或大多数其他理智的编程语言中却不是这样。

getUserName($email);

此处 $email 包含分配给它的任何内容。那是什么并不重要。在任何情况下这里都没有漏洞。此代码表示 调用函数 getUserName 并将 $email 的值作为第一个参数传递给它。 仅此而已。它永远不会被解释为任何其他含义。无需为此目的清理该值。

唯一的时间值被插入 "code" 并且当您非常明确地执行该代码时:

eval("getUserName($email)")
$db->query("SELECT * FROM foo WHERE bar = '$email'")

这些都是将字符串显式插入字符串以创建新字符串的示例,然后将其解释为某种形式的代码。只要您远离此类结构,这个特殊的漏洞就没什么大不了的。