【转】安全的session管理

好文章,转载以备份。原文出自这里

 

前言

session 的管理對網站應用程式非常的重要,不適當或不夠嚴謹的管理也會造成安全上的問題,以下針對 session 管理相關的安全問題分項探討。

 

使用 Framework 內建的 Session Manager

藉由 session 限制與維護使用者的行為是網路安全很重要的一環。大多數的人會使用網站應用程式框架內建的 session 管理,有些人會使用 Perl CGI。網站開發者應盡量避免自行開發 session 管理,因為自行開發常常會藏有許多漏洞,而框架內建的 session 管理經過多次測試與修復相對上較為安全。此外這些框架會持續維護其安全性,因此要確保做好更新與安裝修補程式的動作。

  • 密碼強度
    Session handler 的一個重點是 session token 或 session ID 的密碼強度,Session handler 產生的 token 必須是無法預知並且長度夠長讓人無法猜測的到。Session tokens 必須每個使用者都不同、無法預測、能抵抗反向工程。
  • 適當的 Key Space
    一個加密的演算法也可能因為 Key space 不夠大造成攻擊者使用暴力解來取得內容。因此 token 的 Key space 必須足夠大來防禦暴力攻擊法,並且注意電腦計算能力與寬頻能力已隨著時代進步。
  • Session Identifier(session ID)
    Session Identifier 應該使用最大可用的 character set,如果一個 session ID 要由 8 characters of 7 bits 組成,有效密鑰長度為56位,但如果使用的 character set 只有整數可用 4 bits表示,有效密鑰長度就只有32位。因此一個好的 session ID 應盡量使用越多 characters 越好,但一些特殊字元有轉譯的麻煩,所以大多的 frameworks 採用 A-Z 和 0-9 有些還添加了小寫 a-z。

驗證由客戶端傳來的 Session ID

所有由客戶端傳來的資料都必須經過編碼和驗證,許多 frameworks 會驗證和編碼從 GET 和 POST 而來的 input,但未充分編碼從客戶端 cookie 傳來的 session ID 值。下面的 ESAPI code 片段使用 ESAPI 中的 method 來驗證 session ID 的值:

public String getRequestedSessionId() {
     String id = request.getRequestedSessionId();
     String clean = " ";
     try {
          clean = ESAPI.validator().getValidInput( "Requested cookie: " + id, id, "HTTPJSESSIONID", 50, false );
     } catch (ValidationException e ) {
          // already logged
     }
     return clean;
 }

 

 

確保 idle 和 timeouts 時間夠短

根據業務需求和安全性的考量,session 必須有一有限的壽命,在一定時間後過期。網站應用程式必須將靜止一段時間的 session 設為過期,刪除此 session 並一併更改 session cookie 的內容。

 

在使用者登出後銷毀 session

當使用者登出後網站應用程式需讓 session 無效或者移除此 session,並且如果隨後有別的使用者登入必須取得不同的 session ID。要做到這樣的機制,當使用者 logout 時必須改寫 session cookies 註明已過期並銷毀 session。以下是 ESAPI code 的例子:

public void logout() {
     ESAPI.httpUtilities().killCookie( ESAPI.currentRequest(), ESAPI.currentResponse(), HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME );

     HttpSession session = ESAPI.currentRequest().getSession(false);
     if (session != null) {
          session.invalidate();
     }
     ESAPI.httpUtilities().killCookie(ESAPI.currentRequest(), ESAPI.currentResponse(), "JSESSIONID");
     loggedIn = false;
     logger.info(Logger.SECURITY, "Logout successful" );
     ESAPI.authenticator().setCurrentUser(User.ANONYMOUS);
}

 

 

public void killCookie(HttpServletRequest request, HttpServletResponse response, String name) {
     String path = "//";
     String domain=" ";
     Cookie cookie = ESAPI.httpUtilities().getCookie(request, name);
     if ( cookie != null ) {
          path = cookie.getPath();
          domain = cookie.getDomain();
     }
     SafeResponse safeResponse = new SafeResponse( response );
     safeResponse.addCookie(name, "deleted", 0, domain, path);
}

 

輪換 Session ID

對於高安全性網站,網站應用程式在處理重要的程序之前,或是經過某一段時間和幾次 requests 後,必須重新產生 session ID。中等或低等的網站,在使用者權限改變時也應該重新產生 session ID ,例如從訪客變成登入的會員或從登入者變成管理者。以下是 ESAPI code 重新產生 Session ID 的例子:

public HttpSession changeSessionIdentifier(HttpServletRequest request) throws AuthenticationException {

     // get the current session
     HttpSession session = request.getSession();

     // make a copy of the session content
     Map temp = new HashMap();
     Enumeration e = session.getAttributeNames();
     while (e != null && e.hasMoreElements()) {
          String name = (String) e.nextElement();
          Object value = session.getAttribute(name);
          temp.put(name, value);
     }

     // kill the old session and create a new one
     session.invalidate();
     HttpSession newSession = request.getSession();

     // copy back the session content
     Iterator i = temp.entrySet().iterator();
     while (i.hasNext()) {
          Map.Entry entry = (Map.Entry) i.next();
          newSession.setAttribute((String) entry.getKey(), entry.getValue());
     }
     return newSession;
}

 

 

保護 Session ID

如果可以的話,網站應用程式應該都以 HTTPS 的方式傳輸。如果無法,至少包含敏感性資料的頁面或處理程序要使用 HTTPS; 如果 HTTPS 無法保護整個網站的 session,在 HTTPS 傳輸時必須搭配 session ID,將此 session ID 和網站伺服器的 session 做配對檢查。

如果必須藉由 URL 參數來傳遞 session ID 時,必須使用 POST。如果 cookies 用來儲存並由 HTTPS 傳送 session ID 時,必須被設為”安全”這樣就不會經過 non-SSL 的管道。

網站應用程式必須提供登出的機制,並確保登出後此 session 過期和被銷毀。

 

作者列表

  1. 2011/03/21 姚辰旻 初稿

參考資料

 

PS:

ESAPI的站点都访问不了?


Total views.

© 2013 - 2018. All rights reserved.

Powered by Hydejack v6.6.1