Web 安全防护:XSS 攻击的基础和原理
跨站脚本 (XSS) 攻击是客户端脚本安全的头号敌人。本文深入讨论了XSS攻击的原理,下一章(高级XSS攻击)将更深入地讨论XSS攻击方法。
XSS简介
XSS(Cross Site Script),全称跨站脚本攻击。为了与CSS(Cascading Style Sheet)区别,安全领域将其称为XSS。
XSS攻击通常是指黑客在中注入HTML来篡改网页并插入恶意脚本,从而在用户浏览网页时控制用户的浏览器。这种行为刚出现时,所有演示案例都是跨域行为,因此被称为“跨站脚本”。如今,随着Web端功能的复杂化和应用,是否跨站已经不再重要,但XSS名称始终被保存。 随着Web的快速发展,JavaScript可以用于前后台,甚至可以开发APPLICATION。因此,随着应用场景的增长和变得更加复杂,XSS变得越来越难以统一定位。目前业界的共识是,针对不同场景创建的不同XSS应该区别对待。但即便如此,复杂的应用程序仍然是 XSS 的滋生地,尤其是当许多公司进行快速开发,每周发布一个版本,每两周发布一个版本,而忽略了重要的安全属性时。一旦遭到攻击,后果将不堪设想。 那么什么是XSS?让我们看下面的例子。 现在,当我们点击页面上的按钮 你会发现界面上应该作为数据显示的内容是实际执行。这显然是开发商所不愿意看到的。 XSS 根据效果不同可以分为以下几类: 简单来说,反射型 XSS 只显示用户在任何浏览器(从任何浏览器)输入的数据。浏览器)。 come, be),即需要发起者(用户)触发黑客设置的陷阱(如链接、按钮等)才能攻击成功。大多数在搜索页面和留言板上很容易看到。这种类型的反射型 XSS 也称为 非持久性 XSS(No-Persistent XSS)。 示例: 假设这是一个留言板。加载到此页面时,会出现一个页面: 黑客可以轻松窃取您本地浏览器中存储的各种信息,然后模拟您的登录信息。侵入您的帐户并执行各种操作。 存储型XSS会存储用户输入的数据在服务器端,此类XSS非常稳定,非常有效,而且效果持久。存储的XSS通常被称为“持久性XSS(持久性XSS)”,意思是它已经存在很长时间了。 更常见的情况是黑客撰写包含恶意代码的文章。文章发布后,所有访问博客文章的用户都会执行这段代码,进行恶意攻击。 示例: 直接返回浏览器信息。黑客可以拿到这些信息并将其发送到自己的服务器上随意操作。 实际上,这种类型的XSS与服务器端存储的内容无关。实际上,它也是反射型 XSS。单独划分是因为该类型XSS的形成原因比较特殊。 简单来说,通过修改页面的DOM节点形成的XSS称为DOM Based XSS。 示例如下: 该页面的功能是在输入框中输入内容,搜索结果会直接跳转。效果如下: 点击搜索结果后,页面会自动跳转到百度页面(有毒),但如果我们细心的话,我们会发现其中存在字符串拼接的机会。输入 果然,页面执行了我们所说的操作 填写上面的内容以关闭第一个双引号 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>XSS</title>
</head>
<body>
<div id="t"></div>
<input id="s" type="button" value="获取数据" onclick="test()">
</body>
<script>
function test() {
// 假设从后台取出的数据如下
const arr = ['1', '2', '3', '<img onerror="alert(\'我被攻击了\')" />']
const t = document.querySelector('#t')
arr.forEach(item => {
const p = document.createElement('p')
p.innerHTML = item
t.append(p)
})
}
</script>
</html>获取数据时,页面上会出现以下信息: ![]()
XSS 攻击的类型
反射型 XSS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="t"></div>
<input id="s" type="button" value="获取数据" onclick="test()">
</body>
<script>
function test() {
const arr = ['1', '2', '3', '<img onerror="console.log(window.localStorage)" />']
const t = document.querySelector('#t')
arr.forEach(item => {
const p = document.createElement('p')
p.innerHTML = item
t.append(p)
})
}
</script>
</html>![]()
存储型XSS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="t">
这是我写的一篇文章
</div>
</body>
<script>
console.log(navigator.userAgent)
</script>
</html>![]()
基于DOM的XSS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>XSS</title>
</head>
<body>
<div id="t"></div>
<input type="text" id="text" value="">
<input type="button" id="s" value="search" onclick="test()">
</body>
<script>
function test() {
const str = document.querySelector('#text').value
document.querySelector('#t').innerHTML = '<a href="'%20+%20str%20+%20'" >查找结果</a>'
}
</script>
</html>![]()
" onclick=alert(/XSS/) //: ![]()
hrefhref ,然后把事件onclick,最后一个注释符号//注释双引号,点击跳转链接,脚本就会执行。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网
