了解CSRF和XSS
浏览器的同源策略限制了一些跨域行为,但仍有些特例(img、iframe、script标签)不受跨域限制,这就给XSS攻击创造了机会(这完全不是同源策略的锅,一定是程序员的锅)。
在讲下面的内容前,还是要提一下Cookie,Cookie是用来辨别用户身份的重要依据。来做个形象的比喻,有一天,小A去了一家新开的理发店,店里的托尼老师不认识小A,于是小A就办了一张VIP卡,当小A第二次去这家理发店的时候,店里的托尼老师刷了下小A的卡,想起来了你是小A啊,今天搞什么样的造型啊~ Cookie就是那张VIP卡,用于辨别用户身份。
Cookie包含以下几个属性
采用 Name = Value 的键值对形式存储数据,Name是唯一的
Domain:域名,限制哪些域名下可以使用(该VIP卡仅限本店使用)
Path:路径,只有这个路径前缀的才可用(该VIP卡仅限烫头)
Expires:过期时间(该VIP卡有效期一年)
HTTP(HTTPOnly):只有浏览器请求时,才会在请求头中带着,JavaScript无法读写
Secure:非HTTPS请求时不带
SameSite:用于定义cookie如何跨域发送
Cookie就先简单说到这里,回到XSS攻击,后续讲到的XSS和CSRF攻击都会围绕着怎么获取Cookie来举例。
XSS(Cross-site-Script跨站脚本攻击),通常是带有页面可解析内容的数据未经处理直接插入到页面上解析造成的。XSS根据攻击脚本的引入位置来区分为存储型XSS、反射型XSS以及MXSS(也叫DOM XSS)三种。
根据上面的描述来举个例子:
假设有一个论坛存在XSS漏洞,用户小A在该论坛的一篇帖子中留言到
当小A写的留言被该论坛保存下来之后,如果有其他的用户看到了这条评论(相当于打开了这个页面,执行了hark.js,hark.js里面内容大致是获取Cookie,发送请求),那么这些用户的Cookie都会发送到小A事先写好的信息收集网站中进行保存,然后小A就可以用这些Cookie进行登录啦。
上述这种XSS攻击属于存储型,提交的代码会被存储在服务器端,下次请求目标网站时不用再提交XSS代码。所以这种类型的主要原因是前端提交的数据未经处理直接存储到数据库,然后从数据库中读取出来后直接插入到页面中导致的。
继续讲故事:
假设有一个网站lalala存在XSS漏洞,网址是http://www.lalala.com。然后有一天小A在邮件里发现一封邮件,内容是一张你懂得图片然后配下面的标签。
小A好奇啊,然后就点了进去,如果在此之前小A登录过lalala网站,那么他的Cookie就被盗走了。
这种XSS攻击属于反射型,发出请求时,XSS代码出现在URL中,作为输入提交到服务器,服务器解析后响应,XSS代码随着响应内容一起传回给浏览器,最后浏览器解析执行XSS代码。这个过程像一次反射,故叫做反射型XSS。
MXSS则是在渲染DOM属性时将攻击脚本插入DOM属性中被解析而导致的。
至此,三种类型的XSS攻击都描述完了,你看确实都是程序员的锅吧。
服务端可以做以下动作:
1、刚刚上面讲到Cookie中有个属性时HTTP,设置为True,不允许JavaScript读取cookies,但该属性只适配部分浏览器。对于HTTPS可以设置Secure
2、处理富文本框输入内容,进行XSS过滤,过滤类似script、iframe、form等标签以及转义存储
客户端可以做以下动作:
1、输入检查,和服务端一样都要做。
2、输出检查,编码转义,如果使用jquery,就是那些append、html、before、after等,插入DOM的方法需要注意。现今大部分的MV*框架在模板(view层)会自动处理XSS问题。
XSS攻击的危害是很大的,像上面的例子注入script可以执行任何的JS代码(意味着可以获取cookie等信息了),注入style可以把页面全部弄崩。尤其是具有评论功能的网站需要注意防范此类攻击,不要相信客户端发送过来的任何数据!还有就是不要乱点开奇奇怪怪的链接啦~
什么是CSRF?
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装成受信任用户的请求来利用受信任的网站。
CSRF攻击的本质原因:
CSRF攻击是源于Web的隐式身份验证机制!Web的身份验证机制大致就是说为了防止用户每次发送请求的时候都需要登录,在进行一次登录验证通过后,之后发向该域名的请求都会自动带上cookie。虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的。CSRF攻击的一般是由服务端解决,而XSS主要是由客户端解决。
CSRF攻击的原理:
1. 用户打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A。
2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器。
3. 用户在未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B。
4. 网站B接收到用户请求后,发出一个访问网站A的请求。
5. 浏览器根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户的Cookie信息处理该请求,达到模拟用户操作的目的。
tips:Session Cookie(在浏览器关闭后,就会失效,保存到内存)
Third-party Cookie(关闭浏览器后,不会失效,保存到本地)
常见的CSRF攻击:
Get请求,操作数据库内容
比如网站A的修改密码接口是GET方式,通过调用api/ChangePassword?psw=123就可以进行密码的修改,所以在开发的过程中如果涉及到数据改动都建议采用POST请求
隐藏表单提交POST请求
单纯的POST当然也是能伪造的,JS利用form表单可以跨域请求的特性的提交POST请求仍然能够产生CSRF攻击。
如果网站A有使用Flash,并将跨域策略文件中的allow-access-from domain设置为素有,也是有可能产生CSRF攻击的。
XSRF
通常来说CSRF是由XSS实现的,所以CSRF时常也被称为XSRF,用XSS的方式实现伪造请求,比如网站A存在XSS漏洞,被注入恶意代码后,当有用户访问到有恶意代码的网页的时候,就会发送一条类似转账,关注啊之类的请求,做到XSRF攻击。
看完这几种攻击方式,大概应该能辨别什么时候是CSRF攻击了,简单说就是只要发起了冒牌请求那么就算是CSRF(XSRF)
顺便再总结下XSS和CSRF的其他区别,面试官可能会问到哦~
区别一,发生位置
XSS:发生在客户端
CSRF:发生在服务端
区别二,原理
XSS:注入代码,执行代码,篡改内容
CSRF:携带Cookie模拟请求
区别三,根源
XSS:同源策略机制
CSRF:Web隐式身份验证机制
区别四,就Cookie而言
XSS:盗取Cookie来干坏事
CSRF:借用Cookie来干坏事
最后还是要说下如何防范CSRF攻击
一、Referer(记录 HTTP 请求的来源地址) Check
好处是只需要增加一个拦截器来检查 Referer ,用于过滤非该服务器域名的地址,不需要改变当前系统的任何已有代码和逻辑,非常快捷。
但是,Referer 的值是由浏览器提供的,虽然 HTTP 协议上有明确的要求,但是每个浏览器对于 Referer 的具体实现可能有差别,并不能保证浏览器自身没有安全漏洞。使用验证 Referer 值的方法,就是把安全性都依赖于第三方(即浏览器)来保障,不是很靠谱,并且一些低版本的浏览器像IE6等有方法对Referer 进行篡改。还有重要的一点是,用户可以设置浏览器不携带 Referer字段。
二、验证码
强制用户必须与应用进行交互,才能完成最终请求。在通常情况下,验证码能很好遏制CSRF攻击。但是出于用户体验考虑,网站不能给所有的操作都加上验证码。因此验证码只能作为一种辅助手段,不能作为主要解决方案。
三、Token
在 HTTP 请求中以参数的形式添加一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,假设请求中没有 token 或者 token 内容不对,则觉得可能是 CSRF 攻击而拒绝该请求。并且涉及数据库操作的接口使用POST,因为GET不好加Token,会暴露Token的保密性。
关于Token
Token 应该保存到 local / session stograge(不会跨域工作) 或者 cookies
Tokens 除了像 cookie 一样有有效期,还要提供过期重新获取、强制刷新、撤回等操作
有需要的话,要加密并且签名 token
将 JSON Web Tokens(JWT) 应用到 OAuth 2
四、HTTP 头中自定义属性并验证
类似方法三,只不过不是以参数形式,而是请求头字段携带Token信息。但是要把所有请求都改为 XMLHttpRequest 请求。
至此,有关XSS和CSRF的内容都讲解完毕了,感谢大家抽空阅读。