cookie setSecure详解
1. 前言
最近项目用Sparrow Health System检测漏洞,发现存在一个setSecure安全漏洞问题,于是网上搜索了一下,这里记录一下。
2. 问题
在cas中或其他web开发中,会碰到安全cookie的概念,因为CAS中TGT是存放在安全cookie中的。下面是安全cookie 的理解:
- Set-Cookie 的 secure 属性就是处理这方面的情况用的,它表示创建的 cookie 只能在 HTTPS 连接中被浏览器传递到服务器端进行会话验证,如果是 HTTP 连接则不会传递该信息,所以绝对不会被窃听到。
在setSecure(true); 的情况下,只有https才传递到服务器端。http是不会传递的。
setSecure(true)意味着"指示浏览器仅通过 HTTPS 连接传回 cookie。这可以确保 cookie ID 是安全的,且仅用于使用 HTTPS 的网站。如果启用此功能,则 HTTP 上的会话 Cookie 将不再起作用。"
j2ee servlet的接口中也定义了Cookie对象,也有其方法setSecue(false);
关于setSecure的问题,在http连接下:
- 当setSecure(true)时,浏览器端的cookie会不会传递到服务器端?
- 当setSecure(true)时,服务器端的cookie会不会传递到浏览器端?
- 答案:1)不会 ; 2)会
原理:服务器端的Cookie对象是java中的对象,请不要和浏览器端的cookie文件混淆了。服务器端的Cookie对象是方便java程序员包装一个浏览器端的cookie文件。一旦包装好,就放到response对象中,在转换成http头文件。在传递到浏览器端。这时就会在浏览器的临时文件中创建一个cookie文件。
但我们再次访问网页时,才查看浏览器端的cookie文件中的secure值,如果是true,但是http连接,这个cookie就不会传到服务器端。当然这个过程对浏览器是透明的。其他人是不会知道的。
总结如下:cookie的secure值为true时,在http中是无效的;在https中才有效
3. Cookie设置
实际上,Servlet提供的HttpSession
本质上就是通过一个名为JSESSIONID
的Cookie来跟踪用户会话的。除了这个名称外,其他名称的Cookie我们可以任意使用。
如果我们想要设置一个Cookie,例如,记录用户选择的语言,可以编写一个LanguageServlet
:
@WebServlet(urlPatterns = "/pref")
public class LanguageServlet extends HttpServlet {private static final Set<String> LANGUAGES = Set.of("en", "zh");protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String lang = req.getParameter("lang");if (LANGUAGES.contains(lang)) {// 创建一个新的Cookie:Cookie cookie = new Cookie("lang", lang);// 该Cookie生效的路径范围:cookie.setPath("/");// 该Cookie有效期:cookie.setMaxAge(8640000); // 8640000秒=100天// 将该Cookie添加到响应:resp.addCookie(cookie);}resp.sendRedirect("/");}
}
创建一个新Cookie时,除了指定名称和值以外,通常需要设置setPath("/")
,浏览器根据此前缀决定是否发送Cookie。如果一个Cookie调用了setPath("/user/")
,那么浏览器只有在请求以/user/
开头的路径时才会附加此Cookie。通过setMaxAge()
设置Cookie的有效期,单位为秒,最后通过resp.addCookie()
把它添加到响应。
如果访问的是https网页,还需要调用setSecure(true)
,否则浏览器不会发送该Cookie。
因此,务必注意:浏览器在请求某个URL时,是否携带指定的Cookie,取决于Cookie是否满足以下所有要求:
- URL前缀是设置Cookie时的Path;
- Cookie在有效期内;
- Cookie设置了
setSecure(true)
时必须以https访问。
我们可以在浏览器看到服务器发送的Cookie:
如果我们要读取Cookie,例如,在IndexServlet
中,读取名为lang
的Cookie以获取用户设置的语言,可以写一个方法如下:
private String parseLanguageFromCookie(HttpServletRequest req) {// 获取请求附带的所有Cookie:Cookie[] cookies = req.getCookies();// 如果获取到Cookie:if (cookies != null) {// 循环每个Cookie:for (Cookie cookie : cookies) {// 如果Cookie名称为lang:if (cookie.getName().equals("lang")) {// 返回Cookie的值:return cookie.getValue();}}}// 返回默认值:return "en";
}
可见,读取Cookie主要依靠遍历HttpServletRequest
附带的所有Cookie。
4. setSecure测试
下面我自己再实验一下:
4.1 http访问测试
我自己的电脑用的Tomcat,首先,把cookie-secure的值设为false,创建一个session:
1 public void service(HttpServletRequest request, HttpServletResponse response) {2 // 创建cookie3 Cookie cookie = new Cookie("key", "value");4 // 关键地方:cookie设为false5 cookie.setSecure(false);6 response.addCookie(cookie);7 // 从request中取得cookie,并输出8 Cookie[] cookies = request.getCookies();9 for (Cookie c : cookies) { 10 System.out.println(c.getValue()); 11 } 12 RequestDispatcher dispatcher = request 13 .getRequestDispatcher("index.jsp"); 14 try { 15 dispatcher.forward(request, response); 16 } catch (ServletException e) { 17 e.printStackTrace(); 18 } catch (IOException e) { 19 e.printStackTrace(); 20 } 21 }
好,我们访问一下这个地址:http://localhost:8080/servlet/index.do
用Fiddler来看一下客户端发出的信息:
好,我们再访问一下前面的地址:
这个时候我们可以看到客户端发出的cookie里面,有key=value,说明客户端把cookie发给了服务器端。
4.2 https访问测试
那如果我们在服务器端设置cookie.setSecure(true)呢?
先上代码:
1 public void service(HttpServletRequest request, HttpServletResponse response) {2 // 创建cookie3 Cookie cookie = new Cookie("key", "value");4 // 关键地方:cookie设为false5 cookie.setSecure(true); 6 response.addCookie(cookie);7 // 从request中取得cookie,并输出8 Cookie[] cookies = request.getCookies();9 if (cookies != null) { 10 for (Cookie c : cookies) { 11 System.out.println(c.getValue()); 12 } 13 } 14 RequestDispatcher dispatcher = request 15 .getRequestDispatcher("index.jsp"); 16 try { 17 dispatcher.forward(request, response); 18 } catch (ServletException e) { 19 e.printStackTrace(); 20 } catch (IOException e) { 21 e.printStackTrace(); 22 } 23 }
第一次http访问:
这是request的信息。
服务器的返回信息如下:
我们可以看到服务器发给客户端的信息中有这么一行:Set-Cookie:key=value; Secure
多了一个Secure。
第二次http访问:
我们发现key=value这个cookie已经没有了。
第三次https访问:
那我们用https协议头来试着访问一下看看:
我们看到key=value又发给了服务器端了。
5. 另外
cookie中的数据通常会包含用户的隐私数据,首先要保证数据的保密性,其次要保证数据不能被伪造或者篡改,基于这两点,我们通常需要对cookie内容进行加密,加密方式一般使用对称加密(单密钥,如DES)或非对称加密(一对密钥,如RSA),密钥需要保存在服务器端一个安全的地方,这样,别人不知道密钥时,无法对数据进行解密,也无法伪造或篡改数据。
另外,像上文提到的,重要的cookie数据需要设置成HttpOnly的,避免跨站脚本获取你的cookie,保证了cookie在浏览器端的安全性。
还有我们可以设置cookie只作用于安全的协议(https),JavaEE中可以通过Cookie类的setSecure(boolean flag)来设置,设置后,该cookie只会在https下发送,而不会再http下发送,保证了cookie在服务器端的安全性,
6. 例子
import javax.servlet.http.Cookie; //導入方法依賴的package包/類
/*** Creates a new session cookie for the given session ID** @param context The Context for the web application* @param sessionId The ID of the session for which the cookie will be* created* @param secure Should session cookie be configured as secure*/
public static Cookie createSessionCookie(Context context,String sessionId, boolean secure) {SessionCookieConfig scc =context.getServletContext().getSessionCookieConfig();// NOTE: The priority order for session cookie configuration is:// 1. Context level configuration// 2. Values from SessionCookieConfig// 3. DefaultsCookie cookie = new Cookie(SessionConfig.getSessionCookieName(context), sessionId);// Just apply the defaults.cookie.setMaxAge(scc.getMaxAge());cookie.setComment(scc.getComment());if (context.getSessionCookieDomain() == null) {// Avoid possible NPEif (scc.getDomain() != null) {cookie.setDomain(scc.getDomain());}} else {cookie.setDomain(context.getSessionCookieDomain());}// Always set secure if the request is secureif (scc.isSecure() || secure) {cookie.setSecure(true);}// Always set httpOnly if the context is configured for thatif (scc.isHttpOnly() || context.getUseHttpOnly()) {cookie.setHttpOnly(true);}String contextPath = context.getSessionCookiePath();if (contextPath == null || contextPath.length() == 0) {contextPath = scc.getPath();}if (contextPath == null || contextPath.length() == 0) {contextPath = context.getEncodedPath();}if (context.getSessionCookiePathUsesTrailingSlash()) {// Handle special case of ROOT context where cookies require a path of// '/' but the servlet spec uses an empty string// Also ensure the cookies for a context with a path of /foo don't get// sent for requests with a path of /foobarif (!contextPath.endsWith("/")) {contextPath = contextPath + "/";}} else {// Only handle special case of ROOT context where cookies require a// path of '/' but the servlet spec uses an empty stringif (contextPath.length() == 0) {contextPath = "/";}}cookie.setPath(contextPath);return cookie;
}
/*** 往客戶端寫入Cookie* @param name cookie參數名* @param value cookie參數值* @param maxAge 有效時間,int(單位秒),0:刪除Cookie,-1:頁麵關閉時刪除cookie* @param path 與cookie一起傳輸的虛擬路徑* @param domain 與cookie關聯的域* @param isSecure 是否在https請求時才進行傳輸* @param isHttpOnly 是否隻能通過http訪問*/
public void addCookie(String name, String value, int maxAge, String path, String domain, boolean isSecure, boolean isHttpOnly)
{Cookie cookie = new Cookie(name, value);cookie.setMaxAge(maxAge);cookie.setPath(path);if(maxAge > 0 && domain != null){cookie.setDomain(domain);}cookie.setSecure(isSecure);try{Cookie.class.getMethod("setHttpOnly", boolean.class);cookie.setHttpOnly(isHttpOnly);}catch(Exception e){System.out.println("MyCookie ignore setHttpOnly Method");}response.addCookie(cookie);
}
参考
cookie setSecure详解_wangyunpeng0319的博客-CSDN博客_cookie.setsecure
使用Session和Cookie - 廖雪峰的官方网站
COOKIE的SECURE属性 - 画水 - 博客园
cookie setSecure详解相关推荐
- 安全cookie setSecure详解
http://www.coin163.com/java/docs/201304/d_2775029502.html 在cas中或其他web开发中,会碰到安全cookie的概念,因为CAS中TGT是存放 ...
- php的cookie教程,PHP4之COOKIE支持详解
PHP4之COOKIE支持详解 发布时间:2016-06-17 来源: 点击: 次 PHP4之COOKIE支持详解 建立商业站点或者功能比较完善的个人站点,常常需要记录访问者的信息,在PHP中提供了两 ...
- cookie 操作详解 (asp.net javascript)
(1)ASP.NET cookie 操作详解|cookie 写入.读取.修改.删除2008年10月18日 //写入 protected void Button2_Click(objec ...
- python获取登录后的cookie_python爬虫使用cookie登录详解
前言: 什么是cookie? Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密). 比如说有些网站需要登录后才能访问某个页面,在登录之前,你想 ...
- Cookie用法详解
cookie简介 1. 定义 cookie是由服务器发送给客户端(浏览器)的小量信息. 2. 作用 cookie是键值对形式存储的少量信息,那它有什么作用呢? 我们知道,平时上网时都是使用无状态的HT ...
- php 中 app cookie管理,详解iOS App开发中Cookie的管理方法
一.何为Cookie Cookie是网站为了便是终端身份,保存在终端本地的用户凭证信息.Cookie中的字段与意义由服务端进行定义.例如,当用户在某个网站进行了登录操作后,服务端会将Cookie信息返 ...
- 关于登录记住密码使用cookie的详解
下面是我看的一篇文章引用过来,很易懂 设置cookie 每个cookie都是一个名/值对,可以把下面这样一个字符串赋值给document.cookie: document.cookie="u ...
- Javascript cookie使用详解
2019独角兽企业重金招聘Python工程师标准>>> 设置cookie每个cookie都是一个名/值对,可以把下面这样一个字符串赋值给document.cookie: docume ...
- HTTP Session、Cookie机制详解
一.什么是http session,有什么用 HTTP协议本身是无状态的,本身并不能支持服务端保存客户端的状态信息,于是,Web Server中引入了session的概念,用来保存客户端的状态信息. ...
最新文章
- 在CentOS 6.9 x86_64上从源码安装xz命令的方法
- pytorch元素相乘_PyTorch – 变量和张量之间的元素乘法?
- 多语言切换jquery.i18n.min.js
- C# 用户控件之温度计
- CTO下午茶: 没有安全,一切创新都是套路
- ./dmitry -p ip或者域名 -f -b
- DEV GridView嵌套
- Docker Compose 项目
- Oracle全文索引之五 测试
- python机器学习彩票_Python机器学习及实战kaggle从零到竞赛PDF电子版分享
- C语言枚举类型(Enum)
- Pytorch——计算机视觉工具包:torchvision
- Monkey压力测试
- centos7安装python开发环境(python3_postgresql_sublime_supervisor)
- Spring Cloud Netflix 服务注册与发现 — Eureka 入门案例
- u盘的大小在计算机无法显示,U盘格式化后插入电脑打不开,不显示U盘大小怎么解决?...
- photoshop图层解锁及不能解锁的原因
- uni-app app平台微信支付
- 油管613万播放的星巴克3小时背景音乐无广告纯享版下载
- Ubuntu Server 12.04 搭建 hadoop 集群版环境——基于VirtualBox
热门文章
- 解决远古VOD注入漏洞
- KMPLAYER绿色单文件深度专版
- 5G NR SIB1介绍
- 位是存储在计算机中的最小单位,在计算机中信息存储的最小单位是什么?
- 【技术分享】 ​IE浏览器漏洞利用技术的演变 ( 二 )
- XP系统上出现的“你可能是盗版软件受害者”的解决方法
- php拒绝式服务漏洞防御,PHPYUN最新版SQL注入(绕过防御)
- 小心系统入侵之八——招吸星大法(转)
- 基于容积卡尔曼滤波(CubatureKalmam Filter, CKF)的车辆状态观测器 Carsim与Simulink联合 可生成C代码
- 【已解决】‘node‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件 / 全新安装node