zoukankan      html  css  js  c++  java
  • 跨站点请求伪造(CSRF)

    CSRF即Cross Site Request Forgery(跨站点请求伪造)。

    用户在客户端(浏览器)上任何一个操作如提交表单、点击超链接、或者是页面资源的显示都是向服务器发起请求

    而得以实现的,所以攻击者往往都是可以通过模拟真实用户的请求来“代替”用户完成操作的。

    例如A用户删除id为18的文章的请求地址为:www.eco.com/delete?id=18

    那么攻击者可以构造一个html页面,页面中有这样一段代码:

    ***
    <img src="http://www.eco.com/delete?id=18"  />
    ***

    (当然,用户会看到一张无法显示的图片)

    然后引导A用户去访问攻击者的这个html页面,A用户看到了这样一张无法显示的图片,然后回到自己的博客,一看,

    自己的id为18的文章不翼而飞了,这,就是跨站点请求伪造。当然了,CSRF肯定不会这么轻易就能成功的,因为大多

    数web项目都会对http请求设置一个过滤器,用来验证发出请求的用户身份,使得CSRF的实施变得麻烦起来。

    1.浏览器的cookie策略

    我应该不止一次地说过,用户注册之后,会设置一个cookie(token)返回给客户端(浏览器),用于之后请求的身份

    验证。

    浏览器所持有的cookie分为两种,一种是“Session Cookie”、一种是“Third-party Cookie”也称为本地cookie,两者的

    区别在于“Third-party Cookie”是服务器在Set-Cookie的时候指定了Expire时间(过期时间),到了过期时间,该cookie

    失效;而“Session Cookie”没有指定过期时间,所以浏览器关闭之后就失效了。

    Session Cookie保存在浏览器进程的内存空间中,Third-party Cookie保存在本地(下面分别是session-cookie和

    Third-party Cookie)。

    <?php
    header("Set-Cookie:cookie1=test1");
    header("Set-Cookie:cookie2=test2;expire=Thu,01-Jan-2030 00:00:01 GMT;",false);
    ?>

    假设A域a页面从服务端拿到了返回的如上两种Cookie,那么此时我们打开另一个A域的b页面,你会在b页面任意一个请求

    的cookie看看到上述两种cookie,具体怎么看请求的cookie,下面附上博客园的一个请求案例:

    正如你所看到的那样,这个请求自动携带了cookie。

    接下来我们访问B域的a页面(浏览器不要关闭),而B域a页面中的一个图片标签又访问了A域;

    ***
    <img src="http://www.a.com/delete?id=18"  />
    ***

    你会发现,在该条请求的cookie里面你只能看到携带的A域的Session Cookie;

    本地cookie是拿不到的,这是因为,有的浏览器出于安全考虑(IE),默认禁止在<img>、<iframe>、<script>等

    标签中发送第三方Cookie(浏览器本地cookie)。而有的浏览器默认策略是允许发送第三方cookie。

    下面是亲测案例:

    用chrome登录某网站,控制台 document.cookie 拿到cookie;

    然后用火狐同样登录该网站,但是没有登录,打开控制台,输入以上cookie(请忽略中间的拼写错误TT)

    然后刷新火狐下的该网站,你会发现,当前状态变为登录,并且会员信息为cookie对应的会员信息。

    2.P3P的介入

    P3P头是W3C制定的一项关于隐私的标准,如果网站返回给浏览器的头中包含有P3P头,则在某种程度上说

    将允许浏览器发送第三方cookie(本地cookie),在IE下即使是<iframe>、<script>等标签页不再拦截第三方cookie

    的发送。

    在网站的主要业务中,P3P头主要用于类似广告等需要跨域访问的页面,但很遗憾的是,设置了P3P之后,对于Cookie

    的影响将扩大到整个域中的所有页面。

    (以下内容是我思索再三根据自己的理解总结的,刚开始看的时候想不明白)

    我们通常都是在A域下页面访问A域服务器的Set-cookie接口,但是换一种方式去B域下页面访问A域的Set-cookie接口呢?

    请看图:

    由此看来,通过src属性set-cookie是有跨域限制的(IE),这和浏览器限制javascript权限,对script跨域请求的资源不

    能实现读写应该是一个道理。

    对于以上的情况,加入了P3P头之后,情况就不同了,P3P允许跨域访问隐私数据,从而可以实现跨域Set-Cookie

    以及发送第三方cookie。

    以下是P3P头:

    <?php
    header("P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"");
    header("Set-Cookie:cookie1=test1");
    header("Set-Cookie:cookie2=test2;expire=Thu,01-Jan-2030 00:00:01 GMT;",false);
    ?>

    3.CSRF的防御

    3.1验证码

    验证码强制用户与应用进行交互,才能完成最终请求,但是网站不可能对所有操作都加上验证码,因此验证码只能作

    为防御CSRF的一种手段,而不能作为主要的解决方案。

    3.2Referer Check

    正常页面http请求的referer头必然是当前页面所在的域,如果不是的话极有可能是CSRF攻击,我们可以通过Referer

    Check来判断用户是否被CSRF攻击。但是,服务器并不是什么时候都能获取到referer:

    用时候用户出于安全的考虑,限制referer的发送;

    某些情况下,出于安全考虑,浏览器也不会发送referer,比如HTTPS转HTTP;

    在Flash的一些版本中,曾经可以发送自定义referer,新版本不在允许发送自定义referer头。

    所以,还是无法依赖Referer Check作为CSRF攻击的主要手段,但是可以用来监控CSRF攻击的发生。

    3.3Token

    CSRF攻击之所以能够成功,是因为攻击者能够猜测操作所需要的所有参数,于是对于所有的请求新增一个参数Token

    这个Token要足够随机,必须使用足够安全的随机数生成算法,Token应该作为一个秘密,为用户和服务器共同持有,

    不能让第三方知晓。实际应用中Token存于Session或者本地Cookie。

    Token需要同时存放在提交的表单(hidden)和Session中,服务器验证用户提交的表单Token和Session中的Token是否

    一致,如果一致则请求合法,否则不合法,可能是CSRF攻击。

    Token使用的注意事项:

    如果用户提交了表单,则Token应该视为已消耗,应当再次生成一个新的Token到session中;

    Token如果放在url中,当前页面若嵌入了一个攻击者服务器的请求,则包含Token的url可能会被当做referer发送到攻击者

    的服务器,所以应当尽量把Token放在表单中,把GET改为POST;

    另外,如果攻击者通过XSS获取到了Token那么CSRF的Token防御也就变得毫无意义了,所以安全防御体系是相辅相成,

    缺一不可的。

    4.ClickJacking

    (由于点击劫持不难理解,而且感觉需要总结的不多,故不另开,就在此篇结尾一带而过吧)

    点击劫持是一种视觉上的欺骗,攻击者用一个透明的iframe覆盖在网页上,然后诱使用户进行操作,此时,用户在不知情

    的情况下点击了透明的iframe。可以通过调整iframe的位置迫使用户正好点击在iframe页面的一些特定功能上。

    下面用隐藏的div来模拟iframe做个示范:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <div style="200px;height:200px;border:1px solid;">用户可以看到的</div>
        <div style="position:absolute;top:10px;opacity:0;background:pink;200px;height:100px;" onclick="javascript:alert('hello');"></div>
    </body>
    </html>

    用户看到的界面是这样的:

    当用户点击没有绑定事件的第一个div后,触发了隐藏在相同位置上的div的单击事件:

    攻击者可以利用点击劫持来让用户做一些始料未及的事情。

    与此类似的还有XSIO(图片覆盖攻击)、拖拽劫持、触屏劫持。

    5.ClickJacking防御

    针对传统的ClickJacking可以通过禁止跨域的Iframe来防范,这种方法叫做 frame busting;

    if(top.location !=location){
      top.location = self.location;
    }

    更多相关知识请自行百度。

  • 相关阅读:
    前后端渲染
    与你一起的日子
    Python 字符串转化成整形数组
    Python列出文件和目录
    Eclipse 导入Gson包
    java.lang.NoClassDefFoundError (Eclipse)
    成功的背后!(给所有IT人)
    事件与概率
    Servlet获取form表单上传文件及其他参数
    Servelt学习笔记之二——使用Servlet提取表单中的数据
  • 原文地址:https://www.cnblogs.com/eco-just/p/9498291.html
Copyright © 2011-2022 走看看