头图

网络安全是我们开发过程中需要关注的重点一环,今天Cagen同学给大家详细介绍一下 XSS 的相关内容,帮助我们更好的防范 XSS 攻击

作者: Cagen
转载:https://mp.weixin.qq.com/s/vN...

什么是 XSS

XSS (Cross-site scripting),即跨站脚本攻击,应该是前端同学都应该听过的网络安全相关的名词。它是一种尝试注入恶意脚本代码到网站上的攻击形式。它可以使得恶意使用者的代码在受影响用户的浏览器端执行,并对用户的影响。

危害

似乎离我们很遥远,似乎是 Web 1.0 时代的产物了。但实际上,从 2000 年 XSS 这个名词出现以来,直到 20 年后的今天,XSS 一直是 Web 安全中一个非常重大的威胁。在当前开放式Web应用程序安全项目 OWASP)的排名前 10 的安全风险和漏洞中,XSS 依旧是其中之一。

在网络安全平台 Snyk 的开源报告中所披露最多的漏洞中,XSS 漏洞的数量是大幅领先其他的漏洞。

其可能产生的危害也会有很多,最常见的攻击手段是可以通过恶意脚本的执行,获取到网站用户的 cookies 等隐私信息,并回传到其自身的服务器上,通过 cookies 中的 session 信息,相当于获取了用户的操作权限。除此之外,恶意脚本可以做到几乎脚本能够做到的任何事情,包括键盘记录,替换界面内容,窃取用户信息,更有甚者可以以用户权限为跳板,对服务器进行进一步的攻击。且因为各种安全机制的木桶效应,一旦被 XSS 攻击,网站的其他安全机制也会难以为继,如多重验证机制,或针对 CSRF 等所做的一些自动化防御措施也会等同于失效。

XSS 类型

XSS 大致可以分为 3 个类型

  1. 反射型 (Reflected XSS Attacks) 此种类型的跨站代码存在于URL中,所以黑客通常需要通过诱骗或加密变形等方式,将存在恶意代码的链接发给用户,只有用户点击以后才能使得攻击成功实施。本攻击
  2. 存储型(Stored XSS Attacks) 存储型XSS脚本攻击是指Web应用程序会将用户输入的数据信息保存在服务端的数据库或其他文件形式中,网页进行数据查询展示时,会从数据库中获取数据内容,并将数据内容在网页中进行输出展示,因此存储型XSS具有较强的稳定性。
  3. DOM-based 型(DOM-based XSS Attacks) DOM-based 的跨站脚本攻击是通过修改页面DOM节点数据信息而形成的跨站脚本攻击。

其中反射型和存储型的恶意代码一般都会经过服务器来返回。而 DOM-based 的类型则不会。所以有些时候,一个带有 XSS 注入脚本的 URL 根据不同 Web 应用的架构形式可能会是反射型或者 DOM-based 型。

常见的攻击手段

XSS 的攻击手段千变万化,以下介绍的只是非常基础的两种,以供大家有对 XSS 有一个简单的概念。

来源于用户的表单输入

最常见莫过于回显输入框的情况,如果没有任何防御 XSS 的对策,则用户可以将输入的任何字符串直接变为 HTML 的内容。比如我们常常见到的 \<script\> 标签的形式,常用于存储型的 XSS 攻击。

除此之外,还有很多的 HTML 标签可以被 XSS 攻击利用,比如常见的 \<img\>,\<a\>,\<iframe\> 等等,这些标签不仅常用于存储型的 XSS 攻击,在 DOM-based 型的攻击中更加容易产生威胁:

通过插入这样的代码,可以在页面中执行任意脚本。

来源于 URL 中的某些部分

另一种形式是通过 URL 的参数来注入特定的脚本,比如 URL 中带有一些搜索参数的时候,有可能被 XSS 攻击所利用。比如一个 Web 应用读取了 query 参数并打算将其显示在搜索结果页面上:

此时攻击者就可以将恶意代码注入 URL 中,如:

https://www.example.com/search?query=%3Cimg%20src=%22xx%22%20onerror=%22javascript:alert(1);%22%3E

实战

XSS Game

\<https://xss-game.appspot.com/\> (此地址国内打开可能有困难)

这个游戏是 Google 提供的一个 XSS 的小游戏,大家可以自己在浏览器里试试看能不能闯过所有的关卡(可以通过研究 Target Code 来找到可以注入代码的地方,如果想不出来可以看看页面上的 Hints)。建议尽量不要看提示来挑战。这个游戏一共有 6 关,每个关卡利用了各种不同的技巧和方式来插入恶意代码,有些方式确实非常取巧。完成这个游戏能让你对 XSS 攻击有一个非常直观的认识。

这个游戏中因为没有使用实际的服务器存储,所以 这个游戏中: Level 1 属于反射型, Level 2 属于储存型(当然在当前的例子中其实算是DOM-based 的,实际中碰到的就是存储型的了), Level 3- 6 都属于 DOM-based 的类型。

更多的实验

因为现在大部分的前后端框架都会有 XSS 相关的安全策略,且默认是开启的,平时想要测试一下 XSS 的漏洞可能还比较麻烦。针对这种情况,可以使用 Damn Vulnerable Web Applicationhttps://github.com/digininja/...),它是一个主动关闭了各种安全策略的 Web 应用,包括了各种各样漏洞,当然也包括 XSS 的部分,可以用来测试自己对这些漏洞的掌握。

防范手段

防御 XSS 一大原则就是不要信任用户输入的内容!所有用户输入的内容都可以默认为不可控的、不安全的,包括但不限于 表单输入/URL 等可以由用户任意输入的来源。在回显用户的输入时候一定要做 XSS 的过滤和相应的编码。

浏览器内置的安全机制

开启 X-XSS-Protection:针对反射型 XSS 的一种浏览器防御机制,现在大部分现代浏览器已经废弃了这个属性。

内容安全策略 CSP:CSP通过指定有效域——即浏览器认可的可执行脚本的有效来源——使服务器管理者有能力减少或消除XSS攻击所依赖的载体。一个CSP兼容的浏览器将会仅执行从白名单域获取到的脚本文件,忽略所有的其他脚本 (包括内联脚本和HTML的事件处理属性) 浏览器的同源策略。

Cookie 安全:设置 Cookie 的 HttpOnly 属性,能够最大限度的保证你的 Cookie 不会被脚本所读取并发送到其他服务器上。

使用成熟的框架安全机制

对于前端来说,使用常用的库,React/Vue/Angular 等流行框架来渲染数据基本上都不会有太大的问题。需要注意的是,必须非常非常非常慎重使用类似 React 的 dangerouslySetInnerHTML 或者 Vue 的 v-html 这类绕过 XSS 过滤能力的属性。

不少后端服务的框架也都在设计时就考虑了 XSS 的安全问题,如 Ruby on Rails。当然这类防御措施还是有其局限性的,并不是能一劳永逸的解决所有攻击威胁的。

在没有框架安全机制保证下需要避免的操作

对于前端来说,主要需要针对处理的是 DOM-based 的 XSS 威胁。

在使用 Vanilla JavaScript 需要避免那些能够直接修改 HTML 的操作,如 innerHTML/outerHTML 属性或者 document.write 之类的方法。当需要展示文本的时候,选择如 textContent/innerText 之类安全的方法。当需要创建 HTML 标签的时候,选择 createElement/appendChild 之类的方法。

还有就是更加危险的 eval 方法,虽然一般不会使用,但是需要避免一些隐式的 eval 使用,比如 setTimeout/setInterval 就可以通过 setTimeout(codeAsString, delay) 的形式执行任意字符串代码。

除此之外还有 HTML 标签上的一些事件属性等等。

如果无可避免的要使用类似方法,一定在渲染前做好过滤和编码工作。

更加细致的防范 CheatSheet

开放式Web应用程序安全项目 OWASP)提供了针对 XSS 防御的详尽 CheatSheet,感兴趣的同学可以作为参考。

https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.htm

https://cheatsheetseries.owas...

安全检测

一些工具可以扫描网站存在的 XSS 漏洞,可以方便查缺补漏

https://github.com/s0md3v/XSS...

https://www.zaproxy.org/

最后的最后

需要注意,以上这些防御措施不能详尽描述每个细节和抵御所有 XSS 攻击方式。针对 XSS 的攻防战没有一劳永逸的银弹,也没有傻瓜式的解决方案。只有严格遵照安全最佳实践来尽量避免,并提升安全防范的意识,加强安全审计的工作。

参考资料

https://xss-game.appspot.com/

https://www.google.com/about/...

https://medium.com/@sagarvd01...

https://zhuanlan.zhihu.com/p/...

https://developer.mozilla.org/en-us/docs/Web/HTTP/Headers/X-XSS-Protection

https://security-consulting.icu/blog/2015/03/bypass-csrf-protection-via-xss/

https://snyk.io/learn/cross-site-scripting/

https://owasp.org/www-project-top-ten/

https://en.wikipedia.org/wiki/Cross-site_scripting

The End

如果你觉得这篇文章对你有帮助,有启发,我想请你帮我2个小忙:
1、点个「」,让更多的人也能看到这篇文章内容;
2、关注公众号「豆皮范儿」,公众号后台回复「加群」 加入我们一起学习;

关注公众号的福利持续更新,公众号后台送学习资料:
1、公众号后台回复「vis」,还可以获取更多可视化免费学习资料。
2、公众号后台回复「webgl」,还可以获取webgl免费学习资料。
3、公众号后台回复「算法」,还可以获取算法的学习资料。
4、公众号后台回复「招聘」,获取各种内推。


豆皮范儿
39 声望5 粉丝

爱编程的字节跳动数据平台前端妹子