2012-07-13 102 views
1

第一次为网页创建一个登录系统,我一直在努力读懂安全性,但不确定我是否正确地做了。我的登录会话是否安全?

到目前为止,我有一个用户名/密码存储和密码哈希与SHA256和3字符盐。如果用户名和密码都正确,那么我提出一个新的会话ID这样

session_regenerate_id(); 
$_SESSION['valid'] = 1; 
$_SESSION['userid'] = $userid; 

在每一页我检查

function isLoggedIn() 
{ 
if(isset($_SESSION['valid']) && $_SESSION['valid']) 
    return true; 
return false; 
} 

我用它来检查是否有正确的用户

$username = $_POST['username']; 
$password = $_POST['password']; 
//connect to the database here 
connect(); 
//save username 
$username = mysql_real_escape_string($username); 
//query the database for the username provided 
$query = "SELECT password, salt 
    FROM users 
    WHERE username = '$username';"; 
$result = mysql_query($query); 
if(mysql_num_rows($result) < 1) //no such user exists 
{ 
    //show incorrect login message 
} 
//check the password is correct for the username found 
$userData = mysql_fetch_array($result, MYSQL_ASSOC); 
$hash = hash('sha256', $userData['salt'] . hash('sha256', $password)); 
if($hash != $userData['password']) //incorrect password 
{ 
    //show incorrect login message 
} 
else 
{ 
//setup a new session 
validateUser(); 
//redirect to the main page 
header('Location: main.php'); 
die(); 

如果它是假的,那么它们会被发送回登录页面。这足够安全吗?

主页我也有HTML

链接

<li><a href="main.php">Home page</a> 

,所以我需要结束主页上的PHP脚本时使用这些链接?

+0

如果这是您第一次登录,就ok了。但是你应该阅读关于登录安全性。有很多事情要考虑。 – machineaddict 2012-07-13 09:46:25

+3

3焦炭盐?如果是16个字符并且每个用户都有自己的盐,那将更安全。 – 2012-07-13 09:51:46

+3

这绝对值得一读:[基于表单的网站验证权威指南](http://stackoverflow.com/questions/549/the-definitive-guide-to-forms-based-website-authentication) – Polynomial 2012-07-13 15:16:15

回答

4

加入什么phpdev表示。尽管它看起来足够安全,但我还是推荐了几件事情。

当你想发送一个用户到某个页面时,确保你的脚本退出并完成执行,因为如果仍然有一些行会被执行。借此,例如:

if (!isLoggedIn()){ 
    header('Location: login.php'); 
} 
//It's wrong to assume that things are safe here 
echo $secret_data; 

所以请确保您在header()调用后添加exit();die();

而且散列时,请确保你每用户使用独特的盐,所以你需要在你的users表下一存储salt的哈希密码来创建一个额外的列。强烈建议使用经过良好测试的散列库,如PHPass

如果您要在同一台服务器上使用同一域中运行不同的网络服务,如: mysite.com/my_super_awesome_appmysite.com/my_not_very_awesome_app确保您无论是在$_SESSION前缀添加到您的变量名像$_SESSION['app1_valid']或限制会话Cookie使用某一路径session_set_cookie_params()

+0

谢谢,如果我有一个页面的一些PHP,但也是HTML链接时,我仍然需要结束脚本时,用户导航到另一个页面使用HTML链接? – dan 2012-07-13 13:08:37

+0

@dan,我不确定我对你的理解是否够好,欢迎你编辑你的问题并添加一些我和其他人可以检查的代码。 – Adi 2012-07-13 13:23:37

+0

您可以在PHP> = 5.1.2上使用PHP'hash()'函数。另外,丹,你在重定向后退出。 – 2012-07-13 19:57:53

3

是的,这对我来说看起来很安全。只要确保在做任何事情之前致电session_start(),并小心你正在设置的位置$_SESSION['valid']。确保只有在确认他们输入了正确的用户名和密码后才能设置。至于腌制,我会建议一个独特的盐,每个用户约10个字符。然后用和blowfish算法(bcrypt)对结果进行散列。 BCrypt的设计使得计算散列的代价越来越高,如果有人窃取密码散列,这非常重要。

0

对于基本的应用程序,它看起来没问题。还有很多事情可以做。计时器。字典攻击。登录尝试会话。搜索SO。

function is_customer_logged_in() { 
    if($_COOKIE['GC_CUST_LOGIN']==1 && $_SESSION["loggedIn"]=="1"){ 
     return true; 
    }else{ 
     return false; 
    } 
} 

$_SESSION["time"]=time(); 
setcookie("GC_CUST_LOGIN", 1, ".stackoverflow.com"); 
$_SESSION["loggedIn"]="1"; 
$_SESSION["loggedIn_Md5_Hash"]=md5(hash); 

您还可以插入该会话哈希值,检查是否登录,并添加了许多,还可以使用cookie和session数据库检查后强制匹配。

2

不要忘记要求登录表单中的HTTPS前进,否则这完全没有用处。

0

有很多事情要考虑密码安全。不幸的是,sha-256仍然没有击败bcrypt或scrypt(它们实现了关键拉伸,盐分和可扩展的工作因素,以帮助硬件提高)。

我想通过openwall检查phpass(http://www.openwall.com/phpass/)这是一个非常标准的bcrypt库,易于使用。

就像其他人所说的,除非您的登录页面通过HTTPS保护,否则密码仍然可以被窥探。

我喜欢你正在重新生成session_id。虽然在这种情况下它可能并不重要,但它有助于防止会话重播或会话修复攻击。

一些其他的事情要考虑,以使您的系统一般更安全:

  • 密码策略
    • 密码长度
    • 号码+特殊字符
  • 密码短语
    • 如果你能确保单词可能会有更多的熵不常见
  • 取缔后失败的登录尝试
  • 添加双因素认证