ESAPI之會話安全

ESAPI是開源組織owasp,開放的安全開發框架,但百度、google搜索相關的技術文章很少,今天小嚐試了一下,分享一下心得。

會話攻擊,簡單理解就是盜用竊取用戶的cookie,僞裝成用戶,向服務器端發送請求,竊取用戶私密信息。

具體如何防止會話攻擊,很簡單,參照《Web應用安全威脅與防治--基於OWASP TOP 10 與ESAPI》書中介紹的方法,一旦用戶登錄成功後,馬上validate用戶的會話,具體步驟如下:

  1. 用戶輸入用戶名和密碼
  2. 系統對用戶進行驗證通過
  3. 已有的會話信息如果仍然需要,則轉移到一個臨時變量中去
  4. invalidate當前會話
  5. 創建一個新會話
  6. 把臨時變量中保存的會話信息恢復到新創建的會話中去
  7. 用戶使用這個新的會話登錄到系統中並進行操作


貼出實例

構造一個簡單登錄頁面

<body>
    <form action="loginServlet" method="post">
    	用戶名:<input type="text" name="username" /><br/>
    	密碼:<input type="password" name="password"/><br/>
    	<input type="submit" value="登錄"/>
    </form>
  </body>

驗證成功的頁面

 <body>
    歡迎${sessionScope.username }登錄
  </body>

然後是一個LoginServlet,其中DefaultHTTPUtilities是ESAPI中org.owasp.esapi.reference.DefaultHTTPUtilities類,該類的changeSessionIdentifier(request),就是實現上述功能。

public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		DefaultHTTPUtilities dhUtil = new DefaultHTTPUtilities();
		try {
			HttpSession session = dhUtil.changeSessionIdentifier(request);
			session.setAttribute("username", username);
			session.setAttribute("password", password);
			request.getRequestDispatcher("/index.jsp").forward(request, response);
		} catch (AuthenticationException e) {
			e.printStackTrace();
		}
	}

貼出changeSessionIdentifier(request)方法源碼


public HttpSession changeSessionIdentifier(HttpServletRequest request) throws AuthenticationException {

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

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

		// kill the old session and create a new one
		oldSession.invalidate();
		HttpSession newSession = request.getSession();
		User user = ESAPI.authenticator().getCurrentUser();
		user.addSession( newSession );
		user.removeSession( oldSession );

		// copy back the session content
      for (Map.Entry<String, Object> stringObjectEntry : temp.entrySet())
      {
         newSession.setAttribute(stringObjectEntry.getKey(), stringObjectEntry.getValue());
		}
		return newSession;
	}

這段代碼應該很好理解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章