道高一尺魔高一丈的网站应用攻击与防御
攻击新浪微博的手段(2011年6月28日,许多微博用户发现自己“中毒”,自动关注了一个叫hellosamy的用户,并发布含有病毒的微博,粉丝点击后微博再度扩散,短时间内大量用户中招,数小时后新浪微博修复漏洞)被称作XSS攻击,他和SQL注入攻击构成网站应用攻击最主要的两种手段,全球大约70%的Web应用攻击都来自XSS攻击和SQL注入攻击。此外,常用的Web应用还包括CSRF、Session劫持等手段。
XSS攻击
XSS攻击即跨站点脚本攻击(Cross Site Script),指黑客通过篡改网页,注入恶意HTML脚本,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式。
常见的XSS攻击类型有两种,一种是反射型,攻击者诱使用户点击一个恶意脚本的链接,达到攻击的工地,如下图所示。上面提到的新浪微博攻击就是一种反射型XSS攻击。攻击者的微博折功有一个含有恶意脚本的URL(在实际应用中,该脚本在攻击者自己的服务器www.2kt.cn,URL中包含脚本的链接),用户点击该URL,脚本会自动关注攻击者的新浪微博ID,发布含有恶意脚本URL的微博,攻击就被扩散了。
这次攻击还只是一次恶作剧而已。现实中,攻击者可以采用XSS攻击,偷取用户 Cookie、密码等重要数据,进而伪造交易、盗取用户财产、窃取情报。
另外一种XSS攻击是持久性XSS攻击,黑客提交含有恶意脚本的请求,保存在被攻击的Web站点的数据库中,用户浏览网页时,恶意脚本被包含在正常页面中,达到攻击的目的,如下图所示,此种攻击经常使用在论坛、博客等Web应用中。
XSS攻击相对而言是一种“古老”的攻击手段,却又历久弥新,不断变化出新的攻击花样,许多以前认为不可能用来攻击的漏洞也逐渐被攻击者利用。因此XSS防攻击也是非常复杂的。主要手段有如下两种。
消毒
XSS攻击者一般都是通过在请求中嵌入恶意脚本达到攻击的目的,这些脚本是一般用户输入中不使用的,如果进行过滤和消毒处理,即对某些html危险字符转移,如“>”转义为“>”、“<”转义为“<”等,就可以防止大部分攻击。为了避免对不必要的内容错误转义,如“3<5”中的“<”需要进行文本匹配后在转义,如“<img src=”这样上下文中的“<”才转义。事实上,消毒几乎是所有网站最必备的XSS防攻击手段。
HttpOnly
最早由微软提出,即浏览器禁止页面JavaScript访问带有HttpOnly属性的Cookie。HttpOnly并不是直接对抗XSS攻击的,而是防止XSS攻击者窃取Cookie。对于存放敏感信息的Cookie,如用户认证信息等,可通过对该Cookie添加HttpOnly属性,避免被攻击脚本窃取。
注入攻击
注入攻击主要有两种形式,SQL注入攻击和OS注入攻击。SQL注入攻击的原理如下图所示。攻击者在HTTP请求中注入恶意SQL命令(drop table users),服务器用请求参数构造数据库SQL命令时,恶意SQL被一起构造,并在数据库中执行。
SQL注入攻击需要攻击者对数据库结构有所了解才能进行,攻击者获取数据库表结构信息的手段有如下几种。
开源
如果网站采用开源软件搭建,如用Discuz!搭建论坛网站,那么网站数据库结构就是公开的,攻击者可以直接获得。
错误回显
如果网站开启错误回显,即服务器内部500错误会显示到浏览器上。攻击者通过故意构造非法参数,使服务端异常信息输出到浏览器端,为攻击猜测数据表结构提供了便利。
盲注
网站关闭错误回显,攻击者根据页面变化情况判断SQL语句的执行情况,据此猜测数据库表结构,此种方式攻击难度较大。
防御SQl注入攻击首先要避免被攻击者猜测到表明等数据库表结构信息,此外还可以采用如下方式。
消毒
和防XSS攻击一样,请求参数消毒是一种比较简单粗暴又有效的手段。通过正则匹配,过滤请求数据中可能注入的SQL,如“drop table”、“\b(?:update\b.*?\bset|delete\b\W*?\bfrom)\b”等。
参数绑定
使用预编译手段,绑定参数是最好的防SQL注入方法。目前许多数据访问层框架,如IBatis,Hibernate等,都实现SQL预编译和参数绑定,攻击者的恶意SQL会被当作SQL的参数,而不是SQL命令被执行。
除了SQL注入,攻击者还根据具体应用,注入OS命令、编程语言代码等,利用程序漏洞,达到攻击目的。
CSRF攻击
CSRF(Cross Site Request Forgery,跨站点请求伪造),攻击者通过跨站请求,以合法用户的身份进行非法操作,如转账交易、发表评论等,如下图所示。CSRF的主要手法是利用跨站请求,在用户不知情的情况下,以用户的身份伪造请求。其核心是利用了浏览器Cookie或服务器Session策略,盗取用户身份。
相应地,CSRF的防御手段主要是识别请求者身份。主要有以下几种方法。
表单Token
CSRF是一个伪造用户请求的操作,所以需要构造用户请求的所有参数才可以。表单Token通过在请求参数中增加随机数的办法来阻止攻击者获得所有请求参数:在页面表单中增加一个随机数作为Token,每次响应野米艾尼的Token都不相同,从正常页面提交的请求会包含Token值,而伪造的请求无法获得该值,而伪造的请求无法获得该值,服务器检查请求参数中Token的值是否存在并且正确以确定请求提交者是否合法。
验证码
相对说来,验证码则更加简单有效,即请求提交时,需要用户输入验证码,以避免在用户不知情的情况下被攻击者伪造请求。但是输入验证码是一个糟糕的用户体验,所以请在必要时使用,如支付交易等关键页面。
Referer check
HTTP请求头的Referer域中记录着请求来源,可通过检查请求来源,验证其是否合法。很多网站使用这个功能实现图片防盗链(如果图片访问的页面来源不是来自自己网站的网页就拒绝)。
其他攻击和漏洞
除了上面提到的常见攻击,还有一些漏洞也常被黑客利用。
Error Code
也称作错误回显,许多Web服务器默认是打开异常信息输出的,即服务器端未处理的异常堆栈信息会直接输出到客户端浏览器,这种方式虽然对程序调试和错误报告有好处,但同时也给黑客造成可乘之机。通过故意制造非法输入,使系统运行时出错,获得异常信息,从而寻找系统漏洞进行攻击。防御手段也很简单,通过配置Web服务器参数,跳转500页面(HTTP响应码500表示服务器内部错误)到专门的错误页面即可,Web应用常用的MVC框架也有这个功能。
HTML注释
为调试程序方便或其他不恰当的原因,有时程序开发人员会在PHP、JSP等服务器页面程序中使用HTML注释语法进行程序注释,这些HTML注释就会显示在客户端浏览器,给黑客造成攻击便利。程序最终发布前需要进行代码review或自动扫描,避免HTML注释漏洞。
文件上传
一般网站都会有文件上传功能,设置头像、分享视频、上传附件等。如果上传的是可执行的程序,并通过该程序获得服务器端命令执行能力,那么攻击者几乎可以在服务器上为所欲为,并以此为跳板攻击集群环境的其他机器。最有效的防御手段是设置上传文件白名单,只允许上传可靠的文件类型。此外还可以修改文件名、使用专门的存储等手段,保护服务器免受上传文件攻击。
路径遍历
攻击者在请求的URL中使用相对路径,遍历系统未开放的目录和文件。防御方法主要是将JS、CSS等资源文件部署在独立服务器、使用独立域名,其他文件不使用静态URL访问,动态参数不包含文件路径信息。
Web应用防火墙
网站面临的安全问题复杂多样,各种攻击手段日新月异,新型漏洞不断被报告。如果有一款产品能够统一拦截请求,过滤恶意参数,自动消毒、添加Token,并且能够根据最新攻击和漏洞情报,不断升级对策,处理掉大多数令人头痛的网站攻击,就是一件很美妙的事了。
非常幸运,真的有这样的产品——ModSecurity。
ModSecurity使一个开源的Web应用防火墙,探测攻击并保护Web应用程序,既可以嵌入到Web应用服务器中,也可以作为一个独立的应用程序启动。ModSecurity最早只是Apache的一个模块,现在已经有Java、.NET多个版本,并支持Nginx。
ModSecurity采用处理逻辑与攻击规则集合分离的架构模式。处理逻辑(执行引擎)负责请求和响应的拦截过滤,规则加载执行等功能。而攻击规则集合则负责描述对具体攻击的规则定义、模式识别、防御策略等功能(可以通过文本方式进行描述)。处理逻辑比较稳定,规则集合需要不断针对漏洞进行升级,这是一种可扩展的架构设计,如下图所示。
除了开源的ModSecurity,还有一些商业产品也实现Web应用防火墙功能,如NEC的SiteShell。
网站安全漏洞扫描
和计算机安全漏洞扫描一样,网站也需要安全漏洞扫描。
网站安全漏洞扫描工具是根据内置规则,构造具有攻击性的URL请求,模拟黑客攻击行为,用以发现网站安全漏洞的工具。许多大型网站的安全团队都有自己开发的漏洞扫描工具,不定期的对网站的服务器进行扫描,查漏补缺。市场上也有很多商用的网站安全漏洞扫描平台。
信息加密技术及密钥安全管理
2011年12月被曝的CSDN密码泄露事故中,网站安全措施不力,导致用户数据库被黑客“拖库”并不稀奇,令人错愕的是数据库中的用户密码居然是铭文保存,导致密码泄露,成为地下黑市交易的商品。
通常,为了保护网站的敏感数据,应用需要对这些信息进行加密处理,信息加密技术可分为三类:单项散列加密、对称加密和非对称加密。
单向散列加密
单向散列加密是指通过不同输入长度的信息进行散列计算,得到固定长度的输出,这个散列计算过程是单向的,即不能对固定长度的输出进行计算从而获得输入信息,如下图所示。
利用单向散列加密的这个特性,可以进行密码加密保存,即用户注册时输入的密码不直接保存到数据库,而是对密码进行单向散列加密,将密文存入数据库,用户登录时,进行密码验证,同样计算得到输入密码的密文,并和数据库中的密文比较,如果一致,则密码验证成功,具体过程如下图所示。
这样保存在数据库中的是用户输入的密码的密文,而且不可逆的计算得到密码的铭文,因此即使数据库被“拖库”,也不会泄露用户的密码信息。
虽然不能通过算法将单向散列密文反算得到明文,但是由于人们设置密码具有一定的模式,因此通过彩虹表(人们常用密码和对应的密文关系表)等手段可以进行猜测式破解。
为了加强单向散列计算的安全性,还会给散列算法加点盐(salt),salt相当于加密的密钥,增加破解的难度。
常用的单向散列算法有MD5、SHA等。单向散列算法还有一个特点就是输入的任何微小变化都会导致输出的完全不同,这个特性有时也会被用来生成信息摘要、计算具有高离散程度的随机数等用途。
对称加密
所谓对称加密是指加密和解密使用的密钥是同一个密钥(或者可以互相推算),如下图所示。
对称加密通常用在信息需要安全交换或存储的场合,如Cookie加密、通信加密等。
对称加密的优点是算法简单,加解密效率高,系统开销小、适合对大量数据加密。缺点是加解密使用同一个密钥,远程通信的情况下如何安全的交换密钥是个难题,如果密钥丢失,那么所有的加密信息也就没有秘密可言了。
常用的对称加密算法有DES算法、RC算法等,对称加密是一种传统加密手段,也是最常用的加密手段,适用于绝大多数需要加密的场合。
非对称加密
不同于对称加密,非对称加密和解密使用的密钥不是同一密钥,其中一个对外界公开,被称作公钥,另一个只有所有者知道,被称作私钥。用公钥加密的信息必须用私钥才能解开,反之,用私钥加密的信息只有用公钥才能解开,如下图所示。理论上说,不可能通过公钥计算获得私钥。
非对称加密技术通常用在信息安全传输,数字签名等场合。
信息发送者A通过公开渠道获得信息接收者B的公钥,对提交信息进行加密,然后通过非安全传输通道将密文信息发送给B,B得到密文后,用自己的私钥对信息进行解密,获得原始的明文信息。即使密文信息在传输过程中遭到窃取,窃取者没有解密密钥也无法还原明文。
数字签名的过程则相反,签名者用自己的私钥对信息进行加密,然后发送给对方,接收方用签名者的公钥对信息进行解密,获得原始明文信息,由于私钥只有签名者拥有,因此该信息是不可抵赖的,具有签名的性质。
在实际应用中,常常会混合使用对称加密和非对称加密。先使用非对称加密技术对对称密钥进行安全传输,然后使用对称加密技术进行信息加解密与交换。而有时,对同一个数据两次使用非对称加密,可同时实现信息安全传输与数字签名的目的。
非对称加密的常用算法有RSA算法等。HTTPS传输中浏览器使用的数字证书实质上是经过权威机构认证的非对称加密的公钥。
密钥安全管理
前述的几种加密技术,能够达到安全保密效果的一个重要前提是密钥的安全。不管是单向散列加密用到的salt、对称加密的密钥、还是非对称加密的私钥,一旦这些密钥泄露出去,那么所有基于这些密钥加密的信息就失去了私密性。
信息的安全是靠密钥保证de.dan在实际中经常看到,有的工程师把密钥直接卸载源代码中,稍好一点的写在配置文件中,线上和开发环境配置不同的密钥。总之密钥本身是以明文的方式保存,并且很多人可以接触到,至少在公司内部,密钥不是秘密。
实践中,改善密钥安全性的手段有两种。
一种方案是把密钥和算法放在一个独立的服务器上,甚至做成一个专用的硬件设施,对外提供加密和解密服务,应用系统通过调用这个服务,实现数据的加解密。由于密钥和算法独立部署,由专人维护,使得密钥泄露的概率大大降低。但是这种方案成本较高,而且有可能会成为应用的瓶颈,每次加密、解密都需要进行一次远程服务调用,系统性能开销也较大。
另一种方案是将加解密算法放在应用系统中,密钥则放在独立服务器中,为了提高密钥的安全性,实际存储时,密钥被切分成数片,加密后分别保存在不同存储介质中,兼顾密钥安全性的同时又改善了性能,如下图所示。
应用程序调用密钥安全管理系统提供的加解密服务接口对信息进行加解密,该接口实现了常用的加密解密算法并可根据需求任意扩展。加解密服务接口通过密钥服务器的密钥服务取得加解密密钥,并缓存在本地(定时更新)。而密钥服务器中的密钥则来自多个密钥存储服务器,一个密钥分片后存储在多台服务器中,每个服务器都有专人负责管理。密钥申请者、密钥管理者、安全审核人员通过密钥管理控制台管理更新密钥,每个人各司其职,没有人能查看完整的密钥信息。