网站首页 > 技术文章 正文
我是前端西瓜哥,今天来学习 CSRF。
CSRF,跨站请求伪造,英文全称为 Cross-site request forgery。也可称为 XSRF。
CSRF 攻击 利用的是用户对浏览器的信任。
当我们成功登录一个网站时,其实浏览器在这个网站域名下保存好了 登录凭证,通常通过 cookies 保存。
登录后,我们的在当前域名下发起请求就会带上 cookie,服务器就通过它来确定你对应哪个用户,允许你去执行一些涉及到个人隐私的操作。
浏览器的一个机制:访问了一个 url,会带上对应域名的 Cookies,这就给了 CSRF 可乘之机。
利用 CSRF,攻击者可以欺骗浏览器,让你用特定网站的账号,发送一些请求(比如转账)。
例子
攻击者设计了一个钓鱼网站。网站很简单,里面有一个 form 表单:
- 提交的 url 为你登录的一个银行网站的地址;
- 使用 POST 请求(解决浏览器地址栏访问只能为 GET 请求的局限);
- 预填充转账对象账号、金额等信息;
- 直接用脚本触发提交操作;
<form method="POST" action="http://a-bank.com">
<input type="text" name="toAccountId">
<input type="text" name="acount">
<input type="submit" name="submit" value="Submit">
</form>
<script>
const form = document.querySelector('form');
form.submit();
</script>
这样,攻击者会通过各种方式诱导你访问它的钓鱼网站。
一旦我们访问了攻击者的网站,模拟你自己在银行网站点击 “转账” 按钮的行为,发送转账请求。
当然前提是你在这个银行网站处于登录状态。
不过也不用担心,银行不会犯这么低级的错误,会有非常多的防御措施,可能还要你输入手机验证码。这只是一个用烂的例子而已。
CSRF 的一些防御方式
校验 token
我们可以让请求带上一个额外的 csrf_token,来确保请求是通过网站的前端页面发送的。
这个 csrf_token 由服务器颁发,不要放到 cookie 里,要通过其他方式提供给网站的前端页面,一种方式是放到 DOM 上。
前端请求时就会从 DOM 找出这个 csrf_token,作为一个参数带上,让服务端校验。
为了防止攻击者伪造 csrf_token,我们要确保 csrf_token 和用户凭证有关联,可以考虑对用户凭证做密钥哈希,攻击者没有密钥,就无法伪造。
使用严格的 SameSite
Cookie 有一个 SameSite 属性,设置为严格模式(非 none 值),可以让其他网站的中跨域请求不带上 Cookie。
通过 Referer 判断
如果在网站中发送的请求,HTTP头字段 Referer 中的域名就是当前网站。如果是其他网站发起的请求,Referer 就是这个网站域名。
服务端可以利用这个 Referer 判断请求是否在网站页面中发起的。
此外还可以利用 Origin 头字段,它通常在跨域请求时会携带上。
但 Referer 并不完全可靠,在一些老旧的浏览器在实现上可能会有一些问题,有丢失的可能。
不使用 Cookies
将用户凭证保存到 localStorage 本地缓存中,在网站中发送 Ajax 请求时,手动从中取出放到请求头字段中。这样其他网站进行 CSRF 攻击时,自定携带的 cookie 就没有我们的用户凭证了。
看起来没啥大问题。有个小问题,就是好像不能利用 cookie 的 http-only 防 XSS 攻击了。
人机校验
加一个短信校验、邮箱校验、谷歌万恶的九宫格什么的,确保是一个人在尝试发这个请求。
可以吊打所有攻击,缺点是用户体验不太好。
结尾
CSRF 跨站请求伪造,利用的是人们对浏览器的信任(访问网站会带上 cookie)。当你在网站 A 登录了,攻击者分析网站 A 的请求结构,进行构造好一些请求,诱导用户点击然后真正发起该请求,来实现攻击。
要防范 CSRF,需要开发者在开发中做好各种防御措施。
我是前端西瓜哥,关注我,学习更多前端知识。
- 上一篇: 大批量接口请求的前端优化
- 下一篇: 最简单的 6 种防止数据重复提交的方法!(干货)
猜你喜欢
- 2025-01-02 前后端数据交互(六)——ajax 、fetch 和 axios 优缺点及比较
- 2025-01-02 前端报504错误如何定位
- 2025-01-02 测试提了个bug,为什么你多了个options请求?
- 2025-01-02 如果用户觉得 web 应用反应卡顿, 主要从哪几个方面来排查?
- 2025-01-02 Vue短文:如何在HTTP请求时传递自定义头部
- 2025-01-02 前端小伙伴,axios 是如何封装 HTTP 请求的?(看完会了吗)
- 2025-01-02 SpringMVC实现原理之DispatcherServlet处理请求的过程
- 2025-01-02 Background Sync出世!前端离线请求火起来?
- 2025-01-02 最简单的 6 种防止数据重复提交的方法!(干货)
- 2025-01-02 大批量接口请求的前端优化
你 发表评论:
欢迎- 577℃几个Oracle空值处理函数 oracle处理null值的函数
- 573℃Oracle分析函数之Lag和Lead()使用
- 559℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 558℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 554℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 543℃【数据统计分析】详解Oracle分组函数之CUBE
- 531℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 527℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端懒加载 (49)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle的函数 (57)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)