这些年,AngularJS、React 和 Vue.js 算是前端框架中比较热门的,相对于 jQuery 等框架,有一些不太一样的可能出现问题的点,当然都是集中在 XSS 上。

模板注入

类似后端模板注入,前端模板注入也是存在的,被分析最多的还是 AngularJS,详见 https://docs.angularjs.org/guide/security

首先是后端直接生成前端模板,比如 {{1+1}},然后 AngularJS 去解析和执行。

其次是前端部分表达式和表达式 parser 的参数可以被控制,比如 $watch(userContent, ...) $compile(userContent)

之前的 AngularJS 是有沙箱的,隔离了部分 runtime context,但是最新版本中去除了,因为多次的被绕过,而且并没有真正的提升安全性。

在其他框架中也是存在类似的问题的、

直接插入 HTML

MVVM框架一般不需要关心 dom 操作,但是有时候还必须手动的插入和控制一些 HTML,框架也是提供了相关的方法的。

这时候就应该认真检查用户输入的数据了。

我感觉 AngularJS 和 React 的函数名字设计的特别科学,你要知道 trust 那些 dangerous 的数据才可以,还比如 grpc 中,使用非 SSL 的时候,方法名是add_insecure_port

SSR

为了解决 SPA 页面的 SEO 问题的,主流框架也提供了 SSR 方案,但是 SSR 的时候就经常的忘记了转义和过滤,一个是说程序员的问题,使用了危险的函数,另外一个就是框架的漏洞了。

比如新版知乎页面使用了 SSR,会先把用户的问题输出到页面上,然后后续再执行 JS 做进一步的动作,然后估计是使用了dangerouslySetInnerHTML,导致用户问题中的 JS 被执行,导致了XSS。

img

Vue.js 在 SSR 的时候,默认会转义用户输入,但是在样式中忘记处理了,导致了 XSS。见下面的 demo

var Vue = require('vue')
var app = new Vue({
  data () {
    return {
        xss: '"><script>alert(1)</script>'
    }
  },
  render: function (h) {
    return h('a', {style: {color: this.xss}}, 'foo')
  }
})
var renderer = require('vue-server-renderer').createRenderer()
renderer.renderToString(app, function (error, html) {
  if (error) throw error
  console.log(html)
})