首页
学习
活动
专区
圈层
工具
发布

登记码
EN

Code Review用户
提问于 2020-05-26 20:35:09
回答 3查看 365关注 0票数 -3

我在为一个社交网络学习一个教程。我想知道这段代码有多安全,因为我计划将它发布到公共网络上。

代码语言:javascript
复制
 0){
            array_push($error_array, "E-mail already in use
");
        }

    } else{

        array_push($error_array, "Invalid email format
");
    }

} else {
    array_push($error_array, "E-mails don't match
");
}

if(strlen($uname) > 25 || strlen($uname) < 1) {

    array_push($error_array, "Your username must be between 2 and 25 characters
");
}

if(strlen($fname) > 25 || strlen($fname) < 1) {

    array_push($error_array, "Your first name must be between 2 and 25 characters
");
}

if(strlen($lname) > 25 || strlen($lname) < 1) {

    array_push($error_array, "Your last name must be between 2 and 25 characters
");
}

if($password != $password2){

    array_push($error_array, "Your passwords do not match
");

} else {

    if(preg_match('/[^A-Za-z0-9]/', $password)) {

    array_push($error_array, "Your password can only contain english characters or numbers.
");

    }

}    

if(strlen($password > 30 || strlen($password) < 5)){

    array_push($error_array, "Your password must be between 5 and 30 characters
");
}

if(empty($error_array)) {

    // $password = password_hash($password); // encrypt password
    $password = password_hash($_POST['reg_password'], PASSWORD_BCRYPT, array('cost' => 14));

    // profile picture assignment
    $profile_pic = "assets/images/profile_pics/defaults/default.jpg";

    $query = mysqli_query($con, "INSERT INTO users VALUES(NULL, '$fname', '$lname', '$uname', '$em', 
    '$password', '$date', '$profile_pic', '0', '0', 'no', ',')");

    array_push($error_array, "You can now login
");

    //clear session variables

    $_SESSION['reg_fname'] = "";
    $_SESSION['reg_uname'] = "";
    $_SESSION['reg_lname'] = "";
    $_SESSION['reg_email'] = "";
    $_SESSION['reg_email2'] = "";

}
}

?>
EN

回答 3

Code Review用户

发布于 2020-05-26 21:53:55

密码太可怕了。

它可能包含OWASP网站上列出的十大漏洞。

它使用了一种编程语言,它以其糟糕的安全历史和糟糕的API而闻名,这使得编写安全可靠的代码变得困难。

忘记那个教程,警告别人,找一个更好的教程,关注好的代码和安全性,然后重新开始。一个很好的起点是OWASP网站。如果您真的想继续使用PHP,请至少使用最新版本。

您也有一个不匹配的错误:条件< 1与错误消息at least 2不匹配。这意味着您甚至没有正确地测试您的代码。尤其是边缘情况的测试是非常重要的。

票数 7
EN

Code Review用户

发布于 2020-05-26 22:51:48

我对strip_tags感到有点困惑:

代码语言:javascript
复制
$em = strip_tags($_POST['reg_email']); // remove html tags
$em = str_replace(' ', '', $em); //remove spaces
$em = ucfirst(strtolower($em)); //uppercase first letter

我的印象是你偶然发现了非常古老的教程。您不使用该函数来检查用户名或电子邮件,因为您并不期望人们实际上会在这些字段中放置HTML标记,而且您应该有一个更全面的例程来检查输入的值。

strip_tags的目的是从文本消息中删除html (从而过滤掉一些垃圾邮件,比如可点击的超链接)。Javascript也是。

由于您正在使用filter_var检查电子邮件地址,所以您可以删除这些行,它们是没有意义的。

为什么要大写电子邮件的第一封信?调用变量$email,它更直观。em让我想起了HTML。

要删除字符串周围的空格,只需使用trim函数即可。

此代码引入了一个潜在的漏洞 (SQL注入):

代码语言:javascript
复制
$e_check = mysqli_query($con, "SELECT email FROM users WHERE email='$em'");

我想知道为什么您没有系统地使用parameterized查询(或准备好的陈述) (至少在涉及用户输入时如此)。我更感到惊讶的是,你上次提交的材料没有这样的弱点。

在这种情况下,您应该避免该漏洞,因为您依赖于上面的filter_var来确保电子邮件是有效的,但这是您唯一的防线。如果您忘记检查代码的另一部分中的电子邮件怎么办?而且,filter_var可能有一些我们不知道的缺点。

通常,网站只允许用户名中的字母数字字符加上一些符号,如空格、连字符、下划线等。最简单的方法是使用正则表达式。

没有必要在任何地方删除空格:

代码语言:javascript
复制
$fname = str_replace(' ', '', $fname); //remove spaces

名字很可能包含空格或复合名称,这是没有错的。特里姆:是的。删除所有空白:否。

在这段代码中,您检查的是minimum密码长度,而不是复杂性。12345确实通过了你的测试,但你不应该接受那种密码。但你做的正好相反,用户不允许选择强密码.

代码语言:javascript
复制
if(preg_match('/[^A-Za-z0-9]/', $password)) {

array_push($error_array, "Your password can only contain english characters or numbers.
");

}

设计一个更好的密码策略,比如:至少有一个数字的12个字符,一个特殊字符,一个长密码,就像密码一样,对人类来说更容易记住。每个网站都有自己的规则,这些规则往往适得其反,毫无意义。关键是要在安全和便利之间找到平衡。人们倾向于重复使用相同的密码,部分原因是他们被迫选择不直观的密码。

我不知道为什么您有$_SESSION变量,您没有对它们做任何事情。实际上,它们是无用的,除非您希望在注册后立即启动用户会话(即登录用户)。但是你通常会想要首先验证他们的电子邮件地址(通过发送注册代码)。

我不知道大是项目的范围,但使用development框架可能是个好主意,因为:

  • 它将使你跟上21世纪,从而提高你在就业市场上的价值,如果你追求的职业是一名开发人员。
  • 它将帮助你摆脱繁琐的表单构建和验证练习--不要重新发明轮子,使用其他程序员使用的现代工具。如果你想重新发明轮子,就把它做好。但这需要时间,不能保证取得好的结果。

这种代码已有15年的历史了。至少。而且不太好。

不幸的是,Web上到处都是过时的教程,其中许多都会使不良实践和安全漏洞永久化。事实上,排名最好的教程似乎是那些没有人应该再读的旧东西。我仍然在寻找一个体面的教程,因为我们的发言。

票数 6
EN

Code Review用户

发布于 2020-05-27 06:59:39

不要使用此代码和php5,如果要使用mysqli +“过程样式”,请使用mysqli_real_escape_string。最好的出路--使用"准备陈述

My示例(这是<>输入)

代码语言:javascript
复制
  function insert_user($users) {
    global $db;

    $hashed_password = password_hash($users['password'], PASSWORD_BCRYPT);

    $sql = "INSERT INTO users ";
    $sql .= "(first_name, last_name, email, username, hashed_password) ";
    $sql .= "VALUES (";
    $sql .= "'" . mysqli_real_escape_string($db, $users['first_name']) . "',";
    $sql .= "'" . mysqli_real_escape_string($db, $users['last_name']) . "',";
    $sql .= "'" . mysqli_real_escape_string($db, $users['email']) . "',";
    $sql .= "'" . mysqli_real_escape_string($db, $users['username']) . "',";
    $sql .= "'" . mysqli_real_escape_string($db, $hashed_password) . "'";
    $sql .= ")";
    $result = mysqli_query($db, $sql);

    // For INSERT statements, $result is true/false
    if($result) {
      return true;
    } else {
      // INSERT failed
      echo mysqli_error($db);
      exit;
    }
  }

如何使用这个函数?

代码语言:javascript
复制
$result = insert_user($users);

输出使用strip_tags

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/242970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档