百科狗-知识改变命运!
--

安全 - vue 规模化

乐乐1年前 (2023-11-21)阅读数 23#技术干货
文章标签你的

安全

报告漏洞

如果有漏洞被报告,那么它将立刻成为我们最关心的问题,全职贡献者会放下一切来处理它。如需报告漏洞,请发送电子邮件至 security@vuejs.org。

虽然很少发现有新的漏洞,但我们也建议始终使用最新版本的 Vue 及其官方配套库,以确保你的应用尽可能地安全。

首要规则:永远不要使用不受信任的模板

使用 Vue 时最基本的安全规则是永远不要使用不受信任的内容作为组件模板。这样做相当于允许在你的应用程序中执行任意 JavaScript。更糟糕的是,如果在服务器端渲染时执行了这些代码,可能会导致服务器漏洞被恶意利用。例如:

Vue.createApp({
  template: `
` + userProvidedString + `
` // 永远不要这么做 }).mount('#app')

Vue 模板会被编译成 JavaScript,模板内的表达式将作为渲染过程的一部分执行。尽管表达式会针对特定的渲染场景进行评估,但由于潜在全局执行环境的复杂性,要求 Vue 这样的框架完全屏蔽潜在的恶意代码执行而不产生不切实际的性能开销非常不切实际。完全避免此类问题的最直接方法是确保 Vue 模板的内容始终受你信任并完全由你控制。


Vue 如何保护你

HTML 内容

无论是使用模板还是渲染函数,内容都会自动转义。因此在这个模板中:

{{ userProvidedString }}

如果userProvidedString包含:

''

安全 - vue 规模化

那么它将被转义为以下 HTML:

<script>alert("hi")</script>

从而防止脚本注入。这种转义是使用原生浏览器 API(例如textContent)完成的,因此只有当浏览器本身易受攻击时才会存在漏洞。

attribute 绑定

同样,动态 attribute 绑定也会自动转义。因此在这个模板中:

hello

如果userProvidedString包含:

'" onclick="alert(\'hi\')'

那么它将被转义为以下 HTML:

" onclick="alert('hi')

从而防止title attribute 被提前关闭以注入新的、任意的 HTML。这种转义是使用原生浏览器 API(例如setAttribute)完成的,因此只有当浏览器本身易受攻击时才会存在漏洞。

潜在的安全隐患

在任何 Web 应用程序中,允许以 HTML、CSS 或 JavaScript 形式执行未经处理的、用户提供的内容都有潜在的安全隐患,因此应尽可能避免。不过有些时候部分风险或许是可以接受的。

例如,CodePen 和 JSFiddle 之类的服务允许执行用户提供的内容,但这是在预期的上下文中,并且使用了 iframe 包裹来进行一定程度的沙盒处理。如果某个重要功能本质上需要某种程度的漏洞,则由你的团队根据漏洞导致的最坏情况来权衡该功能的重要性。

注入 HTML

正如你之前所看到的,Vue 会自动转义 HTML 内容,防止你意外地将可执行的 HTML 注入到你的应用程序中。但是,如果你确信某个 HTML 是安全的,你可以显式呈现 HTML 内容:

  • 使用模板:

  • 使用渲染函数:

    h('div', {
    innerHTML: this.userProvidedHtml
    })
    
  • 在 JSX 中使用渲染函数:

TIP

请注意,永远不要 100%信任用户提供的 HTML,除非它位于 iframe 沙盒中,或位于仅有编写该 HTML 的用户才能接触到它的部分中。此外,允许用户编写自己的 Vue 模板也会带来类似的危险。

注入 URL

在这样的 URL 中:

click me 

如果 URL 未经过“净化”处理来防止其通过javascript:执行 JavaScript,则会有潜在的安全隐患。有一些库例如 sanitize-url 可以帮助解决这个问题,但请注意:

TIP

如果你只在前端进行 URL 净化,那么你已经遇到了安全问题。在保存用户提供的 URL 到数据库之前,你的后端必须对其进行净化。只有这么做,才能避免每个连接到你 API 的客户端(包括原生移动应用程序)出现此类问题。另请注意,即便使用了经过净化的 URL,Vue 也无法保证它们指向安全的目标。

注入样式

考虑下列示例:

 click me 

我们假设它已经被sanitizedUrl净化过了,因此它确实是一个真实的 URL 而非 JavaScript。然而,恶意用户仍然可以利用userProvidedStyles,通过提供 CSS 来实现“点击劫持(click jack)”,例如将链接样式设置为“登录”按钮上方的透明框。假设https://user-controlled-website.com/是用来为你的应用程序提供类似于登录界面功能的,那么他们可能刚刚捕获了用户的真实登录信息。

你或许能想象到了允许用户为某个元素提供内容会产生多大的安全漏洞,因为这意味着用户拥有了整个页面样式的完整控制权。这也是为什么 Vue 会阻止在模板中渲染样式标签,比如:

{{ userProvidedStyles }}

为了让你的用户完全免受点击劫持,我们建议只允许用户完全控制 iframe 沙盒内的 CSS。或者,如果需要通过样式绑定来允许用户控制样式,我们建议使用它的对象语法,并且只允许用户为可以被安全控制的特定 property 提供值,如下所示:

 click me 

注入 JavaScript

我们强烈建议不要使用 Vue 渲染元素,因为这么做的话模板和渲染函数不会有副作用。不过,如果你想在运行时引入会被作为 JavaScript 处理的字符串,还有别的办法。

每个 HTML 元素都有能接受 JavaScript 字符串的 attribute,如onclickonfocusonmouseenter。你应当避免将用户提供的 JavaScript 绑定到任一事件 attribute,因为这会是一个潜在的安全隐患。

TIP

请注意,永远不要 100%信任用户提供的 JavaScript,除非它位于 iframe 沙盒中,或位于仅有编写该 HTML 的用户才能接触到它的部分中。

有时我们会收到有关如何在 Vue 模板中执行跨站点脚本(XSS)的漏洞报告。一般来说,我们不认为这种情况是真正的漏洞,因为在下列两种允许 XSS 情况中,我们没有切实可行的方法来保护开发者免受其影响:

  1. 开发者明确要求 Vue 将用户提供的、未经净化的内容作为 Vue 模板渲染。这根本就是不安全的,并且 Vue 无法知道这些内容的来源。
  2. 开发者正在将 Vue 挂载到整个 HTML 页面,而该页面恰好同时包含服务器渲染的和用户提供的内容。这与 1 的问题基本相同,但有时开发者可能会没有意识到这一点。这可能会导致出现潜在漏洞,攻击者也许会提供作为纯 HTML 安全但作为 Vue 模板不安全的 HTML 内容。

最佳实践

通常来说,如果你允许执行未经净化的、用户提供的内容(作为 HTML、JavaScript 甚至 CSS),你可能会面临攻击。无论是使用 Vue、其他框架,或是不使用框架,这些建议都是适用的。

除了上面提到的针对潜在的安全隐患提出的建议之外,我们还建议你熟悉以下资源:

  • HTML5 安全备忘录
  • OWASP 的跨站攻击脚本(XSS)防御备忘录

如果你使用了第三方组件或是会影响 DOM 渲染的第三方依赖,请使用你学到的知识检查它们的源代码以便找出潜在的危险。

后端协调

HTTP 安全漏洞主要由后端负责处理,例如跨站点请求伪造(CSRF/XSRF)和跨站点脚本包含(XSSI),因此这不是 Vue 应该考虑的问题。不过,我们非常建议你去和后端团队交流以了解如何最好地与他们的 API 交互,例如通过提交表单提交的 CSRF 令牌。

服务器端渲染(SSR)

使用 SSR 时还有一些额外的安全问题,因此请确保遵循我们在 SSR 文档中概述的最佳实践以避免漏洞。

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)