XSS攻击原理及危害,说的太详细了!(值得收藏)

随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,在移动互联网时代,web除了传统的 XSS、CSRF 等安全问题之外,又时常遭遇网络劫持、非法调用 Hybrid API 等新型安全问题。当然,浏览器自身也在不断在进化和发展,不断引入 CSP、Same-Site Cookies 等新技术来增强安全性,但是仍存在很多潜在的威胁,这需要技术人员不断进行“查漏补缺”。

近几年,我们面临很多安全挑战,也积累了大量的实践经验。我们梳理了常见的XSS安全问题以及对应的解决方案,希望可以帮助技术人员在日常开发中不断预防和修复安全漏洞。

一. 为什么会有 xss 攻击

因为前端输入的不可信,就会导致恶意代码在浏览器中执行。

  1. 通过一个异常的输入,在用户的浏览器中插入恶意的 javascript 脚本。
  2. 直接添加一个有恶意脚本的网页,诱导用户打开。
  3. 将恶意脚本以话题的方式提交到论坛中,诱使网站管理员打开这个话题,从而获得管理员权限,控制整个网站。

二. xss 攻击的种类

1. 存储型 XSS - 存储在数据库中
a.攻击者将恶意代码提交到目标网站的数据库中。

b.用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器。

c.用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。

d.恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作

在这里插入图片描述

这种攻击常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等

存储型 xss 案例:
1、在UGC(User-generated Content,用户生产内容,百度贴吧,微博等)业务上,比较容易出现存储型 xss 漏洞。

如何解决:
1、属性值过滤
2、重写
参考:腾讯安全应急响应中心:https://security.tencent.com/index.php/blog/msg/53

2. 反射型 XSS
a、攻击者构造出特殊的 URL,其中包含恶意代码。

b、用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。

c、用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。

d、恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

反射型 XSS 漏洞常见于通过 URL 传递参数的功能,如网站搜索、跳转等

反射型 xss案例:
script 标签出现在 url
jacascript:代码出现在url
jAvascRipt: 代码出现在url

解决:白名单解决法,在白名单内就返回页面,不再一律返回404

某天,公司做需要一个搜索页面,根据 URL 参数决定关键词的内容。代码如下:

<input type=“text” value=“<%= getParameter(“keyword”) %>”>
搜索

您搜索的关键字是:<%= getParameter("keyword") %>

如果 黑客构造一下的url, 就可以轻易发起攻击。

http://xxx/search?keyword=“>,拼接到 HTML 中返回给浏览器。形成了如下的 HTML:

">
搜索

您搜索的关键词是:">

问题的原因是,浏览器把用户的输入当成了脚本进行了执行。
解决办法:只要告诉浏览器这段内容是文本就可以解决了

于是有了下面这段代码:

<input type=“text” value=“<%= escapeHTML(getParameter(“keyword”)) %>” >
搜索

您搜索的关键词是: <%= escapeHTML(getParameter("keyword")) %>
escapeHTML()按照如下规则进行转义: ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/d4d9ef3b368c41bfaf671aa3ffe6d4a6.png) 转义之后确实可以解决上面的那个利用标签闭合,进行攻击的情况。但是新的问题继续有: 如果 url 是这样的形式:http://xxx/?redirect_to=javascript:alert('XSS'), 展示在页面的一个 a 标签上:

跳转…
点击 a 标签,还是会弹出 xss,原来不仅仅是特殊字符,连javascript:这样的字符串如果出现在特定的位置也会引发 XSS 攻击。

考虑到只要 URL 的开头不是javascript:, 是不是就可以解决上面的问题。
代码如下:

// 禁止 URL 以 “javascript:” 开头
xss = getParameter(“redirect_to”).startsWith(‘javascript:’);
if (!xss) {
<a href=“<%= escapeHTML(getParameter(“redirect_to”))%>”>
跳转…

} else {

跳转…

}
这样就安全了吗?不是的。
如果 url 的链接是这样的 :http://xxx/?redirect_to=jAvascRipt:alert(‘XSS’),或 http://xxx/?redirect_to=%20javascript:alert(‘XSS’)
依旧可以完成 xss 攻击。

那么如何解决呢?可以通过白名单的方法。

代码如下:

// 根据项目情况进行过滤,禁止掉 “javascript:” 链接、非法 scheme 等
allowSchemes = [“http”, “https”];

valid = isValid(getParameter(“redirect_to”), allowSchemes);

if (valid) {
<a href=“<%= escapeHTML(getParameter(“redirect_to”))%>”>
跳转…

} else {

跳转…

}

总结:
a、攻击者利用用户输入片段,拼接特殊格式的字符串,突破原有位置的限制,形成了代码片段。

b、通过 HTML 转义,可以防止部分 XSS 攻击。(不同情况下,需要采用不同的转义规则)

c、如果数据是以 json 的形式,内联到 html 中 , 插入 json 的地方不能用 escapeHTML() 转义, 这样会破坏json格式。

d、如果 json 中包含字符串 时, 会闭合前一个

e、对于链接跳转,如<a href="xxx"或location.href=“xxx”,要检验其内容,禁止以javascript:开头的链接,和其他非法的 scheme。

3. 基于 DOM 的 XSS(其实是一种特殊类型的反射型 xss)

在这里插入图片描述

  1. 攻击者构造出特殊的 URL,其中包含恶意代码。
  2. 用户打开带有恶意代码的 URL。
  3. 用户浏览器接收到响应后解析执行,前端 JavaScript 取出 URL 中的恶意代码并执行。
  4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。

dom 型 xss 案例
1、取值写入页面或动态执行

想要在客户端实现接受参数并写入页面或动态执行,就不得不用到JavaScript“三姐妹”,她们分别是:innerHTML、document.write、eval。

直接从URL的锚参数(即位于#后面的参数)中取值,不经过任何处理直接innerHTML写入页面, 如果攻击者构造这样的 url :
http://xxx.com/xxx.htm#msg=<img /src=x οnerrοr=alter(1)/>

由于整个攻击不需要像服务端发送任何数据,所以即使业务接入了 web 应用防火墙(WAF),也无法抓到这类 dom xss。

从 cookie中取值
直接从cookie中取值写入页面或动态执行,原理基本同从URL中的取参数值写入页面或动态执行,只是换了一个取值来源而已。
但同时我们注意到,还有一种较为特殊的业务场景,取cookie键值,动态拼接要页面引入前端资源的URL。
代码如下:
在这里插入图片描述
如果window.isp取到的值为“www.attacker.com/”,最终拼接出来的静态资源URL路径为:http://www.attacker.com/victim.com,因为“.”和“/”都不在转义范围内,导致攻击者可以向页面引入自己站点下的恶意js文件,进而实施DOM-XSS攻击.

从localStorage、Referer、Window name、SessionStorage中的取参数值写入页面或动态执行
一般情况下 window.name 容易被认为来源可信,但借助 iframe 的 name 属性,攻击者可以将页面的 window.name 设置为攻击代码,构造DOM XSS:
在这里插入图片描述
总结:

  1. 在取值写入页面或动态执行的业务场景下,在将各种来源获取到的参数值传入JavaScript“三姐妹”函数(innerHTML、document.write、eval)处理前,对传入数据中的HTML特殊字符进行转义处理能防止大部分DOM-XSS的产生.
  2. 根据不同业务的真实情况,还应使用正则表达式,针对传入的数据做更严格的过滤限制,才能保证万无一失。
  3. 不到万不得已,不要使用eval函数处理不可控的外部数据。
  4. 对于从cookie,还是从localStorage、Referer、Window name、SessionStorage中获取数据,都应使用安全的函数,对传入的数据做过滤后,再传递给相关函数写入页面或执行。
  5. 参考/使用filter.js库

2. 前端实现页面跳转
最常用的方式有 location.href 、location.replace() 、 location.assign()
也许提到页面跳转业务场景下的安全问题,你首先会想到限制不严导致任意URL跳转,而DOM XSS与此似乎“八竿子打不着”。但有一种神奇的东西叫“伪协议”,比如:“javascript:”、“vbscript:”、“data:”、“tencent:”、“mobileqqapi:”等,其中“javascript:”、“vbscript:”、“data:”在浏览器下可以执行脚本:
使用这些伪协议执行的JavaScript代码,就相当于在页面内注入了一段恶意代码

使用indexOf判断URL参数是否合法, 代码如下
在这里插入图片描述
indexOf 是一个从头到尾检索字符串,查找是否有字串 xxx,如果攻击者构造 ‘javascript:alert(1);//xxx://’ 这样的url,即可以成功让 indexOf 返回true,并进入跳转逻辑,完成攻击。又可以让 javascript 代码运行时忽略。(因为 xxx:// 位于JavaScript代码的注释部分)

正则表达式缺陷
由于 indexOf下藏着的深坑,想出用正则表达式解决这类问题,但是正则表达式也会有一些问题,比如:
跳转页面只能是qq.com/paipai.com。

认为这样就可以解决DOM-XSS和URL跳转的问题,但忘了一个神奇的符号“^”,加上和不加上,过滤的效果具有天壤之别。
(因为正则没有严格限制传入的URL开头只能是“http”或“https”,攻击者仍然可以构造“javascript:alert(1);//http://www.qq.com”来绕过看似严格的过滤。)

总结:

1、限制能够跳转页面的协议:只能是http、https或是其他指可控协议;

2、严格限制跳转的范围,如果业务只要跳转到指定的几个页面,可以直接从数组中取值判断是否这几个页面。

3、如果跳转范围稍大,正确使用正则表达式将跳转URL严格限制到可控范围内。

三、XSS 攻击的总结

防范存储型和反射型 XSS 是后端的责任

DOM 型 XSS 攻击不发生在后端,是前端的责任。

不同的上下文,调用不同的转义规则

如 HTML 属性、HTML 文字内容、HTML 注释、跳转链接、内联 JavaScript 字符串、内联 CSS 样式表等,所需要的转义规则不一致。业务 需要选取合适的转义库,并针对不同的上下文调用不同的转义规则。

四. xss 攻击有什么危害

窃取敏感信息:攻击者可以通过注入恶意脚本,窃取用户的敏感信息,如用户名、密码、Cookie等。这些信息可以用来冒充用户身份进行恶意操作。

劫持会话:攻击者通过窃取用户的会话令牌或Cookie,能够劫持用户的会话,实施未经授权的操作,如修改账户信息、发表言论等。

篡改网页内容:攻击者可以通过注入恶意脚本,修改网页上的内容,向用户展示虚假信息、欺骗性的广告、恶意链接等,影响用户的体验和信任。

钓鱼攻击:攻击者可以伪造合法网站,诱使用户输入敏感信息,如银行账户密码、信用卡信息等,从而实施钓鱼攻击。

恶意操作:攻击者可以在用户浏览器中执行恶意脚本,例如发起DDoS攻击、改变用户设置、执行未授权操作等,从而对用户和网站造成实际损害。

信任破坏:如果用户发现网站存在XSS漏洞,可能会对该网站产生质疑并失去信任,导致用户流失。

传播恶意代码:攻击者可以利用XSS漏洞传播恶意软件、病毒或恶意脚本,进一步扩大攻击范围。

破坏隐私:用户的隐私可能会被泄露,从而导致个人、财务等方面的损失。

五、防止 XSS 攻击

为了有效防御跨站脚本攻击,以下是一些常见的防御措施:

输入验证和过滤:对于所有用户输入的数据,包括表单提交、URL参数等,进行严格的验证和过滤。确保只允许合法和预期的输入通过。可以使用白名单过滤、正则表达式匹配等方法来防止不安全的输入。

输出转义:在将用户输入数据插入到HTML页面时,使用适当的输出转义机制,将特殊字符转换为它们的HTML实体形式。这样可以防止浏览器将输入内容解释为代码。

使用安全的编码库:使用安全的编码库来处理用户输入和输出,这些库会自动执行必要的输入验证、过滤和输出转义,从而减少开发者的出错机会。

Content Security Policy(CSP):CSP是一种安全策略,可以在HTTP头中设置,用于限制页面可以加载的资源和执行的脚本。通过设置合适的CSP规则,可以有效减少XSS攻击的风险。

HttpOnly和Secure标记:在设置Cookie时,使用HttpOnly标记确保Cookie不能被JavaScript访问,使用Secure标记确保Cookie只在HTTPS连接中传输。

使用框架和库:使用流行的Web开发框架和库(如React、Angular、Vue.js等),这些框架通常有内置的安全机制,可以减少XSS攻击的风险。

教育用户:提高用户的网络安全意识,让他们了解XSS攻击的风险和如何避免受到攻击。

定期安全审计:定期检查和审计代码,查找潜在的XSS漏洞,及时修复。

最小化权限:在数据库和服务器上使用最小权限原则,限制应用程序和用户的访问权限,减少攻击者能够获取的敏感信息。

避免内联脚本:尽量避免使用内联脚本,而是使用外部JavaScript文件。这样可以帮助隔离用户输入和执行的代码。

使用HTTPOnly Cookie:使用HTTPOnly Cookie可以防止通过JavaScript访问Cookie,从而减少攻击者窃取会话令牌的可能性。

安全开发实践:遵循安全的开发实践,编写安全的代码,不信任用户输入,使用最新的漏洞库和工具进行代码审查和漏洞扫描。

最后,如果我的文章对你有所帮助或者有所启发,欢迎关注公众号(微信搜索公众号:首席架构师专栏),里面有许多技术干货,也有我对技术的思考和感悟,还有作为架构师的验验分享;关注后回复 【面试题】,有我准备的面试题、架构师大型项目实战视频等福利 , 小编会带着你一起学习、成长,让我们一起加油!!!

  • 28
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

首席架构师专栏

喜欢请点赞,么么哒

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值