74

【第1311期】浅析前端安全之 XSS

 5 years ago
source link: http://www.10tiao.com/html/293/201806/2651229034/1.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言

今日早读文章由美团@龙佳文授权分享。

正文从这开始~

本篇文章想讲讲 XSS 的产生和防御,主要面向前端安全了解不多的同学。首先,就不直接照搬 XSS 的定义,我想通过下面一个实例来讲讲 XSS 攻击如何进行的,希望会让对前端安全了解不多的同学更容易理解。

从一个实例讲起

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

但是在实现这些功能背后,隐藏了严重的安全问题,接下来,我们来看看这个 bug 是怎么样的,先来看看

可以看到这 IM 支持图片,文字交流,如果我输入一个图片的 html 标签字符,对方就能收到图片。

可是,如果输入的是这样的的 html 标签字符,就会有意料之外的效果

<imgsrc="1"onerror="alert(document.cookie)">

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

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

<divclass="bubble">
   
<pv-html="data.message"></p>
</div>

刚才通过这个简单的 Case,简单介绍了 XSS 的产生和利用。

在常规分类中,XSS 共分为这三种:

  • 存储型

  • 反射型

  • DOM based

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

XSS 的风险

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

信息泄露
  • 个人隐私泄露

  • 商业机密泄露

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

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

如何防御 XSS

转义

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

<head>
   
<metacharset="UTF-8">
   
<title> {{ title }} </title>
</head>

下面是从 https://dev.w3.org/html5/html-author/charref

截取的一部分字符和转义编码的表

这里是从 w3 网站截取的一部分字符和转义编码的表

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

内容白名单

内容白名单,是一个比较宽泛的概念。比如,接着说刚才的富文本的需求,那么我们的内容白名单其实就是 HTML 标签、属性等的一个白名单。比如常规文章、评论富文本,肯定是不需要 <script> 标签的。要去除内容中具有隐患的 script 标签,最简单的方案肯定是替换掉 script 的黑名单策略,但是黑名单意味着未知的风险。

刚才说道不推荐是用黑名单对某些关键词进行过滤。就像这里的这个例子,我如果使用风险关键词替换来实现安全过滤。

这里我实现的是将所有的<script> 替换为空字符。左边的场景能够拦截清除了输入的 <script>, 但右边的场景遇到 <scr<script>ipt>,就不能适用了。

比如常见的富文本场景中,推荐对标签内容进行白名单(标签、属性等)过滤。

比如这里是一个使用 xss 的库对 HTML 做白名单过滤的简单示例:

const xss = require("xss")
const options ={
   whiteList
:{
       a
:["href","title","target"],
       p
:[],
       span
:[],
       h1
:[]
   
}
}
const myxss =new xss.FilterXSS(options);
const result = myxss.process('<script>alert("xss");</script>')
Content Security Policy

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

使用方式

meta

<metahttp-equiv="Content-Security-Policy"content="default-src 'none'; script-src 'self' ssl.google-analytics.com;">

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-stored

https://www.owasp.org/index.php/Cross-siteScripting(XSS))

https://developers.google.com/web/fundamentals/security/csp/

https://content-security-policy.com/

关于本文

作者:@Awee
原文:https://zhuanlan.zhihu.com/p/38327058

最后,为你推荐


【第849期】如何让前端更安全?——XSS攻击和防御详解


【第1043期】jQuery导致的XSS跨站漏洞


【第849期】如何让前端更安全?——XSS攻击和防御详解


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK