《第三方JavaScript编程》——7.3 跨站请求伪造[通俗易懂]

《第三方JavaScript编程》——7.3 跨站请求伪造

大家好,又见面了,我是全栈君。

本节书摘来自异步社区《第三方JavaScript编程》一书中的第7章,第7.3节,作者:[美] Ben Vinegar Anton Kovalyov著,更多章节内容可以访问云栖社区“异步社区”公众号查看

7.3 跨站请求伪造

在第4章中,我们谈到了同源策略。该策略被所有浏览器支持,并防止不同来源的Web页面互相访问对方的方法和属性。你已经学到了一些技巧,使用这些技巧可以向你的服务器跨域发送消息。在本节中,我们将介绍利用该特性是如何转而对你进行攻击的。

跨站请求伪造(CSRF或者XSRF)是针对用户的另一种类型的漏洞。与XSS不同,XSS是将伪造的内容展现给用户,而XSRF利用的是Web应用程序与用户浏览器之间的信任。在本质上,易受XSRF攻击的Web应用都允许攻击者通过自己的网站诱导用户执行某些操作。

在本节中,我们首先来看一些典型的XSRF攻击的例子,然后介绍这一漏洞的变种:JSON劫持。最后,我们讨论防御XSRF攻击的策略。

7.3.1 XSRF攻击
设想如下场景:你为发布者提供了一个添加内容版主的Web接口,内容版主可以编辑、删除通过他们网站中的微件提交的评论。该接口需要身份认证。在将其添加到现有版主列表之前,需要检查调用接口的用户是否通过身份验证并有操作的权限。对于这个例子而言,假设需要添加一个新的版主,用户需要提交(POST方式)一个含有用户名的表单。
screenshot
服务端处理该表单请求的代码,如下所示。
screenshot
从各方面来看,该服务端接口看起来似乎很安全。毕竟它对请求用户的会话和权限级别都做了验证,而且对POST参数中的用户名也做了验证。但很可惜,尽管我们做了这么多努力,这个接口还是很容易受到XSRF的攻击。要理解其中的原因,只需要看程序清单7.4,这是攻击者提供的恶意表单,会利用访问者的身份向moderators/add接口发送POST请求。

程序清单7.4 攻击者利用XSRF漏洞提交自己的用户名作为内容版主
screenshot
尽管这看起来像一个普通的Web页面,但网页上的脚本会自动生成并提交一个指向moderators/add接口的表单。换言之,只要用户访问这个页面,就会将攻击者的用户名作为参数向moderators/add提交一个POST请求。在浏览器看来,这就是向camerastork.com服务器发起的一个正常请求,因此会在请求中传输存储在camerastork.com域下的cookies,包括用户的会话cookie。服务端接收到包含cookie的请求后会检查会话并验证提供的用户名。一切看起来都很正常,因此服务端会将攻击者作为内容版主添加到你的账户中。攻击就这样悄无声息的成功完成了。

7.3.2 JSON劫持
刚刚你已经了解了XSRF漏洞的经典例子,但不幸的是,XSRF攻击有多种不同形式的变种。其中之一就是所谓的JSON劫持,常用来窃取用户的受保护信息。如果你还记得第4章中我们提到的JSONP,就应该还记得< script >标签并不受同源策略的限制,而且你曾利用这一点在微件中发送跨域HTTP请求。JSON劫持正是利用了SOP的这种例外情况,通过标准的< script >标签加载该接口,从而窃取JSON数据。

假如说Camera Stork微件允许用户对过去的购买记录进行评论,这种信息就被认为是隐私,用户并不希望将他们的购买历史公开给其他用户。微件中为了获取这部分数据,需要在服务端实现一个接口,通过JSON格式返回当前会话用户的购买历史。你就需要在一个Camera Stork域名下的iframe页面中使用XMIHttpRequest调用该接口获取数据。下面是接口响应的示例。
screenshot
假设攻击者想要使用XSRF漏洞来获取这些数据。正如你所知道的,如果攻击者可以利用用户(访问恶意Web页面的用户)的身份发送该接口请求,服务端便会读取该用户的会话并返回相应的购买记录。攻击者只需要能够访问响应的正文就大获全胜了。但是具体怎么做呢?同源策略会阻止使用XMLHttpRequest的方式进行请求,因为接口与攻击者的页面隶属不同的域。只剩下使用< script >标签的方式来请求接口了,但攻击者会遇到另外一个问题:他们无法捕获响应数据的正文,因为JSON输出并没有赋值给某个变量或者持久化。因此,看起来购买历史接口的安全性似乎是有充分保障的。

事实上并不一定。对于一些旧的浏览器,可以通过自定义Object原型的setter方法来捕获传递给它的任何值。也就使得捕获接口的JSON输出成为可能,比如捕获购买历史接口返回的输出结果,见程序清单7.5。

程序清单7.5 JSON劫持一个看起来安全的HTTP接口
screenshot
有了页面上的这段代码,攻击者只需要将不知情的访问者引诱到他们的网站,并使用< script >标签加载有漏洞的JSON接口。攻击者便可以将捕获到的变量内容发送到他们的服务器。这并不是一个假设的情况,这种方式曾经被用来提取一个访问者的Twitter追随者。

好消息是,在如今的一系列现代浏览器中该漏洞已经不复存在。然而,它并非浏览器JSON劫持的唯一切入点,可能也不是最后一个。

7.3.3 保护应用免受XSRF攻击
保护应用免受XSRF攻击的标准方式称之为XSRF令牌。一个XSRF令牌是一个不可预知的值,通常是一个同当前用户会话相关,但无法重用的随机生成的字符串。执行受保护操作的每个页面都包含这样的令牌。当用户提交一个操作时,表单或者JavaScript代码会将XSRF令牌作为请求的一部分一并提交,同时服务端会校验令牌的合法性。如果令牌丢失或者无效,整个请求会被拒绝。XSRF令牌应当与单个会话相关联,否则攻击者就可以使用通过他们自己会话生成的令牌。

图7.2展示了XSRF令牌发起和校验的过程。
screenshot
从本质上讲,当发出一个XSRF令牌时,就相当于为用户提供了一个对应操作的一次性唯一许可,而该操作通过独立的HTTP请求是禁止访问的。并且用户只有在访问包含对应操作的页面时才能获得该许可。因为攻击者无法访问该令牌,他们也就不能诱导用户发起这些需要令牌的资源请求。

XSRF令牌的有效性只取决于服务端同浏览器用户之间的交换。如果在发布者的页面代码中生成一个XSRF令牌,恶意页面就可以获取该令牌并像之前一样进行攻击。解决方案是:只在外部iframe(通过camerastork.com访问)的页面中提供XSRF令牌,这样父文档便无法访问到。这也就意味着,如果要使用该令牌,向你的服务器发起的任何请求都需要在iframe内进行(使用window.postMessage或者easyXDM)。

在JSON劫持的情况下,除了标准的XSRF保护方式之外,还可以在JSON响应的第一行添加一些有问题的JavaScript代码,这样攻击者就不可能通过< script >标签成功访问。例如,你可以在服务器JSON响应的第一行添加一个简单的无限循环,如下。
screenshot
如果攻击者通过< script >标签加载数据就无法绕过第一行,因为浏览器在执行该循环时会暂停响应。另一方面,你的微件可以通过XMLHttpRequest以纯文本的方式获取这些数据,然后丢弃掉第一行,再将响应转换为一个JavaScript对象即可。

大多数的Web开发框架(如Ruby on Rails和Python的Django)都有针对XSS和XSRF的内置策略。如果你正在使用某个Web框架,一定要先了解它的文档并熟悉这些工具。

本节介绍了一个可恶的漏洞:跨站请求伪造,作为一个第三方JavaScript开发者,这是一个要时刻考虑的问题。虽然我们所描述的防御机制并不复杂,但应该足以防御大多数XSRF漏洞。XSS和XSRF漏洞是Web应用中成功攻击的主要方式,对于第三方JavaScript应用更是如此,所以我们才花费时间来讨论它们。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/108526.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • kettle 性能优化_kettle过滤记录

    kettle 性能优化_kettle过滤记录性能调优在整个工程中是非常重要的,也是非常有必要的。但有的时候我们往往都不知道如何对性能进行调优。其实性能调优主要分两个方面:一方面是硬件调优,一方面是软件调优。本章主要是介绍Kettle的性能优化及效率提升。……

    2022年9月20日
    3
  • 面试JAVA常被问到的问题(持续更新中)

    面试JAVA常被问到的问题(持续更新中)引言有的面试会被问到有没有写博客,这时候我尴尬,不知道怎么回答,所以这篇文章仅仅是把我面试JAVA的遇到的问题记录下来而已,也算是我写博客迈出的第一步,起码,以后被问到:有没有写博客?我可以回答,我写过。 (最主要的是以后换工作我不用频繁百度常见面试题了。。。。)ps1,别把我太当回事,我是个LJ;2,说得不对的地方请多多包涵,想看更详细的请百度官方文档和其他大佬的文章;3,如果有被问到…

    2022年7月9日
    23
  • 字符指针赋值[通俗易懂]

    程序1:把两个相同的字符串赋值给两个不同的指针。比较两个指针
    #include
    intmain(void)
    {
    char*a;                          
    printf(“%p/n”,a);
    printf(“%d/n”,sizeof(a));//定义一个指针(一个字节),指针变量里面的值是随机的,所以这个指针也叫悬空指针。
    a=”hello”;                

    2022年4月16日
    57
  • Hook(钩子技术)基本知识讲解,原理

    一、什么是HOOK(钩子)      对于Windows系统,它是建立在事件驱动机制上的,说白了就是整个系统都是通过消息传递实现的。hook(钩子)是一种特殊的消息处理机制,它可以监视系统或者进程中的各种事件消息,截获发往目标窗口的消息并进行处理。所以说,我们可以在系统中自定义钩子,用来监视系统中特定事件的发生,完成特定功能,如屏幕取词,监视日志,截获键盘、鼠标输入等等。     钩子…

    2022年4月3日
    41
  • 传统php用单例模式的作用大吗,一次生命周期走完不是进程就结束了嘛?[通俗易懂]

    传统php用单例模式的作用大吗,一次生命周期走完不是进程就结束了嘛?

    2022年2月12日
    49
  • pycharm2021.11.3激活补丁_最新在线免费激活

    (pycharm2021.11.3激活补丁)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月30日
    70

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号