安全的PHP查询?

时间:2011-06-17 17:47:04

标签: php mysql email

我有一个页面来激活点击我发送的电子邮件中的激活链接的用户,该电子邮件包含一个使用GET方法发布电子邮件地址的网址,我的代码如下,但我要求的是这是一个安全的方法还是有任何可以改进的方法?感谢

$username = $_GET['email']; 

mysql_query("UPDATE users SET active = 'yes'
WHERE email = '$username'") or die('oops!');

echo "<meta http-equiv=\"refresh\" content=\"0;URL=/index.php?msg=active\">";

10 个答案:

答案 0 :(得分:5)

这不是激活电子邮件的最佳方法。任何人都可以使用假电子邮件注册并创建自己的GET请求来激活它。你应该使用一个无法猜到的唯一哈希。此外,您需要使用mysql_real_escape_string转义SQL语句。

答案 1 :(得分:5)

答案 2 :(得分:4)

考虑以下$ _GET ['email']的值:

"'; DELETE FROM users WHERE 1 or username = ''"

如果您的用户提交此值,您的脚本将执行以下SQL语句:

UPDATE users SET active = 'yes' WHERE email = ''; DELETE FROM users WHERE 1 or username = ''"

您需要过滤输入以删除在SQL设置中有意义的字符(在此示例中为\')。

您可以使用PDO预处理语句或使用mysql_real_escape_string()进行过滤来帮助保护您的查询。

此外,您希望创建一个唯一的,不可猜测的值以发送给用户,并期望从$ _GET返回该值。如果您允许用户提供纯文本电子邮件地址,则恶意用户可以激活任何电子邮件地址。 md5()或其他哈希函数可用于创建唯一值。

答案 3 :(得分:3)

这根本不安全。您需要在mysql_real_escape_string()

上致电$username
$username = mysql_real_escape_string($_GET['email']); 

最好使用PDO并通过prepared statement传递变量。

答案 4 :(得分:2)

不,这很容易受到SQL注入的攻击。我可以在'中放置$_GET['email']并运行我喜欢的任何查询。

答案 5 :(得分:2)

这绝对不安全。你需要逃避任何有潜在危险的角色(如果有人通过mysql_real_escape_string输入了'在他们的电子邮件地址中'。

答案 6 :(得分:2)

不安全。您应该使用存储过程,或escape the sql

答案 7 :(得分:2)

想象一下,我想对您的网站做一些恶意的事情,现在假设我操纵您的网址并将.php?email=arron@arronchapman.com更改为.php?email=1';SHOW TABLES,甚至可能.php?email=1';DROP TABLE USERS;更改不是很好吗?

防止这种情况的最简单方法是将所有输入值包装在函数mysql_real_escape_string中,这会使您的查询如下所示: mysql_query("UPDATE users SET active = 'yes' WHERE email = '" . mysql_real_escape_string($username) .'") or die('oops!');

我想向您介绍我的朋友Bobby Tables(来自XKCD): enter image description here

答案 8 :(得分:1)

除了其他人提到的SQL注入问题之外,您还有一个问题,即人们可以伪造自己的激活链接并绕过接收电子邮件的需要。

一个常见的解决方案是在激活之前检查的URL中包含某种哈希值。

例如 -

为激活创建一个表。当用户注册时,插入电子邮件地址(或其他一些唯一标识符)和一些非常量的秘密值。这可以是随机数,时间戳和盐,或类似的。

生成电子邮件的链接时,请包含从散列电子邮件地址和密码值中获取的哈希值。

然后,当用户点击链接时,您可以从URL中获取电子邮件地址,使用数据库中的值对其进行哈希处理,并查看它是否与URL中的哈希值匹配。

这将使某人伪造激活链接变得更加困难。

答案 9 :(得分:0)

然而,正如每个人都说的那样,在查询中使用它之前逃避字符串是绝对必要的,我认为还有更多需要关注。

这仍然允许非用户尝试使用不同的电子邮件地址并查看结果。

我建议加密电子邮件,并在网址中使用电子邮件的加密版本。

因此,当您向他们发送链接时:

$enc_key = 'SOME KEY I USE';
$email = mysql_real_escape_string($email);
$result = $db->query("SELECT AES_ENCRYPT('$email', '$enc_key') as email");
$enc_email = mysql_fetch_assoc($result);
$enc_email = $enc_email['email'];
$url = "http://www.example.com/confirm.html?key=$enc_email";

然后检查用户确认你:

$enc_key = 'SOME KEY I USE';
$enc_email = mysql_real_escape_string($_GET['key']);
$result = $db->query("UPDATE users SET active = 1 WHERE AES_ENCRYPT(email, '$enc_key') = '$enc_email'");