白帽子讲Web安全(纪念版)
只是笔记,详情请查阅吴翰清老师的《白帽子讲Web安全》
前言
安全工程师的核心竞争力不在于他能拥有多少个0day,掌握多少中安全技术,而是在于他对安全理解的深度,以及由此引申的看待安全问题的角度和高度。
在此书中最可贵的不是那一个个工业化的解决方案,而是在解决这些问题时,背后的思考过程。我们不是要做一个能解决问题的方案,而是要做一个能够“漂亮的”解决问题的方案这是每一名优秀的安全工程师应有的追求。
第一篇 世界观安全
安全问题的本质是信任问题
因为信任关系被破坏,从而产生了安全问题。我们可以通过信任域的划分、信任边界的确定,来发现问题是在何处产生的。
安全三要素
安全三要素是安全的基本组成元素,分别是机密性(Confidentiality)、完整性(Integrity)、可用性(Availability)。
机密性要求保护数据内容不能泄漏,加密是实现机密性的常见手段。
我们在选择方案时,需要灵活变通,因地制宜,没有一成不变的方案。
完整性则要求保护数据内容是完整的、没有被篡改的。常见的保证一致性的技术手段是数字签名。
可用性要求保护资源是“随需而得”。
拒绝服务攻击破坏的是安全的可用性。
如何实施安全评估
资产等级划分
互联网安全的核心问题,是数据的安全问题。
在安全领域里,我们把可能造成危害的来源称为威胁(Threat),而把可能会出现的损失称为风险(Risk)。
威胁分析
威胁分析就是把所有的威胁都找出来。
STRIDE是6个单词的首字母缩写,我们在分析威胁时,可以从以下6个方面去考虑。
在进行威胁分析时,要尽可能地不遗漏威胁,头脑风暴的过程可以确定攻击面。
风险分析
风险由以下因素组成:
R i s k = P r o b a b i l i t y ∗ D a m a g e P o t e n t i a l Risk = Probability * Damage Potential Risk=Probability∗DamagePotential
影响风险高低的因素,除了造成损失的大小外,还需要考虑到发生的可能性。
DREAD也是几个单词的首字母缩写,它指导我们应该从哪些方面去判断一个威胁的风险程度。
风险高低定义如下:
高危:12~15 中危:8~11 低危:0~7
设计安全方案
安全评估的产出物,就是安全解决方案。
没有不安全的业务,只有不安全的实现方式。
一个优秀的安全方案应该具备以下特点:
- 能有效解决问题;
- 用户体验好;
- 高性能;
- 低耦合;
- 易于扩展和升级。
白帽子兵法
Secure By Default原则
在设计安全方案时,最基本最重要的原则就是“Secure By Default”。实际上,“Secure By Default”原则也可以归纳为白名单、黑名单思想。
最小权限原则
Secure By Default的另一层含义就是“最小权限原则”。最小权限原则也是安全设计的基本原则之一。最小权限原则要求系统只授予主体必要的权限,而不要过度授权,这样能有效减少系统、网络、应用、数据库出错的机会。
纵深防御(Defense in Depth)原则
纵深防御包含两层含义:首先,要在各不同层面、不同方面实施安全方案,避免出现疏漏,不同方案之间需要互相配合,构成一个整体;其次,要在正确的地方做正确的事情,即:在解决根本问题的地方实施针对性的安全方案。
在常见的入侵案例中,大多数是利用Web应用漏洞,攻击者先获得一个低权限的webshell,然后通过低权限的webshell上传更多的文件,并尝试执行更高权限的系统命令,尝试在服务器上提升权限为root;接下来攻击者再进一步尝试渗透内网,比如数据库服务器所在网段。
就入侵的防御来说,我们需要考虑的可能有Web应用安全、OS系统安全、数据库安全、网络环境安全等。这些不同层面的安全方案,将共同组成整个防御体系,这也就是纵深防御的思想。
数据与代码分离原则
这一原则广泛适用于“注入”而引发的安全问题场景。
不可预测性原则
Secure By Default,是时刻要牢记的总则;纵深防御,是要更全面、更正确的看待问题;数据与代码分离,是从漏洞成因上看问题;不可预见性,是从克服攻击方法的角度看问题。
不可预测性,能有效的对抗基于篡改、伪造的攻击。
不可预见性的实现往往需要用到加密算法。
第二篇 客户端脚本安全
第2章 浏览器安全
2.1同源策略
同源策略(Same Origin Policy)是一种约定,它是浏览器最核心也是最基本的安全功能。可以说web是构建在同源策略的基础之上的,浏览器只是针对同源策略的一种实现。
浏览器的同源策略,限制了来自不同源的“document”或脚本,对当前“document”读取或设置某些属性。
对于当前页面来说,页面内存放的JavaScript文件的域并不重要,重要的是加载JavaScript页面所在的域是什么。
在浏览器中,<script>
、<img>
、<iframe>
、<link>
等标签都可以跨域加载资源,而不受同源策略的限制。这些带“src”属性的标签每次加载时,实际上是由浏览器发起了一次GET请求。不同于XMLHttpRequest的是,通过src属性加载的资源,浏览器限制了JavaScript的权限,使其不能读写返回的内容。
如果XMLHttpRequest能够跨域访问资源,则可能会导致一些敏感数据泄露,比如CSRF的Token,从而导致发生安全问题。
2.2浏览器沙箱
Sandbox即沙箱,计算机技术发展到今天,Sandbox已经成为泛指“资源隔离类模块”的代名词。Sandbox的设计目的一般是为了让不可信任的代码运行在一定的环境中,限制不可信任的代码访问隔离区之外的资源。如果一定要跨越Sandbox边界产生数据交换,则只能通过指定的数据通道,比如经过封装的API来完成,在这些API中会严格检查请求的合法性。
2.3恶意网址拦截
恶意网址拦截的原理很简单,一般都是浏览器周期性的从服务器端获取一份最新的恶意网址名单,如果用户上网时访问的网址存在于此黑名单中,浏览器就会弹出一个警告页面。
常见的恶意网址分为两类:一类是挂马网站,这些网站通常包含有恶意的脚本如JavaScript或flash,通过利用浏览器的漏洞(包括一些插件、控件漏洞)执行shellcode,在用户电脑中植入木马;另一类是钓鱼网站,通过模仿知名网站的相似页面来欺骗用户。
除了恶意网址黑名单拦截功能外,主流浏览器都开始支持EV SSL证书(Extended Validation SSL Certificate),以增强对安全网站的识别。
EVSSL证书是全球数字证书颁发机构与浏览器厂商一起打造的增强型证书,其主要特色是浏览器会给予EVSSL证书特殊待遇。
第3章 跨站脚本攻击(XSS)
终极武器:XSS Worm
XSS Worm是XSS的一种终极利用方式,它的破坏力和影响力是巨大的。但是发起XSS Worm攻击也有一定的条件。
一般来说,用户之间发生交互行为的页面,如果存在存储型XSS,则比较容易发起XSS Worm攻击。
比如,发送站内信、用户留言等页面,都是XSS Worm的高发区,需要重点关注。而相对的,如果一个页面只能由用户个人查看,比如“用户个人资料设置”页面,因为缺乏用户之间互动的功能,所以即使存在XSS,也不能被用于XSS Worm的传播。
XSS构造技巧
-
利用字符编码
-
绕过长度限制
最好的办法是把XSSPayload写到别处,再通过简短的代码加载这段XSS Payload。需要特别注意的是,在有的技术文档中,提到
<base>
标签只能用于<head>
标签之内,其实这是不对的。<base>
标签可以出现在页面的任何地方,并作用于位于该标签之后的所有标签。所以在设计XSS安全方案时,一定要过滤掉这个非常危险的标签。 -
Anehta的回旋镖
回旋镖的思路就是:如果在B域上存在一个反射型“XSS_B”,在A域上存在一个存储型“XSS_A”,当用户访问A域上的“XSS_A”时,同时嵌入B域上的“XSS_B”,则可以达到在A域的XSS攻击B域用户的目的。
对于浏览器来说,htmlparser会优先于JavaScript Parser执行
第四章 跨站点请求伪造(CSRF)
浏览器所持有的Cookie分为两种:一种是“Session Cookie”,又称“临时Cookie”;另一种是“Third-party Cookie”,也称为“本地Cookie”。
两者的区别在于,Third-party Cookie是服务器在Set-Cookie时指定了Expire时间,只有到了Expire时间后Cookie才会失效,所以这种Cookie会保存在本地;而Session Cookie则没有指定Expire时间,所以浏览器关闭后,Session Cookie就失效了。
如果浏览器从一个域的页面中,要加载另一个域的资源,由于安全原因,某些浏览器会阻止Third-party Cookie的发送。
P3P头的副作用
如果网站返回给浏览器的HTTP头中包含有P3P头,则在某种程度上来说,将允许浏览器发送第三方Cookie。在IE下即使是<iframe>
、<script>
等标签也将不再拦截第三方Cookie的发送。
在网站的业务中,P3P头主要用于类似广告等需要跨域访问的页面。但是很遗憾的是,P3P头设置后,对于Cookie的影响将扩大到整个域中的所有页面,因为Cookie是以域和path为单位的,这并不符合“最小权限”原则。
CSRF的防御
验证码被认为是对抗CSRF攻击最简洁而有效的防御方法。
Referer Check在互联网中最常见的应用就是“防止图片盗链”。同理,Referer Check也可以被用于检查请求是否来自合法的“源”。
CSRF为什么能够攻击成功?其本质原因是重要操作的所有参数都是可以被攻击者猜测到的。
出于这个原因,可以想到一个解决方案:把参数加密,或者使用一些随机数,从而让攻击者无法猜测到参数值。这是“不可预测性原则”的一种应用。
Token使用的原则
防御CSRF的Token,是根据“不可预测性原则”设计的方案,所以Token的生成一定要足够随机,需要使用安全的随机数生成器生成Token。
CSRF的Token仅仅用于对抗CSRF攻击,当网站还同时存在XSS漏洞时,这个方案就会变得无效,因为XSS可以模拟客户端浏览器执行任意操作。在XSS攻击下,攻击者完全可以请求页面后,读出页面内容里的Token值,然后再构造出一个合法的请求。这个过程可以称之为XSRF,和CSRF以示区分。XSS带来的问题,应该使用XSS的防御方案予以解决,否则CSRF的Token防御就是空中楼阁。安全防御的体系