1. 概览
XSS: Cross-site Scripting
XSS 是一种 Web 应用中常见的安全漏洞。
XSS 允许攻击者在 Web 页面植入脚本,从而被其他用户看到。XSS 缺陷可能会被攻击者利用来获取基于同源策略的登录权限。
为了获取什么数据:
- 用户敏感信息,cookies
- 发送 HTTP 请求
- 操作 dom 元素
后果:
- Cookie 盗取。 获取 sessionID
- TODO 获取 sessionID 能干啥?
- keylogging(键盘监听)。将用户操作键盘的事件进行监听,获取登录密码或者银行密码等敏感信息。
- phishing ( 网络欺诈 ) 。添加一个虚拟的登录 form,提交时到自己的 Server,从而获取用户的敏感信息。
小结:
- 如果一个攻击者,访问你的网站,能够在其他用户的浏览器执行脚本,那么你的网站和其他用户的安全会受到攻击。
2. XSS 攻击
相关者:
- the website
- the website’s database
- victim 普通用户
- attacker
- attacker’s server
场景示例:
这个示例中 attackers 的最终目标是窃取 victim 的 Cookie。
XSS 类型:
* Persistent XSS ( 持久型 ) 恶意脚本被存储在 Website 的数据库中
* Reflected XSS ( 反射型 ) 当 victim 发请求时脚本才会被执行
* DOM-based XSS ( DOM 依赖型 ) 错误发生在客户端代码
反射型 XSS 攻击:
反射型攻击,恶意字符串会作为 victim 到 Website 请求的一部分。
- 反射型攻击如何实现
反射型 XSS 攻击看起来似乎是无害的,因为它会要求 victim 主动将恶意代码发送至服务器,所以似乎没有方法攻击网站。有两种常用的方式使 victim 主动执行反射型攻击的恶意脚本。
- 钓鱼链接 -> 针对特定人群
- 钓鱼网站或者钓鱼广告 -> 无特定针对
DOM XSS:
如何区分 DOM 依赖型攻击:
- 在传统的 XSS,恶意代码是在页面加载时执行,会作为 server 传送时执行
- DOM XSS 的恶意代码是在页面加载完毕后执行,将用户输入的不安全代码作为合法脚本去执行导致的。
为什么 DOM XSS 很重要:
- 复杂应用使用客户端渲染
- 客户端渲染时使用 xhr + js 渲染 DOM
- 即使 sServer 安全,也不能保证客户端会免受攻击
对 server 不可见的 DOM XSS:
- 对 URL 里面#后面的参数处理不当
- 使用 Localstorage 的数据不当
- 使用 IndexedDB 的数据不当
3. 防御 XSS
方法
- 转码
- 校验
这两种方法的共同点:
- Context(上下文)。 安全处理需要根据页面不同位置的输入和不同。
- Inbound/Outbound。 既可以在收到input的时候做转码(inbound),可也在页面插入时(outbound)再做转码。
- Client/Server。 可以在服务器端,也可以在客户端做校验。视情况而定。
Input handling contexts
Context | Example |
---|---|
HTML 元素内容 | <div>userInput</div> |
HTML 属性值 | <input value="userInput"> |
URL Query 值 | http://example.com/?parameter=userInput |
css value | color: userInput |
Javascript value | var name = “userInput” |
为什么要区分这些情况
Application code | <input value="inputCode"> |
---|---|
Malicious string | "><script>...</script><input value=" |
Resulting code | <input value=""><script>...</script><input value=""> |
Inbound/Outbound
- 需要区分各种输入情况
- 有可能有多个 DOM 是一个数据源
=> 如果在获取数据时做处理 ( Inbound ) 不 UR 在显示时再转换数据(Outbound)应该作为主要防御方法。
在哪里做防御
- Server
- Client
Encoding 转码
Encoding 会使浏览器将脚本转换成 data 显示。如:<and>
=> <and>
1 2 3 4 5 |
print "<html>" print "Latest comment: " print encodeHtml(userInput) print "</html>" |
=> :
1 2 3 4 5 |
<html> Latest comment: <script>...</script> </html> |
在客户端转码
Context | Method / property |
---|---|
HTML element content | node.textContent = userInput |
HTML attribute value | element.setAttribute(attribute, userInput) or element[attribute] = userInput |
url query | window.encodeURIComponent(userInput) |
CSS value | element.style.property = userInput |
局限性
1 2 |
document.querySelector('a').href = userInput |
=>:
编辑器,允许用户自定义 HTML,如果转码会有问题。 需要用 Validation 来处理。
Validation 校验
允许部分如 <em></em>
, 过滤如 <script></script>
。
两种主要实践:
- 分类策略(Classification strategy) 黑名单或者白名单方式区分
- 校验结果(Validation outcome)
分类策略
- 黑名单
- 复杂
javascript:
Javascript:
javascript: - 需要持续更新
- 复杂
- 白名单
- 简单
- 持久
结果校验
- Rejection 直接拒绝,对于不符合要求的输入直接过滤。
- Sanitisation 清理,将不合理的部分去掉,保留符合要求的部分。
使用什么防护技术
- 转码作为主要防线
- 使用 Inbound 校验方式处理特殊的输入,如 HREF 里面的 JavaScript
- 第三道防线,CSP
CSP
安全防护稍有不慎便会危害网站,Content Security Policy (CSP)可以减少风险。
CSP 约束了网站信任的来源,对于下面的情况进行约束:
- 不被信任的来源。外部资源 ( JS, CSS ) 不会被加载
- 行内资源。行内 JS 和 CSS 不会被执行。
- Eval。 Eval不能被使用。
如何启用 CSP
特殊的 header:
1 2 |
Content-Security-Policy |
CSP 语法
示意:
1 2 3 4 5 |
Content‑Security‑Policy: directive source‑expression, source‑expression, ...; directive ...; ... |
Directives:
- connect-src
- font-src
- frame-src
- img-src
- media-src
- object-src
- script-src
- style-src
Source=expression
- 具体指定
1 2 |
protocol://host‑name:port‑number |
- none 不允许引用任何外部资源
- self 只允许本域
- unsafe-inline 允许行内资源
- unsafe-eval 允许eval
注意: 只要 CSP 被使用,Inline 和 Eval 就被禁用,只有通过上面的指定才可允许被使用。
示例
1 2 3 4 5 6 |
Content‑Security‑Policy: script‑src 'self' scripts.example.com; media‑src 'none'; img‑src *; default‑src 'self' http://*.example.com |
总结
XSS 概览
如果对用户输入的处理不够安全,则 XSS 可以通过代码注入进行攻击,一次成功的 XSS 攻击允许攻击者在被攻击者的浏览器端执行有害的 JS 代码,这会危害网站和用户的利益。
XSS 攻击
常见的 XSS 攻击主要有三类:
- 持久化攻击,特点是恶意代码来源为网站的数据库。
- 反射型攻击的来源为受害者主动发起的请求。
- 基于 DOM 的 XSS 攻击主要是由于客户端代码缺陷导致。
如何防御
最重要的防御方式需要对 Input 输入进行处理。
通常我们需要对用户的输入进行编码,在某些不适合进行编码的场合下,需要对输入进行校验,而根据不同的输入类型,需要选择不同的处理的方式。
想要对 XSS 攻击进行彻底防御,我们需要在客户端和服务器端都进行输入端的处理。
CSP 为我们的防御提供了额外的一层保障。
思维导图
本文作者:冯白杨
用户评论(3)
写的很好呀~
很有帮助,赞!
赞👍