CSRF、XSS学习
什么是 CSRF
跨站请求伪造(英语:Cross-site request forgery)
CSRF 就是利用用户的登录态发起恶意请求。
这个主要利用的是用户的 Cookie 的特性,每次向主机访问都会携带上 Cookie,所以像传统的基于 Session 维护用户状态的网站就会给坑到,具体如何实现呢?
因为现在同源策略已经出来了,所以一般是无法跨站点访问,因此这里就只讲通过图片方式的访问
如下,表面看起来是一个图片标签,但是访问的却是当前网站的某个 api,这样每次当用户刷新都会访问这个链接,加上每次请求都会携带用户的 Cookie 去访问服务端,会让服务端以为这个就是用户自己发的
<img src="http://alsritter.icu/student/set-user?name=joh&age=18">
PS:一般都是通过类似 Markdown 评论区这样的地方注入的
![这是一张假的图片链接](http://alsritter.icu/student/set-user?name=joh&age=18)
解决办法就是使用 Token 机制,每次都需要从 localStorage
里取得 Token 再添加到请求头里发送请求,避免使用 Cookie-Session 来验证身份
什么是 XSS
XSS 攻击是指攻击者在网站上注入恶意的客户端代码,通过恶意脚本对客户端网页进行篡改,从而在用户浏览网页时,对用户浏览器进行控制或者获取用户隐私数据的一种攻击方式。
一般就是通过各种手段注入一段 JS
<script>alert("看到这条消息表示注入成功!")</script>
或者想要偷偷的增加访问量可以使用这个 iframe
标签
<!-- frameborder="0" 规定是否显示框架周围的边框 1显示边框 0不显示 -->
<iframe src="http://alsritter.icu/2020/10/27/CSRF/" frameborder="0" width="100%"></iframe>
所以一般对于能让用户输入内容的地方最好加个转译,如下,这样就能很有效防止部分直接通过插入 Dom 的注入了
字符 | 转义后的字符 |
---|---|
& | & |
< | < |
> | > |
" | " |
' | ' |
/ | / |
更多特殊字符转译参考 这里
常见的 XSS 分为 反射型、存储型 和 DOM 型
反射型 XSS
这种是基于请求参数的,接收了参数,不做处理还直接回显给页面就会给注入(一般容易出现在搜索页面)
http://127.0.0.1:5500/temp.html?message=<script>alert("看到这条消息表示注入成功!")</script>
发出请求时,XSS 代码出现在 url 中,作为输入提交到服务器端,服务器端解析后响应,XSS 代码随响应内容一起传回给浏览器,最后浏览器解析执行 XSS 代码。这个过程像一次反射,所以叫反射型 XSS。
下面 php 的同理(图是大佬提供的,并没有接触过 php)
补充一点:Vue 的 {{text}}
是 v-text
的简写,所以是不解析 HTML Dom 的,因此可以很大程度的防止注入脚本,如果使用 v-html
就要小心了
存储型
比较常见的一个场景是攻击者在社区或论坛上写下一篇包含恶意 JavaScript 代码的文章或评论,所有访问该文章或评论的用户,都会在他们的浏览器中执行这段恶意的 JavaScript 代码。
DOM 型
这个就有点 SQL 注入内味了
const btn = document.getElementById('btn');
btn.addEventListener('click', () => {
div.innerHTML = `<a href=${val}>testLink</a>`
}, false);
原本是这种输入内容拼接成一个新 Dom 的,但是如果用户输入的是 '' onclick=alert(/xss/)
构造出来的 Dom 就变成了
<a href onlick="alert(/xss/)">testLink</a>