freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Vue.js下的跨站脚本攻击学习整理
2020-12-15 21:26:28

最近学习了vue.js环境下xss攻击场景相关的知识。整理出来分享给大家。

vue.js 下的数据绑定

常见的vue.js数据绑定是通过双大括号{{}}或者v-text指令进行的数据绑定的。vue.js会自动将对应的模版编译成js代码。

例如:模版代码为

<p v-text="message"></p>

vue.js会把这段模版代码编译成:

function anonymous() {
  with(this) {
    return _c('p', {
      domProps: {
        "textContent": _s(message)
      }
    }, [])
  }
}

一般情况下,vue.js通过双大括号向html内容中对指定部分进行插值。

而双大括号{{}}和v-text指令上底层上实现主要都是通过元素 DOM属性的textContent值来实现数据插入。

这种情况下一般不会出现注入的问题,因为浏览器的原生api会安全的处理这些值。 但是数据插值有时候需要向页面中插入富文本信息。如果使用{{}} 和 v-text指令的话,富文本会被转义成普通文本。不能实现需求。

这时候可能需要用到v-html标签。v-html标签的模版在vue.js编译的形式如下:

示例模版:

<p v-html="message"></p>

vue模版渲染代码:

function anonymous() {
  with(this) {
    return _c('p', {
      domProps: {
        "innerHTML": _s(message)
      }
    }, [])
  }
}

可以看的v-html标签底层实际上使用了 Dom元素的innerHTML属性进行数据插入。而 innerHTML属性在被插入不信任数据的时候就会导致JS注入的问题。

安全防御:日常vue.js中数据绑定应该尽量使用{{}}和v-text的方式。v-html是一个有风险的指令,使用时一定要对数据进行过滤处理。


vue.js 下的标签的属性绑定

标签属性绑定,其实也是数据绑定的一种。我把它独立出来是因为属性上的数据绑定和上一小街其实的区别还是很大。

web前端开发中除了数据内容填充,同时也需要对标签的属性进行数据绑定操作。

vue中我们使用v-bind 标签属性进行数据绑定,这些数据的插值也是通过浏览器原生api对数据进行转码插入。由于浏览器自身api安全的保障,数据插入一般不会造成闭合属性导致的xss问题。

示例模版:对a标签的href进行数据插入

<a v-bind:href="1234"></a>

vue.js编译后的代码:

function anonymous() {
  with(this) {
    return _c('a', {
      attrs: {
        "href": 1234
      }
    }, [])
  }
}

这种场景下,往往是开发人员安全意识缺失,在对标签属性进行数据绑定的时候,忽略对于某些标签的危险属性绑定时的特殊处理。

我们知道,特殊标签的某些属性,可以在属性值可控的情况下进行js代码注入。这样又回到了通用场景下 xss防护应该要注意的问题。

web危险属性大致有:

所有元素的style属性。(应避免用户输入数据绑定到标签的style属性中,防范钓鱼攻击。)

a 标签的 href 属性。(正常情况应保证url 协议是http 和 https)

iframe 标签的 src 属性。(要防止通过 javascript://  执行js)
object 标签的 data 属性 。(要防止通过 javascript://  执行js.)

form  的 action 属性(要防止通过 javascript://  执行js.)

防护知识:对于src 、href 、action 、 data 这类可以赋值为uri的属性要限制好协议和请求的url,尽量保证使用http:// 和 https:// 协议及访问可信的资源服务器 。

Vue.js 服务端模版渲染XSS

其实不仅仅是vue,在目前前后端分离开发的趋势下,前端Javascript框架如果使用了服务端模版渲染模版的方式,就都有可能出现服务端模版XSS。(这类XSS的本质是模版注入,并不一定出现都在服务端渲染场景)。

服务端渲染模版本身是为了提前生成html,利于某些站点的seo 和加快页面加载,如果对模版中用户数据处理不当,就会导致模版注入的问题。

举例:

如果你在vue.js开发的网站中输入了{{ 2+2 }},后端服务器给返回了4的时候。你可以断定这里存在模版解析的问题(服务端将用户输入直接放到template 中作为template的一部分解析返回)。

那么,如何攻击vue.js模版注入漏洞?

但在vue组件模版中,我们不能直接调用底层javascript函数。利用vue的模版注入一般使用的是javascript的prototype的特性。

首先我们知道,vue会把模版解析成js代码。那么对于模版注入漏洞,我们只需要将注入数据在解析结果里变成一段想要的js代码就可以了。

Javascript 中的一切内容都是对象。每个对象都包含一个protoptype (原型),prototype其中有个属性叫constructor ,它指向的是该对象构造函数。

函数也是一个对象,函数对象的constructor是一个允许动态生成函数的函数。这个constructor只要简单把代码字符串赋值给它就可以构造一个匿名的JS 函数。

举个例子:利用toString函数的构造函数,通过赋值构造一个匿名函数。

toString.constructor("consolo.log(1)")();


调用这个匿名函数:

Vue 的模版注入payload 原理就就是这样,常用的测试payload有:

{{constructor.constructor('alert(1)')()}}
{{_c.constructor('alert(1)')()}}
{{_v.constructor('alert(1)')()}}
{{_s.constructor('alert(1)')()}}

还有很多payload , 大家可以到参考资料中的xss-cheat-sheet中查找。

防护知识:对于模版注入,我们可以通过v-pre指令对模版中的用户输入进行处理v-pre 指令可以跳过指定点的模版编译。将起用在用户输入上可以防止用户输入造成的模版注入问题。


关于vue.js XSS 相关内容的分享就到这里。其他的攻击点就靠大家一起发掘啦。


参考文档:

http://www.mabiji.com/vuejs/vue-directive.html

https://template-explorer.vuejs.org/#

https://portswigger.net/web-security/cross-site-scripting/cheat-sheet#vuejs-reflected

https://portswigger.net/research/evading-defences-using-vuejs-script-gadgets


本文作者:天玑@涂鸦智能安全团队

漏洞悬赏计划:涂鸦智能安全响应中心(https://src.tuya.com)欢迎白帽子来探索。

招聘内推计划:涵盖安全开发、安全测试、代码审计、安全合规等所有方面的岗位,简历投递sec@tuya.com,请注明来源。

# xss # web安全 # 网络安全技术 # vue
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录