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 {
}
}```