php - FILTER_SANITIZE_EMAIL 是否足够,或者还需要 mysql_real_escape_string 来避免 PHP/MySQL 中的安全问题?

标签 php mysql security sql-injection

我正在像这样检查数据库的输入:

$email = $_POST['newsletter_email'];
$email = filter_var($email, FILTER_SANITIZE_EMAIL); 

然后:

$is_user = $db->count_rows('users', "WHERE email='" . $email . "'");

问题是,它足够好吗?或者我还应该使用mysql_real_escape_string

最佳答案

这个问题有两个部分。

  1. 如何验证电子邮件地址。
  2. How to prevent SQL Injection .

输入验证

$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
if ($email !== false) {
    // Well, you've got yourself a valid email address!
}

防止 SQL 注入(inject)

不要使用mysql_real_escape_string()。正确的方法prevent SQL Injection是使用参数化查询。也称为准备好的语句。

推荐阅读:

您的代码应如下所示:

$stmt = $db->prepare('SELECT count(userid) FROM users WHERE email = ?');
if ($stmt->exec([ $email ])) {
    $is_user = $stmt->fetchColumn(0);
}

如果这对您来说太麻烦,您可以加载 EasyDB库并使您的查询如下所示:

$is_user = $db->cell('SELECT count(userid) FROM users WHERE email = ?', $email);

请停止使用输入转义并采用准备好的语句。它们在单独的数据包中发送查询和参数,这意味着即使使用 Unicode hack,也无法更改查询结构。

重要

您必须正确使用准备好的语句(即,切勿将用户输入与传递给 prepare() 的查询字符串连接起来)才能实现此有保证的安全级别。

此外,在 PHP 中,某些驱动程序将默认模拟准备好的语句。来自 PHP manual :

PDO::ATTR_EMULATE_PREPARES Enables or disables emulation of prepared statements. Some drivers do not support native prepared statements or have limited support for them. Use this setting to force PDO to either always emulate prepared statements (if TRUE), or to try to use native prepared statements (if FALSE). It will always fall back to emulating the prepared statement if the driver cannot successfully prepare the current query. Requires bool.

模拟的准备好的语句不提供与真正的准备好的语句相同的安全保证(即 data/instruction separation )。为了安全起见,请禁用模拟准备。

$db = new PDO(/* etc */);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

关于php - FILTER_SANITIZE_EMAIL 是否足够,或者还需要 mysql_real_escape_string 来避免 PHP/MySQL 中的安全问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30443747/

相关文章:

java - 使用PBKDF2 java解密和加密

javascript - 在 Silverstripe 中将屏幕宽度传递给 Controller

php - MySQL 查询中表名周围反引号的重要性

Mysql - 如何设置自增从零开始

c - 保护 RAM 中的加密 key ?

java - 从 servlet 打开受密码保护的网站

php - 是否可以将 PDO 参数绑定(bind)到对象的成员变量?

PHP 析构函数显示错误?

javascript - 未捕获的语法错误 : Unexpected identifier (alert connected)

php - mysql "or"查询操作的顺序