![850a2cf4cca309e5d327db5eced18127.png](https://img-blog.csdnimg.cn/img_convert/850a2cf4cca309e5d327db5eced18127.png)
通过给定异常的输入,黑客可以在你的浏览器中,插入一段恶意的 JavaScript 脚本,从而窃取你的隐私信息或者仿冒你进行操作。
![734b8f76938f822e024d228892758db0.png](https://img-blog.csdnimg.cn/img_convert/734b8f76938f822e024d228892758db0.png)
在理解漏洞之前,要先动一个概念即通源策略
通源策略
说到XSS不得不提“SOP同源策略”
与URLhttp://store.company.com/dir/page.html
进行源对比
![b2811271fe69b744976e564183119d42.png](https://img-blog.csdnimg.cn/img_convert/b2811271fe69b744976e564183119d42.png)
反射型XSS
反射型XSS原理
![3bc7661a0d088620c752706b6f8831fd.png](https://img-blog.csdnimg.cn/img_convert/3bc7661a0d088620c752706b6f8831fd.png)
当Web应用程序使用动态页面向用户显示搜索结果时,便会造成一种常见的XSS漏洞。 这个页面会使用一个包含搜索关键字的参数,并且在响应过程中将文本返回给用户。 以下方PHP代码举例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>反射形xss</title>
</head>
<body>
<form role="search" action="" method="GET">
<input type="text" name="search" placeholder="请输入要搜索的内容">
<button type="submit">搜索</button>
</form>
<?php
if (isset($_GET['search']) && !empty($_GET['search'])) {
// isset()函数检查变量是否已经设置,返回值是 TRUE 和 FALSE
// empty()判断一个[变量]是否被认为是空的。
$search = $_GET['search'];
echo "<h3>你搜索的结果内容是:" . $search . "</h3>";
}
?>
</body>
</html>
在输入框中输入下方的攻击代码
</h3><script>alert('xss');</script><h3>
执行后可以看到浏览器弹窗
![1654b618e5e80a9a7d6184d1b31ed511.png](https://img-blog.csdnimg.cn/img_convert/1654b618e5e80a9a7d6184d1b31ed511.png)
显示页面源代码后,对比源码,可以发现倒数第二行中,出现了攻击代码。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>反射形xss</title>
</head>
<body>
<form role="search" action="" method="GET">
<input type="text" name="search" placeholder="请输入要搜索的内容">
<button type="submit">搜索</button>
</form>
<h3>你搜索的结果内容是:</h3><script>alert('xss');</script><h3></h3>
//上行攻击代码出现处
</body>
</html>
它的攻击原理就是将html标签闭合,然后插入javascript代码让浏览器执行。
这是正常的URL连接
http://101.200.153.218/te/?search=aaa
这是攻击的URL连接
http://101.200.153.218/te/?search=%3C%2Fh3%3E%3Cscript%3Ealert%28%27xss%27%29%3B%3C%2Fscript%3E%3Ch3%3E
这一串代码%3C%2Fh3%3E%3Cscript%3Ealert%28%27xss%27%29%3B%3C%2Fscript%3E%3Ch3%3E
是浏览器将</h3><script>alert('xss');</script><h3></h3>
输入转换而成的。 当直接在浏览器参数后提交代码不成功时,可以尝试进行转义再过尝试。
产生原因
主要原因是对没有实施过滤或净化措施或过滤不严格
基于DOM的XSS
什么是DOM?
![1b7f30a971c414298739a2093e1dec1e.png](https://img-blog.csdnimg.cn/img_convert/1b7f30a971c414298739a2093e1dec1e.png)
一个Web页面,就是一个文档。DOM是Web页面完全面向对象的表述。 DOM是一种模型,中文名为【文档对象模型】。也是HTML和XML的编程接口,提供了队文档的结构化表述,定了一种方式可以从程序中对该结进行访问,从而改变文档的结构,样式和内容。 DOM将文档解析为一个节点和对象组成的结构集合。 即,它将Web页面和脚本或程序语言连接了起来。
说人话,那就是:DOM是一个乐高,HTML和XML是小零件。
一个Web页面,就是一个文档。DOM是Web页面完全面向对象的表述。 API (web 或 XML 页面) = DOM + JS (脚本语言)
举个栗子:
document.getElementsByTagName("p");
document是DOM的对象,document使用getElementsByTagName方法获取到<p>
标签这个元素。 如果没有DOM这个接口,就无法通过API获取文档的元素。
DOM XSS原理
首先,用户请求一个包含JavaScript的特殊URL,会由攻击者提交。然后服务器响应里不会包含攻击者的脚本,当用户的浏览器处理该响应时,这段攻击代码被前端JS里的DOM处理操作引发。
![a8b5063c738d8b21ac9a77b0c532d88e.png](https://img-blog.csdnimg.cn/img_convert/a8b5063c738d8b21ac9a77b0c532d88e.png)
![b4a44c4ee8c87facd8e0e0fc3c9ab670.png](https://img-blog.csdnimg.cn/img_convert/b4a44c4ee8c87facd8e0e0fc3c9ab670.png)
基于DOM的XSS是不需要与服务器交互的,==只发生在客户端处理数据阶段==。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>DOM xss</title>
</head>
<body>
<form role="search" action="" method="GET">
<input type="text" name="search" placeholder="请输入要搜索的内容">
<button type="submit">搜索</button>
//form表单,输入内容后点击submit后,在from属性action无设置的情况下
//form会生成一个携带参数的连接,参数名为input标签的name,参数为输入的内容
</form>
<script>
var search = location.search.substring(8);
//location对象中的search方法使用substring()方法来截取携带的参数。
//substring()是字符串的方法,因为search方法已经做了截取。故可以使用。
document.write('你搜索的结果内容是:' + decodeURIComponent(search));
//document.write()只是一个输出
//decodeURIComponent()为转码方法,如%23专程@
</script>
</body>
</html>
当使用攻击代码<script>alert('xss');</script>
当作内容提交时,没有做特殊字符过滤则浏览器会将输入内容当代码执行。
持久型(存储型) XSS
持久型XSS原理
持久型XSS也称之为存储型XSS,其主要是将恶意代码存储在服务中,当用户浏览带带有恶意代码的页面,那么就遭受到了攻击。
![9aa83b6e281cab99db319aa020338d04.png](https://img-blog.csdnimg.cn/img_convert/9aa83b6e281cab99db319aa020338d04.png)
![50f9010f445e9417764ca6e629c32548.png](https://img-blog.csdnimg.cn/img_convert/50f9010f445e9417764ca6e629c32548.png)
当你在网页中搜索一个关键词时,实际上与这个关键词相关的所有搜索结果都会被展示出来。一旦这些搜索结果中,包含黑客提供的某个恶意 JavaScript 脚本,那么只要我们浏览了这个网页,就有可能会执行这些脚本。
因为这些恶意的搜索结果,会长期保存在服务端数据库中,所以它又叫作存储型 XSS。
因为对于一个反射型或者基于 DOM 的 XSS 来说,需要黑客诱导用户点击恶意的 URL,才能够成功地在用户浏览器上执行 JavaScript 脚本。
XSS能做什么?
1、窃取Cookie
因为同源策略的保护,http://server.com 中是无法直接向 http://hacker.com 发送 GET 或者 POST 请求的。这也是为什么,在上面的例子中,我们需要通过 window.location 来执行跳转操作,间接地将 Cookie 信息发送出去。除了 window.location 之外,我们还可以通过加载 JavaScript 文件、图片等方式,向 http://attacker.com 发送带有 Cookie 的 GET 请求。
2、未授权操作
可以利用 JavaScript 的特性,直接代替用户在 HTML 进行各类操作。
3、按键记录和钓鱼
JavaScript 的功能十分强大,它还能够记录用户在浏览器中的大部分操作。比如:鼠标的轨迹、键盘输入的信息等。也就是说,你输入的账号名和密码,都可以被 JavaScript 记录下来,从而被黑客获取到。
另外,即使某个存在 XSS 漏洞的页面不具备任何输入框,黑客还可以通过修改 DOM,伪造一个登录框,来诱导用户在本不需要登录的页面,去输入自己的用户名和密码。这也是“钓鱼”的一种形式,在这个过程中用户访问的域名是完全正常的,只是页面被篡改了,所以具备更高的迷惑性。 比如,在登陆窗口前再加入一个登陆窗口,输入账户密码提交时,利用脚本的功能,同时填入真窗口中,并发送。此时即让人登陆了网站,也获取到了账户密码。
如何进行XSS防护?
浏览器XSS保护机制
浏览器自带的XSS过滤。如果在IE/Chrome/Safari中尝试这样的示例,浏览器可能会显示以下消息:“为帮助阻止跨站点脚本,已修改此页面。”,窗口也无法弹出。这是因为现代浏览器除了Firefox都包含一个帮助用户防范反射型XSS漏洞的内置机制。
1、验证输出
输出的时候去进行验证,即当需要展示的时候,我们再对内容进行验证,这样我们就能够根据不同的环境去采取不同的保护方案了。 HTML常见XSS注入点
| 注入点 | 示例 | | --- | --- | | HTML元素内容 | <div>内容用户<div>
| | HTML元素属性 | <input value="内容用户">
| | URL请求参数 | http://server.com?search=用户内容
| | CSS值 | color:用户内容 | | JavaScript | `var name="用户内容" |
2、编码
XSS 防护的核心原则就是验证。 我们可以优先采用编码的方式来完成。所谓编码,就是将部分浏览器识别的关键词进行转换(比如 < 和 >),从而避免浏览器产生误解。
| 注入点 | 方法 | | --- | --- | | HTML元素内容 | node.textContent=用户输入
| | HTML元素属性 | element.setAttribute('input',用户输入)
或者element['input']=用户输入
| | URL请求参数 | windows.encodeURIComponent(用户输入)
| | CSS值 | element.style.color=用户输入 |
3、检测和过滤
对用户的内容进行检测。在这里,我们可以采用黑名单和白名单的规则。黑名单往往是我们最直接想到的方法:既然黑客要插入<javascript>
标签,那么我们就检测用户内容中是否存在<javascript>
标签就好了。 但是<javascript>
还会变成<JavaScript>
,甚至使用使用对单个字符转码的形式,其次以HTML5的发展速度,新的标签总是会被开发出来。 因此检测过滤黑名单是一个长期更新和维护的过程。
有黑名单就有白名单,用过防火墙策略的都知道,白名单更便于维护。 比如: 在只输入一个分数的地方,规定只有整型变量是合法的。 在输入字符串的地方,规定只能为文本形式
4、CSP
面对 XSS 这样一个很普遍的问题,W3C 提出了 CSP(Content Security Policy,内容安全策略)来提升 Web 的安全性。所谓 CSP,就是在服务端返回的 HTTP header 里面添加一个 Content-Security-Policy 选项,然后定义资源的白名单域名。浏览器就会识别这个字段,并限制对非白名单资源的访问。配置样例如下所示:
Content-Security-Policy:default-src ‘none’; script-src ‘self’;
connect-src ‘self’; img-src ‘self’; style-src ‘self’;
那我们为什么要限制外域资源的访问呢?这是因为 XSS 通常会受到长度的限制,导致黑客无法提交一段完整的 JavaScript 代码。为了解决这个问题,黑客会采取引用一个外域 JavaScript 资源的方式来进行注入。除此之外,限制了外域资源的访问,也就限制了黑客通过资源请求的方式,绕过 SOP 发送 GET 请求。目前,CSP 还是受到了大部分浏览器支持的,只要用户使用的是最新的浏览器,基本