<pre name="code" class="html"><p style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "> <a target=_blank href="http://www.infoq.com/cn/articles/cookie-security">原文连接</a></p><p style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "> 在 Web 应用中,Cookie 很容易成为安全问题的一部分。从以往的经验来看,对 Cookie 在开发过程中的使用,很多开发团队并没有形成共识或者一定的规范,这也使得很多应用中的 Cookie 成为潜在的易受攻击点。在给 Web 应用做安全架构评审(Security architecture review)的时候,我通常会问设计人员以下几个问题:</p><ol style="margin: 0px 0px 0px 50px; padding: 0px; font-family: verdana, Arial, Helvetica, sans-serif; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "><li style="margin: 0px; padding: 0px; font-size: 14px; list-style: decimal; ">你的应用中,有使用 JavaScript 来操作客户端 Cookie 吗?如果有,那么是否必须使用 JavaScript 才能完成此应用场景?如果没有,你的 Cookie 允许 JavaScript 来访问吗?</li><li style="margin: 0px; padding: 0px; font-size: 14px; list-style: decimal; ">你的网站(可能包含多个 Web 应用)中,对于 Cookie 的域(Domain)和路径(Path)设置是如何制定策略的?为何这样划分?</li><li style="margin: 0px; padding: 0px; font-size: 14px; list-style: decimal; ">在有 SSL 的应用中,你的 Cookie 是否可以在 HTTP 请求和 HTTPS 请求中通用?</li></ol><p style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "> 在实际的应用场景中,Cookie 被用来做得最多的一件事是保持身份认证的服务端状态。这种保持可能是基于会话(Session)的,也有可能是持久性的。不管哪一种,身份认证 Cookie 中包含的服务端票据(Ticket)一旦泄露,那么服务端将很难区分带有此票据的用户请求是来自于真实的用户,或者是来自恶意的攻击者。在实际案例中,造成 Cookie 泄露最多的途径,是通过跨站脚本(XSS, Cross Site Script)漏洞。攻击者可以通过一小段 JavaScript 代码,偷窃到代表用户身份的重要的 Cookie 标示。由于跨站脚本漏洞是如此的普遍(不要以为简单的 HTML Encode 就可以避免被跨站,跨站是一门很深的学问,以至于在业界衍生出一个专用的名词:跨站师),几乎每一个网站都无法避免,所以这种方式是实际攻防中被普遍使用的一种手段。</p><p style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "> 避免出现这种问题的首要秘诀就是尽所有的可能,给你的 Cookie 加上 HttpOnly 的标签。HttpOnly 的具体使用不在本文的讨论范围内,否则作者略有骗 InfoQ 稿酬的嫌疑。一个大家所不太熟悉的事实是,HttpOnly 是由微软在 2000 年 IE6 Sp1 中率先发明并予以支持的。截止现在,HttpOnly 仍然只是一个厂商标准,但是在过去的十余年中,它得到了众多浏览器的广泛支持。</p><p style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "> 下表是 OWASP 整理的关于主流浏览器对 HttpOnly 支持情况的一个总结。从表中可以看出,目前主流的浏览器,除了 Android 之外,几乎都无一例外对这一属性予以了支持。</p><p style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "> 当然对于中国开发者来说,需要考虑的问题更加复杂一些:在这个神奇的地方,有大量的用户使用的浏览器并不在以下的列表中,他们使用的是以下面浏览器中的一种或者数种为内核的“精装版”浏览器。这些浏览器厂商对于同源策略、HttpOnly Cookie、证书管理等安全规范的支持情况,有待于进一步调查。</p><table border="1" cellspacing="0" cellpadding="0" style="margin: 0px auto; padding: 0px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; color: rgb(35, 35, 35); font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; line-height: 28px; text-align: left; background-color: rgb(250, 255, 255); width: 617px; "><tbody style="margin: 0px; padding: 0px; "><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; "><span style="margin: 0px; padding: 0px; color: rgb(51, 51, 51); ">Browser</span></p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; "><span style="margin: 0px; padding: 0px; color: rgb(51, 51, 51); ">Version</span></p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; "><span style="margin: 0px; padding: 0px; color: rgb(51, 51, 51); ">Prevents Reads</span></p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; "><span style="margin: 0px; padding: 0px; color: rgb(51, 51, 51); ">Prevents Writes</span></p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Microsoft Internet Explorer</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">10</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Microsoft Internet Explorer</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">9</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Microsoft Internet Explorer</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">8</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Microsoft Internet Explorer</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">7</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Microsoft Internet Explorer</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">6 (SP1)</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">No</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Microsoft Internet Explorer</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">6 (fully patched)</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Unknown</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Mozilla Firefox</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">3. 0.0.6+</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Netscape Navigator</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">9. 0b3</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Opera</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">9. 23</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">No</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">No</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Opera</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">9. 5</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">No</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Opera</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">11</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Unknown</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Safari</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">3</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">No</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">No</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Safari</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">5</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">iPhone (Safari)</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">iOS 4</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Google's Chrome</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Beta (initial public release)</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">No</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Google's Chrome</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">12</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Yes</p></td></tr><tr style="margin: 0px; padding: 0px; "><td width="205" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Android</p></td><td width="143" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Android 2.3</p></td><td width="113" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Unknown</p></td><td width="154" style="margin: 0px; padding: 5px; line-height: 25px; border: 1px solid rgb(192, 192, 192); border-collapse: collapse; "><p align="center" style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; ">Unknown</p></td></tr></tbody></table><p style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "> 在我看来,一个 Web 应用的每一个 Cookie 都应该带上 HttpOnly 的标签。我没有看到这个决定可能带来的负面作用,如果一定要说有的话,那么就是你的应用将不能再通过 JavaScript 来读写 Cookie 了。可是这真有必要吗?个人认为,JavaScript 操作 Cookie 是一种不正常的做法;可以用 JavaScript 操作 Cookie 完成的功能,一样可以用服务端响应 Http 头设置 Cookie 来完成。相反,设置所有的 Cookie 为 HttpOnly 带来的巨大好处则非常明显:尽管你需要继续修复 XSS 漏洞,但是这些漏洞至少暂时不会让你的用户遭受大规模的账户损失。</p><p style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "> 关于 Cookie 的第二个话题是域设置。</p><p style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "> 浏览器在选择发送哪些本地 Cookie 到本次请求的服务端时,有一系列的比较和甄别。这些甄别中最重要的部分是 Domain 和 Path 的吻合。Domain 形如 .abc.com 的 Cookie,会被发送给所有 abc.com 在 80 端口上的子域请求。但是反之则不行,这就是 Cookie 的域匹配(domain match)原则。</p><p style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "> 在一个大型 Web 站点中,往往有多个应用,生存在不同的子域名或路径下。这些应用之间由于共享同一个域名,所以往往可能会彼此有操作对方应用 Cookie 的能力。这种情况下,设计好 Cookie 的 Domain 和 Path 尤为重要。在实际设计工作中,最重要的一个安全原则就是:最小化授权。这意味着,你需要将自己的 Cookie 可被访问到的范围降至最低。应用之间传递数据和共享信息的解决方案非常多,而通过 Cookie 这种用户输入(User input)来共享数据,是最不安全的解决方案之一。</p><p style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "> Cookie 另外一个不太常被使用的属性是 Secure. 这个属性启用时,浏览器仅仅会在 HTTPS 请求中向服务端发送 Cookie 内容。如果你的应用中有一处非常敏感的业务,比如登录或者付款,需要使用 HTTPS 来保证内容的传输安全;而在用户成功获得授权之后,获得的客户端身份 Cookie 如果没有设置为 Secure,那么很有可能会被非 HTTPS 页面中拿到,从而造成重要的身份泄露。所以,在你的 Web 站点中,如果使用了 SSL,那么你需要仔细检查在 SSL 的请求中返回的 Cookie 值,是否指定了 Secure 属性。</p><p style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "> 除此之外还值得特别指出的是,一些 Web 应用除了自己的程序代码中生成的 Cookie,往往还会从其他途径生成一些 Cookie。例如由 Web Server 或者应用容器自动生成的会话 Cookie,由第三方库或者框架生成的 Cookie 等等。这些都需要进行有针对性的加固处理。</p><p style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "> 几乎每个站点都难以离开 Cookie,但 Cookie 的使用因其貌似简单,而很容易被人轻视。重新审视应用中的 Cookie 代码,几乎只需要很小的代价就可以获得巨大的安全收益。</p><p style="margin-top: 5px; margin-bottom: 5px; padding-top: 0px; padding-bottom: 0px; font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; color: rgb(35, 35, 35); line-height: 28px; background-color: rgb(250, 255, 255); "> <span style="margin: 0px; padding: 0px; color: rgb(51, 51, 51); ">参考文章</span></p><ul style="margin: 0px 0px 0px 50px; padding: 0px; font-family: verdana, Arial, Helvetica, sans-serif; color: rgb(35, 35, 35); list-style: none; line-height: 28px; background-color: rgb(250, 255, 255); "><li style="margin: 0px; padding: 0px; font-size: 14px; list-style: disc; "><a target=_blank href="http://en.wikipedia.org/wiki/HTTP_cookie" style="margin: 0px; padding: 0px; color: rgb(26, 100, 162); text-decoration: none; ">http://en.wikipedia.org/wiki/HTTP_cookie</a></li><li style="margin: 0px; padding: 0px; font-size: 14px; list-style: disc; "><a target=_blank href="https://www.owasp.org/index.php/HttpOnly" style="margin: 0px; padding: 0px; color: rgb(26, 100, 162); text-decoration: none; ">https://www.owasp.org/index.php/HttpOnly</a></li></ul>
Cookie安全漫谈
最新推荐文章于 2018-11-27 11:02:02 发布