0

我有一个网站,我让用户输入他们的用户名/密码以登录并将这些信息存储在一个文件中。这是我当前的代码:

function getPassword( $user )
{
  $passwords= array 
       (
        'Admin' => '123456',
        'Moderator' => 'abcde'
       );
 eval(file_get_contents('./login.info'));  //<--- THIS is where usernames/passwords are stored  

    $password = $passwords[ $user ];
    if ( NULL == $password )
        return NULL;

    return array( $user, $password );
}

这是我为用户创建新帐户的代码:

<?php
if((isset($_POST['username']))and(isset($_POST['password']))){
 $file = "login.info";
 $fh = fopen($file, 'a');
//prevent sql injection
function check_field($fh)
{
  if(!preg_match("/[^a-zA-Z0-9\.\-\_\@\.\+\~]/",$fh))
  return TRUE;
  else
  return FALSE;
}
if(!check_field($_POST[username]))
{
  header("Location:illegalchars.html");
  break;
}
if(!check_field($_POST[password]))
{
  header("Location:illegalchars.html");
  break;
}
 fwrite($fh, '$passwords["'.$_POST['username'].'"]="'.$_POST['password'].'";');
 fclose($fh);
 header("Location:success.html");
 break;
}
?>

我知道我的代码不漂亮.. 并且存在重大问题。
其中之一是:如果有人使用用户名 x 创建帐户,任何人仍然可以使用新密码创建 x 以获得控制权。
我的简单解决方案是将管理员帐户移到eval(file_get_contents('./login.info'));顶部,并将新帐户附加到新用户/通行证列表的顶部。但是,我不明白为什么将 eval 放在数组顶部不起作用。另外,我如何才能将代码附加到列表顶部。任何帮助是极大的赞赏。

==EDIT== 我知道对这段代码有很多批评,但是有人可以回答这个问题吗?我目前并没有试图提高安全性/性能(这是一个概念验证游戏,最终,这整个事情无论如何都必须重写)。我只想要一个功能脚本,请回答问题?:]

4

3 回答 3

2

坦率地说,这里存在重大问题。

零。您不应该存储明文密码。曾经。使用带盐的单向哈希,例如 sha1()(不是 md5),互联网上有大量关于此的手册。

一。使用 eval() 是不好的做法,无论是在性能方面还是在安全方面。寻找其他机制,他们总是在那里。

二。您应该使用可靠的数据存储机制,而不是 php 文件。建议使用 RDBMS,例如 mysql,它可以确保不会为用户创建重复记录。

三。您不应该在用户名上放置任何特殊含义,例如 admin 或 mod,将权限设置为特殊字段,或者更好的是,考虑使用基于角色的授权。

四。如果没有适当的架构,您将无法控制为某些用户运行的代码的安全性。考虑使用基于对象的 MVC 方法,您可以再次找到许多关于此的手册。

抱歉,这听起来很重要,但我坚信这比为您提供的代码发布补丁更好。

于 2011-01-18T05:26:01.197 回答
1

登录脚本

如果您真的不能不使用 openid 之类的东西,那么您可以在这里查看我改进的登录脚本(应该是最后的手段..)。

开放标识

出于对美好的热爱,请不要编写自己的登录系统(不要存储密码)。阅读 Stackoverflow 作者的这篇文章,了解Lifehacker 是如何被黑的。我特别喜欢这句话,我完全同意:

我不是来批评 Gawker 的。相反,我要感谢他们广泛而大胆地说明了有关网站密码的肮脏事实:没有密码我们都会过得更好。如果您希望看到一个没有 Gawker 风格密码泄露的未来网络 - 停止使用唯一的用户名和密码信任每个随机的互联网站点!要求他们允许您使用您的互联网驾照(即您现有的 Twitter、Facebook、Google 或 OpenID 凭据)登录他们的网站。

您应该使用例如 openid( lightopenid )。阅读链接以了解将 openid 集成到您的网站是多么容易。

于 2011-01-18T09:00:03.393 回答
1

我的天啊!

我可以在dailywtf上发布这个吗?

eval 和纯文本数据库本质上没有任何问题,但前提是没有更好的解决问题的方法。即便如此,您也应该广泛过滤 eval 的输入,并在数据库之上使用抽象。

OTOH 每次要执行任何操作时都读取整个数据库是完全错误的。

存储未加密的密码是错误的。

你说过你不能使用 mysql - 但是 dbm 呢?sqlite?一个快速的谷歌建议有很多平面文件抽象层在纯文本或 CSV 文件之上运行。

于 2011-01-18T12:40:21.337 回答