概念解析CSRF,CrossSiteRequestForgery,跨站请求伪造。为什么跨站请求需要伪造?因为浏览器实现了同源策略,所以这里的网站和源可以看作是同一个概念。同源策略同源策略限制从一个源加载的文档或脚本如何与另一个源的资源交互。它是隔离潜在恶意文档的关键安全机制。——MDN来源是什么?JavaScript可以通过document.origin查看当前文档的来源,但不能改变来源;来源由协议(https)、域名(segmentfault)和端口(默认为80)组成;所谓同源就是协议、域名、端口都一样。从一个源加载的文档或脚本与另一个源的资源交互,可以理解为从当前源(网站)加载的文档或脚本发送请求到另一个源(网站)(请求的URL包含另一个来源)。浏览器对此行为进行了限制。如何限制,实验中分别在segmentfault和baidu发送xhr请求,请求一个segmentfault文档,其url为https://segmentfault.com/a/11...,相关截图如下,发送后在segmentfaultConsole中请求,Network中的Headers和Response显示如下。这里需要注意几点。控制台不报错,请求包含cookie,响应成功,返回文档可见。在百度控制台发送请求后,Network中的Headers和Response显示如下。首先,控制台报错,No'Access-Control-Allow-Origin'headerispresentontherequestedresource。来源'https://www.baidu.因此不允许访问com'。其次,请求不包含cookie,虽然响应成功,但是返回的内容是看不到的。综上所述,通过ResponseHeaders,我们可以判断请求已经发送到segmentfault并进行了处理,segmentfault也给了我们请求的文档。那么所谓的限制呢?首先,在百度文档中,通过JavaScript发送给segmentfault的请求没有携带segmentfaultcookie;第二,segmentfault其实已经返回了内容,但是浏览器不让我们看到,不允许访问。想一想同源策略限制了从一个源加载的文档或脚本如何与另一个源的资源交互。它是隔离潜在恶意文档的关键安全机制。——MDN在这里使用限制,即仍然允许。比如一个网站可以引用其他网站的图片、脚本等,都是带有src属性的标签。如果通过baidu中img的src标签向https://segmentfault.com/a/11...发送请求会怎样?相比之前发送xhr,通过img标签发送请求会带上cookie!!!发出去了!!!虽然返回的结果还是看不到。那么坏处在哪里呢?举例CSRF攻击的应对措施CSRF攻击可以在受害者不知情的情况下,以受害者名义伪造请求,发送到被攻击站点,从而进行权限保护下的非授权操作。例如,受害人Bob在银行有一笔存款。通过向银行网站发送请求http://bank.example/withdraw?...Bob可以将1,000,000的存款转入bob2的帐户。通常,请求发送到网站后,服务器会先验证请求是否来自合法的session,session的用户Bob已经成功登录。HackerMallory自己在银行有一个账户,他知道上面的URL来转账。Mallory可以自己向银行发送请求:http://bank.example/withdraw?…。但是这个请求是来自Mallory,而不是Bob,他不能通过安全认证,所以这个请求是行不通的。这时,Mallory想到了使用CSRF攻击方法。他先自己建了一个网站,在网站中加入如下代码:src="http://bank.example/withdraw?...",引诱Bob访问他的网站。当Bob访问网站时,上面的url会从Bob的浏览器发送到银行,这个请求会连同Bob浏览器中的cookie一起发送到银行服务器。大多数时候,请求失败是因为他要求Bob的身份验证信息。但是,如果此时Bob刚好访问了他的银行,他的浏览器和银行网站之间的会话还没有过期,浏览器的cookie中包含Bob的身份验证信息。这时候悲剧发生了,url请求会被响应,钱会从Bob的账户转到Mallory的账户,而Bob当时并不知道。后来,鲍勃发现账户里的钱少了。就算是去银行查看日志,也只能发现确实是有自己的合法请求转账,没有任何被攻击的痕迹。马洛里可以拿到他的钱并逍遥法外。引用【浅谈CSRF攻击方式】(https://www.cnblogs.com/hyddd...防御方式并不是所有的请求都必须进行CSRF防御,很多读取数据的请求不需要CSRF防御,因为返回结果本质上是不可见的;操作数据的请求往往需要CSRF防御,比如修改账户信息,CSRF只是在发送请求时带上相应的cookie,但是这个cookie对于攻击者来说仍然是不可见的,无法操作,攻击者所拥有的只是这个看不见的、无法操作的cookie。所以防御的基本思路是在请求中加入额外的验证信息(token),不仅仅是通过cookies来验证请求,大致有以下几种方式:服务端验证HTTPReferrer字段对于每个请求,验证是否它的Referrer是同源在请求地址上加上一个token,并在服务器端验证。比如你喜欢segmentfault中的一篇文章,就会发送这样的请求。我推测segmentfault的防御机制是这样的。每当用户请求页面时,页面中将包含一个随机段落。Number(token),发送密钥请求时,会带上token作为请求的参数。CSRF攻击者获取不到token,服务器根据token判断请求是否正常。另外即使是同一个用户发送同一个请求,页面中的token还是会有所不同。亲测实验证明,token在一定时间内不会发生变化。可以说token是有有效期的。在请求头中添加一个自定义的token,比如在知乎点赞一篇文章结合Wiki中CSRFPrevention的介绍,在知乎中称为Cookie-to-headertoken。主要过程如下。服务器发送一个cookie,其中包含xsrf=fajflafjaajf21ejlkja,它的值是一个随机数(token)。客户端读取cookie并读取令牌。当客户端发送需要csrf防御的请求时,比如示例中的知乎Like,token会被设置为请求头的值。比如知乎例子中的X-Xsrftoken就是在request中加入的(csrf,xsrf是一个东西)。服务端会检查token是否匹配cookie的值,判断请求的合法性要实现这样的过程,要求cookie中的xsrf字段不设置为httpOnly其次,这样可以防止csrf,因为JavaScript在其他源中无法读取知乎源的cookie,只有知乎自己的源JavaScript可以读取自己的cookie。对应前面的例子,即使用户在没有退出A网站的情况下访问B网站,B网站也通过A网站的cookie向A网站发送请求,但是B网站无法读取A网站的cookie,请求中不能包含对应的请求头,或者请求头中的值不能匹配cookie,比如知乎的X-Xsrftoken。当网站A收到这样的请求时,就可以判断这是一个恶意请求。参考资料同源策略CSRF攻击应对方法简单说说CSRF攻击方法CSRF介绍以及什么是同源策略?-CSRF推荐文档inweb0x04WikiCross-SiteRequestForgery(CSRF))Cross-SiteRequestForgery(CSRF)PreventionCheatSheet_Prevention_Cheat_Sheet#Viewstate_.28ASP.NET.29)
