浅析前端安全之 XSS

本文是我在掘金技术社区主办的 JTalk 线下活动《前端安全大起底 | 美团技术团队专场》 活动上的分享整理。本篇文章想讲讲 XSS 的产生和防御,主要面向前端安全了解不多的同学。首先,就不直接照搬 XSS 的定义,我想通过下面一个实例来讲讲 XSS 攻击如何进行的,希望会让对前端安全了解不多的同学更容易理解。从一个实例讲起

这里我准备了一个web im demo,在这个 IM 里实现了文字,链接,头像等功能

但是在实现这些功能背后,隐藏了严重的安全问题,接下来,我们来看看这个 bug 是怎么样的,先来看看。可以看到这 IM 支持图片,文字交流,如果我输入一个图片的 html 标签字符,对方就能收到图片。可是,如果输入的是这样的的 html 标签字符,就会有意料之外的效果:

在看到对方的窗口调用了alert,并且内容中是自己的 cookie 信息,这通常意味着我们的 cookie 中的用户认证凭据被盗取了。当然,这里使用 alert 是为了展示脚本的执行能力,通常情况,黑客一旦通过确认某处存在漏洞,那之后利用这个漏洞的所能做的事情就很多了。

看到消息气泡模板,找到问题所在了,这里使用了 v-html 但是却没有做任何安全处理。对于具体安全的处理方式,我们在后面细说。

刚才通过这个简单的 Case,简单介绍了 XSS 的产生和利用。在常规分类中,XSS 共分为这三种:

存储型

反射型

DOM based

我认为,前端应用的复杂度不断提升的今天,这三个分类可能有不少融合的场景。

XSS 的风险

会话劫持

将 cookie 或 token 等类似令牌数据上报给黑客,黑客就能以受害用户的权限进行操作

信息泄露

个人隐私泄露

商业机密泄露

进一步的攻击

运行恶意脚本的用户浏览器可能被操控继续攻击其他目标

有黑客利用 XSS 嗅探内网服务,然后发起下一步的攻击

如何防御 XSS

转义

网页由HTML组成,通常在模板文件中描述,并在页面呈现时嵌入动态内容。存储的XSS攻击利用对来自后端数据存储的动态内容的不当处理。攻击者通过插入一些JavaScript代码来滥用可编辑字段,当另一用户访问该页面时,该代码将在浏览器中执行。

{{ title }}

下面是从https://dev.w3.org/html5/html-author/charref截取的一部分字符和转义编码的表:

说到转义,我们从实际场景出发,来看看我们在 nodejs 中常用的几个模板引擎的实际用例,左边上部分是 ejs ,在 ejs 中是输出转义结果,是不进行转义。下面的虽然语法不一样,都一样提供了转义和不转义的功能。所以在绝大多数场景,请使用转义输出。

内容白名单

内容白名单,是一个比较宽泛的概念。比如,接着说刚才的富文本的需求,那么我们的内容白名单其实就是 HTML 标签、属性等的一个白名单。比如常规文章、评论富文本,肯定是不需要标签的。要去除内容中具有隐患的 script 标签,最简单的方案肯定是替换掉 script 的黑名单策略,但是黑名单意味着未知的风险。刚才说道不推荐是用黑名单对某些关键词进行过滤。就像这里的这个例子,我如果使用风险关键词替换来实现安全过滤。这里我实现的是将所有的替换为空字符。左边的场景能够拦截清除了输入的, 但右边的场景遇到,就不能适用了。

比如常见的富文本场景中,推荐对标签内容进行白名单(标签、属性等)过滤。比如这里是一个使用 xss 的库对 HTML 做白名单过滤的简单示例:

constxss=require("xss")

constoptions={

whiteList:{

a:["href","title","target"],

p:[],

span:[],

h1:[]

}

}

constmyxss=newxss.FilterXSS(options);

constresult=myxss.process('')

Content Security Policy

内容安全性政策 (CSP) 是一个可显著降低现代浏览器中 XSS 攻击的风险和影响的防护功能。 它允许网页的作者控制可以从哪里加载和执行JavaScript(和其他资源)。XSS攻击依赖于攻击者能够在用户的网页上运行恶意脚本 - 通过在页面标记内的某处插入内联标记,或者通过诱骗浏览器从恶意第三方域加载JavaScript。 通过在响应头中设置内容安全策略,您可以告诉浏览器永远不会执行内嵌 JavaScript,并锁定哪些域名可以为页面托管 JavaScript使用方式

meta

header

Content-Security-Policy: default-src 'none'; script-src 'self' ssl.google-analytics.com;

https://content-security-policy.com/CSP 提供了很多指令用来约束不同资源的来源,比如这里我列举了一部分。除了资源来源的指令还有几个特殊的指令,比如 report-uri 可以用于指定一个违反 csp 一些异常情况上报地址,让开发者能够了解到在浏览器的异常情况。

block-all-mixed-content:HTTPS 网页不得加载 HTTP 资源(浏览器已经默认开启)

upgrade-insecure-requests:自动将网页上所有加载外部资源的 HTTP 链接换成 HTTPS 协议

plugin-types:限制可以使用的插件格式,比如禁用 flash, java applet

sandbox:浏览器行为的限制,比如不能有弹出窗口等。

安全意识

最后一点,正如这个图片的标语一样,我们需要时刻保持安全意识。虽然安全始终是相对的,但如果我们通过提高开发中的安全意识,也就增加攻击者发起攻击的成本。

参考链接

https://www.hacksplaining.com/prevention/xss-storedhttps://www.owasp.org/index.php/Cross-site_Scripting_(XSS)https://developers.google.com/web/fundamentals/security/csp/https://content-security-policy.com/

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20180622G0YQ1O00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券