1. 程式人生 > >Session Cookie的HttpOnly和secure屬性

Session Cookie的HttpOnly和secure屬性

一、屬性說明:
1 secure屬性
當設定為true時,表示建立的 Cookie 會被以安全的形式向伺服器傳輸,也就是隻能在 HTTPS 連線中被瀏覽器傳遞到伺服器端進行會話驗證,如果是 HTTP 連線則不會傳遞該資訊,所以不會被竊取到Cookie 的具體內容。
2 HttpOnly屬性
如果在Cookie中設定了"HttpOnly"屬性,那麼通過程式(JS指令碼、Applet等)將無法讀取到Cookie資訊,這樣能有效的防止XSS攻擊。

對於以上兩個屬性,
首先,secure屬性是防止資訊在傳遞的過程中被監聽捕獲後資訊洩漏,HttpOnly屬性的目的是防止程式獲取cookie後進行攻擊。
其次,GlassFish2.x支援的是servlet2.5,而servlet2.5不支援Session Cookie的"HttpOnly"屬性。不過使用Filter做一定的處理可以簡單的實現HttpOnly屬性。GlashFish3.0(支援servlet3.0)預設開啟Session Cookie的HttpOnly屬性。
也就是說兩個屬性,並不能解決cookie在本機出現的資訊洩漏的問題(FireFox的外掛FireBug能直接看到cookie的相關資訊)。

What is it and why do I care ?

Session cookies (或者包含JSSESSIONID的cookie)是指用來管理web應用的session會話的cookies.這些cookie中儲存特定使用者的session ID標識,而且相同的session ID以及session生命週期內相關的資料也在伺服器端儲存。在web應用中最常用的session管理方式是通過每次請求的時候將cookies傳送到伺服器端來進行session識別。

你可以設定附加的secure標識來提示瀏覽器只能通過Https(加密方式)方式來傳輸cookie,Http(未加密方式)方式則不可以。這種方式來保證你的session cookie對於攻擊者是不可見的,避免中間人攻擊(Man-in-the-Middle Attack,簡稱“MITM攻擊”)。這並不是一個完美的session安全管理方案,卻是一個重要的步驟。

what should I do about it ?

應對方法很簡單。你必須在session cookie新增secure標識(如果有可能的話最好保證請求中的所有cookies都是通過Https方式傳輸)

如下是示例:未新增secure標識的session cookie-可能會被洩露

Cookie: jsessionid=AS348AF929FK219CKA9FK3B79870H;

新增secure標識:

Cookie: jsessionid=AS348AF929FK219CKA9FK3B79870H; secure;

方式很簡潔。你可以甚至可以手工設定這個標識,如果你在Servlet3或者更新的環境中開發,只需要在web.xml簡單的配置來實現。你只要在web.xml中新增如下片段:

  <!-- Cookie設定secure屬性,提示瀏覽器只能通過Https(加密方式)方式來傳輸cookie,
  Http(未加密方式)方式則不可以 -->
  <session-config>
    <cookie-config>
      <http-only>true</http-only>
      <secure>true</secure>
    </cookie-config>
  </session-config>

Filter:

import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * @Description: Cookie設定HttpOnly,Secure,Expire屬性
 * @Author [email protected]
 * @Date 2018/10/24 21:57
 */

public class CookieFilter implements Filter {

    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        Cookie[] cookies = req.getCookies();

        if (cookies != null) {
            Cookie cookie = cookies[0];
            if (cookie != null) {
	            	/*cookie.setMaxAge(3600);
	            	cookie.setSecure(true);
	            	resp.addCookie(cookie);*/

                //Servlet 2.5不支援在Cookie上直接設定HttpOnly屬性
                String value = cookie.getValue();
                StringBuilder builder = new StringBuilder();
                builder.append("JSESSIONID=" + value + "; ");
                builder.append("Secure; ");
                builder.append("HttpOnly; ");
                builder.append("Path=/; ");
                Calendar cal = Calendar.getInstance();
                cal.add(Calendar.HOUR, 1);
                Date date = cal.getTime();
                Locale locale = Locale.CHINA;
                SimpleDateFormat sdf =
                        new SimpleDateFormat("dd-MM-yyyy HH:mm:ss",locale);
                builder.append("Expires=" + sdf.format(date));
                resp.setHeader("Set-Cookie", builder.toString());
            }
        }
        chain.doFilter(req, resp);
    }

    public void destroy() {
    }

    public void init(FilterConfig arg0) throws ServletException {
    }

}```