XSS「Cross Site Script」
文章很干,没有图,耐心。
我们知道了同源策略可以隔离各个站点之间的 DOM 交互、页面数据和网络通信,虽然严格的同源策略会带来更多的安全,但是也束缚了 Web。这就需要在安全和自由之间找到一个平衡点,所以我们默认页面中可以引用任意第三方资源,然后又引入 CSP 策略来加以限制;默认 XMLHttpRequest 和 Fetch 不能跨站请求资源,然后又通过 CORS 策略来支持其跨域。
所以安全性降低了,为了更好的技术应用,同时也带来了更多的安全隐患,如XSS,CSRF。
什么是XSS
Cross-Site Scripting(跨站脚本攻击)简称 XSS,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。
其实防范的宗旨是--增加攻击的难度,降低攻击的后果
XSS攻击类型
第一种 反射型
在一个反射型 XSS 攻击过程中,恶意 JavaScript 脚本属于用户发送给网站请求中的一部分,随后网站又把恶意 JavaScript 脚本返回给用户。当恶意 JavaScript 脚本在用户页面中被执行时,黑客就可以利用该脚本做一些恶意操作。
攻击方式:诱导用户自己点开(一次性),可能发送一些用户数据给脚本。
场景:比如有一个网站 A.com 。
恶意用户「hacker」构造了一个链接「A.com?url=<script>alert('XSS');</script>」。
发送给这个网站用户「user」,当 user 访问这个链接。
本来后端代码写的也有问题,比如用户输入了什么就直接返回什么,这个时候alert('XSS')就会触发。
想想,如果script中是一些获取用户的信息,就是一种比较危险的事情了。
第二种 DOM 型
DOM型攻击都是直接修改dom结构的
1.修改属性插入内容document.write等等,改变dom结构后可以发起攻击
场景:当恶意用户输入的东西存在恶意脚本,也会造成攻击
可以通过encodeURI进行转码
2.基于 DOM 的 XSS 攻击是不牵涉到页面 Web 服务器的。
具体来讲,黑客通过各种手段将恶意脚本注入用户的页面中,比如通过网络劫持在页面传输过程中修改 HTML
页面的内容,这种劫持类型很多,有通过 WiFi 路由器劫持的,有通过本地恶意软件来劫持的,它们的共同点
是在 Web 资源传输过程或者在用户使用页面的过程中修改 Web 页面的数据。
主要通过CSP方式去防范。
第三种 储存型
恶意用户通过输入恶意的脚本,提交数据给后台,恶意的脚本存储到了服务器上,
每次访问数据库的时候都会去触发,伤害最大。
场景:当一个网络论坛里面的评论模块,有一些评论,恶意用户在上面评论了一段恶意脚本,
然后提交到数据库,以后所有的用户直接访问了这个模块的内容就会执行这个脚本,造成攻击
这种攻击常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。
防范:前端:需要校验过滤。
或者在输出的时候过滤,对各种奇怪的符号处理
如:
& === &
" === """
' === &apos
< === <
> === >
可以通过encodeURI进行转码
如何防范XSS攻击呢?
我们知道存储型 XSS 攻击和反射型 XSS 攻击都是需要经过 Web 服务器来处理的,因此可以认为这两种类型的漏洞是服务端的安全漏洞。而基于 DOM 的 XSS 攻击全部都是在浏览器端完成的,因此基于 DOM 的 XSS 攻击是属于前端的安全漏洞。
它们都有一个共同点,那就是首先往浏览器中注入恶意脚本,然后再通过恶意脚本将用户信息发送至黑客部署的恶意服务器上。所以要阻止 XSS 攻击,我们可以通过阻止恶意 JavaScript 脚本的注入和恶意消息的发送来实现。
XSS注入的方式
-
在HTML中,恶意内容以script标签注入,如反射性注入脚本。
通过下面提及的CSP防范
-
在标签的 href、src 等属性中,包含 javascript: 等可执行代码。
通过输入过滤,如果不行会有CSP防范
-
在内联的 JavaScript 中,拼接的数据突破了原本的限制(字符串,变量,方法名等),如eval()、setTimeout()、setInterval() 可以拼接数据并被执行。
跟我们平时写代码的习惯相关了,一般很少有人这么写的
-
在 onload、onerror、onclick 等事件中,注入不受控制代码。
输入脚本进行过滤或转码
如果开发者没有将用户输入的文本进行合适的过滤,就贸然插入到 HTML 中,这很容易造成注入漏洞。攻击者可以利用漏洞,构造出恶意的代码指令,进而利用恶意代码危害数据安全。
前端/服务端对于明确的输入类型,例如数字、URL、电话号码、邮件地址等等内容,进行输入过滤。
但是有些时候,对于一些输入过滤是可能存在乱码的情况。
充分利用 CSP
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
虽然前端/服务端执行过滤或者转码可以阻止 XSS 攻击的发生,但完全依靠前端/服务器端依然是不够的,我们还需要把 CSP 等策略充分地利用起来,以降低 XSS 攻击带来的风险和后果。
实施严格的 CSP 可以有效地防范 XSS 攻击,具体来讲 CSP 有如下几个功能:
- 限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无法被加载的;
- 禁止向第三方域提交数据,这样用户数据也不会外泄;
- 禁止执行内联脚本和未授权的脚本;
- 还提供了上报机制,这样可以帮助我们尽快发现有哪些 XSS 攻击,以便尽快修复问题。因此,利用好 CSP 能够有效降低 XSS 攻击的概率。
使用 HttpOnly 属性
由于很多 XSS 攻击都是来盗用 Cookie 的,因此还可以通过使用 HttpOnly 属性来保护我们 Cookie 的安全。
通常服务器可以将某些 Cookie 设置为 HttpOnly 标志,HttpOnly 是服务器通过 HTTP 响应头来设置的,下面是打开 Google 时,HTTP 响应头中的一段:
set-cookie: id=1000 expires=Sat, 18-Apr-2022 06:52:22 GMT; path=/; domain=.google.com; HttpOnly
其他的办法
输入内容长度控制
对于不受信任的输入,都应该限定一个合理的长度。虽然无法完全防止 XSS 发生,但可以增加 XSS 攻击的难度。
验证码
即使网站被攻击了,核心信息防止脚本冒充用户提交危险操作。
总结
xss攻击是无法从根本上解决的,只能提高攻击者的攻击难度,做到“绝对的安全”
。
各位看官如遇上不理解的地方,或者我文章有不足、错误的地方,欢迎在评论区指出,感谢阅读。