我有一个页面来激活点击我发送的电子邮件中的激活链接的用户,该电子邮件包含一个使用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\">";
答案 0 :(得分:5)
这不是激活电子邮件的最佳方法。任何人都可以使用假电子邮件注册并创建自己的GET请求来激活它。你应该使用一个无法猜到的唯一哈希。此外,您需要使用mysql_real_escape_string转义SQL语句。
答案 1 :(得分:5)
忘记mysql_real_escape_string
- 请参阅https://stackoverflow.com/questions/5690795/am-i-safe-using-just-mysql-real-escape-string-to-defend-sql-injections/5690877#5690877和Do htmlspecialchars and mysql_real_escape_string keep my PHP code safe from injection?。
使用PDO。
不要忘记second-order SQL injection(什么,没有人告诉你安全性很难?)。更多信息here。
答案 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):
答案 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'");