前端安全系列(一):如何防止XSS攻击? (3)

对于链接跳转,如 location.href="xxx",要检验其内容,禁止以javascript:` 开头的链接,和其他非法的 scheme。

根据上下文采用不同的转义规则

某天,小明为了加快网页的加载速度,把一个数据通过 JSON 的方式内联到 HTML 中:

<script>
var initData = <%= data.toJSON() %>
</script>

插入 JSON 的地方不能使用 escapeHTML(),因为转义 " 后,JSON 格式会被破坏。

但安全组又发现有漏洞,原来这样内联 JSON 也是不安全的:

当 JSON 中包含 U+2028U+2029 这两个字符时,不能作为 JavaScript 的字面量使用,否则会抛出语法错误。

当 JSON 中包含字符串 时,当前的 script 标签将会被闭合,后面的字符串内容浏览器会按照 HTML 进行解析;通过增加下一个 标签等方法就可以完成注入。

于是我们又要实现一个 escapeEmbedJSON() 函数,对内联 JSON 进行转义。

转义规则如下:

字符转义后的字符
U+2028   \u2028  
U+2029   \u2029  
<   \u003c  

修复后的代码如下:

<script>
var initData = <%= escapeEmbedJSON(data.toJSON()) %>

通过这个事件,小明学习到了如下知识:

HTML 转义是非常复杂的,在不同的情况下要采用不同的转义规则。如果采用了错误的转义规则,很有可能会埋下 XSS 隐患。

应当尽量避免自己写转义库,而应当采用成熟的、业界通用的转义库。

漏洞总结

小明的例子讲完了,下面我们来系统的看下 XSS 有哪些注入的方法:

在 HTML 中内嵌的文本中,恶意内容以 script 标签形成注入。

在内联的 JavaScript 中,拼接的数据突破了原本的限制(字符串,变量,方法名等)。

在标签属性中,恶意内容包含引号,从而突破属性值的限制,注入其他属性或者标签。

在标签的 href、src 等属性中,包含 javascript: 等可执行代码。

在 onload、onerror、onclick 等事件中,注入不受控制代码。

在 style 属性和标签中,包含类似 background-image:url("javascript:..."); 的代码(新版本浏览器已经可以防范)。

在 style 属性和标签中,包含类似 expression(...) 的 CSS 表达式代码(新版本浏览器已经可以防范)。

总之,如果开发者没有将用户输入的文本进行合适的过滤,就贸然插入到 HTML 中,这很容易造成注入漏洞。攻击者可以利用漏洞,构造出恶意的代码指令,进而利用恶意代码危害数据安全。

XSS 攻击的分类

通过上述几个例子,我们已经对 XSS 有了一些认识。

什么是 XSS

Cross-Site Scripting(跨站脚本攻击)简称 XSS,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。

为了和 CSS 区分,这里把攻击的第一个字母改成了 X,于是叫做 XSS。

XSS 的本质是:恶意代码未经过滤,与网站正常的代码混在一起;浏览器无法分辨哪些脚本是可信的,导致恶意脚本被执行。

而由于直接在用户的终端执行,恶意代码能够直接获取用户的信息,或者利用这些信息冒充用户向网站发起攻击者定义的请求。

在部分情况下,由于输入的限制,注入的恶意脚本比较短。但可以通过引入外部的脚本,并由浏览器执行,来完成比较复杂的攻击策略。

这里有一个问题:用户是通过哪种方法“注入”恶意脚本的呢?

不仅仅是业务上的“用户的 UGC 内容”可以进行注入,包括 URL 上的参数等都可以是攻击的来源。在处理输入时,以下内容都不可信:

来自用户的 UGC 信息

来自第三方的链接

URL 参数

POST 参数

Referer (可能来自不可信的来源)

Cookie (可能来自其他子域注入)

XSS 分类

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwsspx.html