XSS
狐七 3/12/2022 计算机网络
# 1. XSS是什么?有几种?
查看答案
跨站脚本攻击,有三种方式:
- 反射型XSS
- 存储型XSS
- DOM XSS
其中前两种一般是由服务端漏洞造成的,第三种是由前端漏洞造成的。
本质是:恶意代码与我们的代码混合,浏览器不知道导致恶意代码被执行,由于直接在终端,所以可以直接用恶意代码获取用户的cookie信息,并利用这些信息冒用用户向网站发请求。
# 反射型XSS
在url中写包含恶意的代码,服务端未进行转义就拼接在HTML中返回,浏览器解析之后恶意代码执行。
- GET 一个链接,诱导用户打开
- POST 构造表单提交,引导用户点击(少见)
反射型 XSS 的攻击步骤:
- 攻击者构造出特殊的 URL,其中包含恶意代码。
- ⽤户打开带有恶意代码的 URL 时,⽹站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。
- ⽤户浏览器接收到响应后解析执⾏,混在其中的恶意代码也被执⾏。
- 恶意代码窃取⽤户数据并发送到攻击者的⽹站,或者冒充⽤户的⾏为,调⽤⽬标⽹站接⼝执⾏攻击者指定的操作。
# 存储型XSS
一般是富文本编辑器,服务端将前端传入的HTML格式的字符串,未进行转义直接存在数据库中,然后把数据库中的信息取到之后传给客户端展示,执行恶意代码。
存储型 XSS 的攻击步骤:
- 攻击者将恶意代码提交到⽬标⽹站的数据库中。
- ⽤户打开⽬标⽹站时,⽹站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器。
- ⽤户浏览器接收到响应后解析执⾏,混在其中的恶意代码也被执⾏。
- 恶意代码窃取⽤户数据并发送到攻击者的⽹站,或者冒充⽤户的⾏为,调⽤⽬标⽹站接⼝执⾏攻击者指定的操作。
# DOM XSS
用js的安全漏洞,比如行内代码<img onerror>
,浏览器解析执行恶意代码窃取信息。
DOM 型 XSS 的攻击步骤:
- 攻击者构造出特殊的 URL,其中包含恶意代码。
- ⽤户打开带有恶意代码的 URL。
- ⽤户浏览器接收到响应后解析执⾏,前端 JavaScript 取出 URL 中的恶意代码并执⾏。
- 恶意代码窃取⽤户数据并发送到攻击者的⽹站,或者冒充⽤户的⾏为,调⽤⽬标⽹站接⼝执⾏攻击者指定的操作。
# 2. 反射型XSS常见手段是?
查看答案
- GET:网站搜索、跳转
- POST:表单提交并诱导用户点击
# 3. 存储型XSS常见手段是?
查看答案
- 论坛发帖
- 商品评论
- 用户私信
# 4. 反射型XSS和存储型XSS的区别是?
查看答案
存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里
# 5. DOM XSS和反射型存储型XSS的区别是?
查看答案
DOM XSS是纯前端的漏洞,其他两个是服务端漏洞
# 6. XSS会带来那些危害?
查看答案
攻击者可以通过这种攻击方式可以进行以下操作:
- 获取页面的数据,如DOM、cookie、localStorage;
- DOS攻击,发送合理请求,占用服务器资源,从而使用户无法访问服务器;
- 破坏页面结构;
- 流量劫持(将链接指向某网站);
# 7. 如何预防反射型XSS攻击和存储型XSS攻击?
查看答案
XSS攻击的预防不建议在输入的时候进行转义,而是在输出的时候进行。
将服务端渲染改成纯前端渲染
- 纯前端渲染的时候会清楚的知道内容是文本,还是属性还是样式,这样浏览器就会识别,不会进行别的代码操作。
- 这种方式还需要DOM XSS的防御配合
- 如果遇到性能要求高,对SEO要求高的页面还需要使用服务端渲染
对HTML模板进行转义,ejs,node的js-xss库,把 & < > " ' / 这几个字符转义掉。
使用 CSP
CSP 的本质是建立一个白名单,告诉浏览器哪些外部资源可以加载和执行,从而防止恶意代码的注入攻击。我们只需要配置规则,如何拦截由浏览器自己来实现。
通常有两种方式来开启 CSP:- 一种是设置 HTTP 首部中的Content-Security-Policy。
- 一种是设置 meta 标签的方式对一些敏感信息进行保护,比如 cookie 使用 http-only,使得脚本无法获取。
- 也可以使用验证码,避免脚本伪装成用户执行一些操作。
# 8. 如何预防DOM XSS攻击?
查看答案
- 避免使用
.innerHTML
、.outerHTML
、document.write()
。 - 如果用
Vue/React
技术栈,并且不使用v-html/dangerouslySetInnerHTML
功能。 - DOM 中的内联事件监听器
location
、onclick
、onerror
、onload
、onmouseover
等<a>
标签的 href 属性- JavaScript 的
eval()
、setTimeout()
、setInterval()
等,都能把字符串作为代码运行的代码要小心使用。