跳到主要内容

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 的注入了

字符转义后的字符
&&amp;
<&lt;
>&gt;
"&quot;
'&#x27;
/&#x2F;

更多特殊字符转译参考 这里

常见的 XSS 分为 反射型、存储型 和 DOM 型

反射型 XSS

这种是基于请求参数的,接收了参数,不做处理还直接回显给页面就会给注入(一般容易出现在搜索页面)

http://127.0.0.1:5500/temp.html?message=<script>alert("看到这条消息表示注入成功!")</script>

发出请求时,XSS 代码出现在 url 中,作为输入提交到服务器端,服务器端解析后响应,XSS 代码随响应内容一起传回给浏览器,最后浏览器解析执行 XSS 代码。这个过程像一次反射,所以叫反射型 XSS。

下面 php 的同理(图是大佬提供的,并没有接触过 php)

01 02

补充一点: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>