2012-07-13 140 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。雖然在這種情況下它可能並不重要,但它有助於防止會話重播或會話修復攻擊。

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

  • 密碼策略
    • 密碼長度
    • 號碼+特殊字符
  • 密碼短語
    • 如果你能確保單詞可能會有更多的熵不常見
  • 取締後失敗的登錄嘗試
  • 添加雙因素認證