这是关于安全性和MySQL的良好实践吗?

时间:2016-07-01 10:06:27

标签: php mysql security

我想对网站的某些php代码有一些反馈,因为这是我第一次编写适合在公共网站上使用的代码而且我很少偏执。

此代码位于注册页面的顶部,其中包含一个发送回自身的帖子表单,因此我通过检查POST" isset"来检查表单是否已完成。

注册页面:

<?php
if (isset($_POST['email'])) {

    $thanks = '';

    $name = $_POST['name'];
    $email = $_POST['email'];
    $postcode = $_POST['postcode']; //not used
    $password = $_POST['password'];


    //connects to database, DB variable is dbConnection
    require_once("include/database_connect_test.php");

    //First check email isn't already on DB
    $sql = 'SELECT * FROM `user_profile` WHERE email=?';

    $stmt = $dbConnection->prepare($sql);
    $stmt->bind_param('s', $email);
    $stmt->execute();
    $stmt->store_result();


    $num_of_rows = $stmt->num_rows;
    $stmt->close();

    if($num_of_rows>0)
        $thanks = 'This email has already been registered';

    //If not, create profile
    else{

        require_once('generate_uuid.php');

        $hash = password_hash($password, PASSWORD_BCRYPT); //password_verify(pass, hash) to verify



        $sql = 'INSERT INTO `user_profile`(`name`, `email`, `hash`, `uuid`) VALUES (?,?,?,?)';

        $stmt = $dbConnection->prepare($sql);
        $stmt->bind_param('ssss', $name, $email, $hash, $uuid);

        $stmt->execute();

        $stmt->close();


        $thanks = 'Thank you for signing up!'; //used in the html
    }
}?>

提前感谢任何输入:)

4 个答案:

答案 0 :(得分:3)

从安全角度来看,我没有看到任何特别错误。你正在做最重要的事情:

  • 使用当前支持的MySQL扩展程序
  • 使用预备陈述
  • 使用password_hash()
  • 哈希密码

挑剔:

  • 设置$_POST['email']这一事实并不意味着其他帖子变量也会存在。您应该真正验证所有输入,因为填写表单并不是向脚本提交数据的唯一方法。但是,而不是 security 是一种确保您可以通过避免误报来利用PHP通知的方法。

    此外,您可能会喜欢过滤器扩展程序,这项功能已经推出了一段时间,但并不是特别普遍,并允许这样的代码:

    $name = filter_input(INPUT_POST, 'name');
    $email = filter_input(INPUT_POST, 'email');
    $postcode = filter_input(INPUT_POST, 'postcode'); //not used
    $password = filter_input(INPUT_POST, 'password');
    
  • 我从来不喜欢在结果集中对行进行计数以验证用户是否存在的技术,因为它太依赖于外部因素(数据库驱动程序,使用的查询函数......)。我只是获取行,这也允许检索会话变量的其他用户数据。

  • 我认为$uuid是在generate_uuid.php内定义的,但是当你看到代码时,它似乎无处不在。一个更好的结构是你包含的文件加载函数然后你调用这些函数:

    $uuid = generate_uuid();
    $stmt->bind_param('ssss', $name, $email, $hash, $uuid);
    

...但是,正如我所说,这些因素都不会影响安全性。

答案 1 :(得分:1)

以下是一些PHP功能和函数的集合,可用于代码块:

  • filter_var,检查字符串电子邮件地址$_POST['email']是否为有效的电子邮件形状:
 if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){...}
  • 您确实应该为Password_hash设置$options['cost']值。默认标准是10,这有点弱,这取决于您所说的服务器规格至少 12成本值。
$options['cost'] = 12;
$hash = password_hash($password, PASSWORD_BCRYPT,$options);
  • 我建议您通过$_POST Regex等自定义脱衣功能运行preg_replace变量。我个人总是会使用Regex例程从提交的字符串中删除不需要的字符。

  • 您的uuidid我希望它是一个计数器整数,但它会以字符串形式转换为绑定(S ),所以不确定是什么类型的变量?

  • 此外,您可以通过研究和查看Cross Site Scripting以及如何避免这种情况来提高安全性,基本上在提交表单中设置一个唯一值,并将此值保存到$_SESSION和然后进行比较,这将更加确保发送到您的PHP / MySQL的内容将来自您的发送表单。

  • 在相关的安全说明中,您还可以为您的网站设置Content Security Policy标题。

答案 2 :(得分:1)

  1. 用户枚举。使用两步注册(电子邮件链接)
  2. 您无法阻止高速机器人注册
  3. 您没有确认用户的电子邮件地址或密码(他们可能输错了。大多数网站都使用“确认密码”表单字段)
  4. 不验证数据(电子邮件真的是电子邮件,密码是十个空格吗?)
  5. 与安全性无关,您应该使用Post-Redirect-Get模式。目前,当用户看到“Thanks”消息时,如果他们在浏览器上点击“刷新”,它将尝试重新注册它们。

答案 3 :(得分:0)

现在有人可以将javascript作为他的用户名,如果你添加了一个javascript运行的评论部分。您的脚本容易受到xss注入攻击。使用mysqli_real_escape_string和htmlpurifier。