彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码)

这篇具有很好参考价值的文章主要介绍了彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

前端关于网络安全看似高深莫测,其实来来回回就那么点东西,我总结一下就是 3 + 1  = 4,3个用字母描述的【分别是 XSS、CSRF、CORS】 + 一个中间人攻击。当然 CORS 同源策略是为了防止攻击的安全策略,其他的都是网络攻击。除了这 4 个前端相关的面试题,其他的都是一些不常用的小喽啰。

我将会在我的《面试题一网打尽》专栏中先逐一详细介绍,然后再来一篇文章总结,预计一共5篇文章,欢迎大家关注~

本篇文章是前端网络安全相关的第一篇文章,内容就是 CSRF 攻击。

一、准备工作

CSRF(cross-site request forgery)跨站请求伪造,是利用 iframe、img、a 、link、form等标签src、href 等不存在跨域问题的特点。CSRF 攻击的本质是利用 cookie 会在同源(同站)请求中携带发送给服务器的特点,以此来实现用户的冒充,伪造用户的请求。

1.1 拉取仓库

所以本篇文章的基础是需要一个服务端的项目,可以跟着我的这篇文章搭建自己的服务端项目。或者直接克隆我的仓库代码在这个提交上拉一个新分支,本篇文章所有的代码都是在这个提交基础上进行的。

彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码),面试题穿成串一网打尽,前端,安全,csrf

在本篇文章之前,我已经写了xss 攻击的文章,所以在你拉取我的 git 最新代码的时候,已经有很多更新的提交了,不过,无论是从上面我说的那个提交拉取新分支,还是拉取最新的代码都可以,我的仓库的所有的合并都是相互独立的。

不论你先看 XSS 教程还是先看 CSRF 教程都可以。

1.2 新增 CSRF 文件夹

彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码),面试题穿成串一网打尽,前端,安全,csrf

二、攻击条件

  1. 目标站点一定要有 CSRF 漏洞
  2. 用户要登录过目标站点,并且在浏览器上保持有该站点的登录状态
  3. 需要用户打开一个第三方站点,可以是黑客的站点,也可以是一些论坛

所以说这个攻击,有两个网站!

三、攻击类型

3.1 get 攻击:

利用 iframe、img、a 等标签发起 get 请求时,不存在跨域的问题,利用 cookie 发起跨站请求,注意是跨站,不是跨域【协议+域名+端口号都相同才不跨域、有效顶级域名 + 1 相同才不跨站】

在当前访问的网站和请求服务的网站跨站的情况下,第三方服务设置的 cookie 就称之为第三方 cookie,比如当前网站A,有一个 iframe 地址为 B,B 请求服务,B 的 cookie 对于网站 A 就是第三方 cookie,跨站的概念和 cookie 的 domain 属性设置是差不多的,

还可以利用 a 标签的 href 属性,这个本质上也是 get 请求的攻击。

跨站和跨域的关系与区别

  • 跨站 not samesite:两个域名不属于同站(域名-主机名/IP相同,协议相同)。
  • 跨域:两个域名不属于同源(域名-主机名/IP相同,端口号相同,协议相同)。

Cookie 的同源主要用于防止 CRSF,Cookie 的校验较宽松,Cookie 只关注域名,忽略协议和端口,只要两个 URL 的 eTLD+1 相同即可【顶级域名+1】,eTLD 表示有效顶级域名,注册于 Mozilla 维护的公共后缀列表(Public Suffix List)中,例如,.com、.co、.uk、.github.io 等。而 eTLD+1 则表示,有效顶级域名+二级域名,例如 taobao.com 等。

  1. www.taobao.com 和 www.baidu.com 是跨站
  2. www.a.taobao.com 和 www.b.taobao.com 是同站
  3. a.github.io和b.github.io是跨站

所以跨站即:两个 URL 顶级域名和二级域名不同就是跨站(也称第三方(Third-party)),相同则是同站本方(First-party)

跨站就一定跨域

跨域不一定跨站

3.2 post 攻击:

构建一个表单 html 中的 <form action="xxx" method="get/post"></form>,隐藏它,当用户进入页面时,自动提交这个表单,一个 form 表单可以实现 post 请求或者get 请求

好久不用原生的 form 表单了,都忘了怎么用了,在提交 form 表单之后页面会自动跳转,想要阻止自动跳转,就不能用 form 自带的 submit 功能了,需要手动使用 js 提交表单的内容,但是那样就不会发起 csrf 攻击了。

四、get 类型 CSRF 攻击

get 类型 CSRF 攻击是利用 iframe、img 等标签发起 get 请求时,不存在跨域的问题,利用 cookie 发起跨站请求。

4.1 攻击的步骤

  1. 有一个安全的网站 A(https://safe.com),用户登录的身份验证存在 cookie 中,使用 get 请求保存敏感信息(密码),如:https://safe.com/savePwd?pwd=456,在请求时会携带cookie的身份信息
  2. 用户在 A网站正常登录,useId 保存在 cookie 中,A 的服务器接收到请求后,验证 cookie 信息后,就开始更改密码。
  3. 有一个黑客,伪造了一个恶意网站B(https://danger.com),此网站有一个有一个 iframe或者img,src 的值是 https://safe.com/savePwd?pwd=456 ,黑客诱导用户打开这个网站,并且A网站还没有退出登录。【也可以用 a 标签】
  4. 用户打开 B 网站就会自动发送 更改密码的请求【因为会自动加载 iframe 里面的内容】,并且携带了A网站的 cookie。【能携带是浏览器的功能SameSite=none的功能】
  5. cookie 不区分端口号,但是区分 path
  6. B 网站只能利用 cookie,但是不能通过 document.cookie 获取 A 的 cookie,因为在B网站上获取的只能是 B 的 cookie

4.2 代码实现

根据 4.1 的流程实现代码即可。

4.2.1 安装 cookie-parser

我们主要的目的是盗用 cookie,所以要学会在 express 服务端代码中设置、获取 cookie,我们使用 cookie-parser 这个安装包

pnpm i cookie-parser

4.2.2 安装 cors

因为 cookie 是不区分端口号的,我们有一个不安全的页面 2,并且页面 2 和页面 1 是跨站的,而且跨站一定会跨域,所以我们要保证我们的服务支持跨域请求,express 中设置支持跨域的方法很简单就是使用 cors 这个 npm 包。

pnpm i cors

4.2.3 新增 csrf/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .button {
        cursor: pointer;
      }
    </style>
  </head>
  <body>
    <div class="button" onclick="login()">点击用户1登录,设置cookie</div>
   <div class="button" onclick="savePwd()">点击修改密码</div>
    <script>
      function login() {
        fetch('/getInfo').then((res) => {
          console.log('登录成功', res);
        });
      }
      function savePwd() {
        fetch('/savePwd?pwd=456').then((data) => {
            return data.json()
        }).then((res) => {
            console.log('修改结果', res)
        })
      }
    </script>
  </body>
</html>

4.2.4 新增 csrf/index2.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>恶意网站</h1>
    <a href="https://www.safe.com/savePwd?pwd=789">点击修改密码</a>
    <!--<img src="https://www.safe.com/savePwd?pwd=789"/>-->
    <!--<iframe src="https://www.safe.com/savePwd?pwd=789">点击修改密码</iframe>-->
</body>
</html>

4.2.5 新增 csrf/index.js

const express = require('express');
const path = require('path');
const cors = require('cors');
const cookieParser = require('cookie-parser');

// 第一个服务
const app = express();
// 允许跨域请求
app.use(cors());
// 解析 cookie
app.use(cookieParser());

// 安全的网页,用于用户登录
app.get('/', function (req, res) {
  res.sendFile(path.join(__dirname, '/index.html'));
});

// 安全的网页的登录接口,给网站设置 cookie
app.get('/getInfo', function (req, res) {
  res.cookie('userId', '111111', {
    expires: new Date(Date.now() + 900000),
    sameSite: 'None', // 这个是必须设置的
    secure: 'true', //只要是 truthy 值就可以
    path: '/',
  });
  res.send('end');
});
// 修改密码的接口
app.get('/savePwd', function (req, res, next) {
  const { query, cookies } = req;
  // 能获取 cookie 才返回修改成功
  if (cookies.userId) {
    res.json({
      pwd: query.pwd,
      message: '修改成功',
    });
  } else {
    res.json({
      pwd: query.pwd,
      message: '修改失败',
    });
  }
});
app.listen(3000)

// 第二个服务
// 不安全的网页,用于用 iframe/ a 标签 等 嵌入安全的网页,盗用 cookie
const app2 = express();
app2.get('/', function (req, res) {
    res.sendFile(path.join(__dirname, '/index2.html'));
  });
app2.listen(3001)


4.2.6 运行代码

npm run dev csrf

4.2.7 使用 whistle

按照官网安装即可,我们使用它的目的是

  1. 把 localhost:3000 映射到 https://www.safe.com
  2. 把 localhost:3001 映射到 https://www.danger.com

这样我们就有 2 个跨站的域名了。

安装之后 在命令行运行

w2 start

彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码),面试题穿成串一网打尽,前端,安全,csrf

然后访问http://127.0.0.1:8899/ 设置域名映射

4.2.8 结果彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码),面试题穿成串一网打尽,前端,安全,csrf

彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码),面试题穿成串一网打尽,前端,安全,csrf

这里面有一个关键点是需要设置 sameSite = none 、 secure = true

(1)chrome 浏览器默认的 sameSite = lax,所以要手动设置 sameSite = none

(2)要设置 sameSite=none,那么就必须要设置 secure =true,而设置后 secure=true之后, 只能通过https 请求携带cookie了,这也是我们要使用域名代理的原因。

参考这篇文章

 4.2.9 提交代码

五、防御攻击

5.1 进行同源检测

服务端进行同源检测【类似非简单请求的同源策略,get请求不会跨域】,在接收到请求之后,判断 origin 或 referer 的值是否是安全的【如果是在恶意网站发起的请求,origin、referer 会显示恶意网站,如下图】【优先判断 origin】

彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码),面试题穿成串一网打尽,前端,安全,csrf

Origin 或 Referer 的关系和区别

  1. Origin 和 Referer 都可以服务端用来做来源验证,来防止 csrf 攻击,都是浏览器自动带在请求头的
  2. 但是,可以通过 Referrer Policy 来禁止请求携带 referer,【请求头增加字段 Referrer-Policy: no-referrer/origin等】所以服务器验证请求中的 referer 不太可靠
  3. 因此标准委员会又制定了 origin 属性,在一些重要的场合,比如通过 XMLHttpRequest 、fetch 发起跨站请求时,都会带上 origin
  4. Origin 包含协议、主机和端口,不包含路径
  5. Referer 只包含了源页面的 URI,包含路径,而且该字段可能在用户隐私方面存在一些敏感性问题。
  6. Origin 主要用于跨站请求的安全性检查,而 Referer 则是提供请求来源信息的通用手段,可用于日志记录、统计分析等。
  7. 所以对于 csrf 来源验证,服务器的策略是有优先判断 origin;如果请求头中没有包含 origin 属性 ,再根据实际情况判断是否使用 referer 

Origin:

  • 用途: Origin 请求头用于表示一个 URI 的起源,包括协议、主机和端口。
  • 格式: Origin: <scheme>://<host>:<port>
  • 安全性: Origin 是由浏览器自动设置的,它通常用于跨站请求的安全性检查。在跨域请求时,浏览器会检查目标服务器是否允许来自特定 Origin 的请求,如果不允许,浏览器会阻止此类请求。
  • origin的值不能手动修改,不能手动设置都是浏览器自动的

Referer:

  • 用途: Referer 请求头用于表示请求的来源页面的 URI。它指明了用户是从哪个页面跳转或提交请求的。
  • 格式: Referer: <origin>
  • 安全性: Referer 是由浏览器设置的,但它不像 Origin 那样用于强制安全性检查。虽然 Referer 也可以在某些场景下用于防范 CSRF 攻击,但它的值可由用户和服务端控制,不是可靠的安全控制手段。
  • 可以手动修改document.write('<meta name="referrer" content="http://example.com">')但是会收到安全限制,不建议

 5.1.1 修改 index.js

现在我们来根据请求的 referer 来进行同源检测,我们的例子中使用的是a 标签,浏览器不会自动携带 origin , 所以我们只能根据 referer 判断了。

彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码),面试题穿成串一网打尽,前端,安全,csrf

这里面有一个关于 express 的知识,就是使用 req.get 获取http的请求头 

5.1.2 运行

这回我们再点击恶意网站的链接跳转,就会显示失败

彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码),面试题穿成串一网打尽,前端,安全,csrf

 彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码),面试题穿成串一网打尽,前端,安全,csrf

5.2 使用 CSRF token 验证

其实本质就是每一个请求都加一个 token 验证,在该密码的接口中带上这个 token,由服务器进行验证,验证通过才进行下一步操作。token 的设置主要有两种方式

  1. 页面加载时硬编码在 html 中【要用服务端渲染,服务端生成token,嵌在html中,比如form表单的隐藏字段中】【这种方法的问题是,每一次请求都需要加上这个 token,并且如果加上了 cdn 负载均衡服务器(分布式服务器),每个服务器的session 无法同步,那就保证token的正确了】。很多教程中都是说的用这种服务端渲染的硬编码!但是我们常用的vue等框架不是ssr的,所以看的云里雾里,如果是用的nuxt等框架就可以实现这种逻辑了
  2. 前端动态获取 CSRF 令牌,用新的接口获取 token【要保证这个token获取接口是安全且身份验证和授权,不容易受到 CSRF 攻击】这种方式通常被称为 "CSRF Token Refresh",其中前端可以通过新接口请求一个最新的 CSRF 令牌,并将其嵌入到后续的请求中。这可以提高安全性,特别是对于那些用户会话可能变得很长时间的应用程序,因为 CSRF 令牌的有效性通常是有限的,但是这样的话,逻辑循环了,要怎么保证获取 token 的接口不会受到 CSRF攻击呢。

5.3 对cookie进行双重验证

cookie 进行双重验证是指,在第一次访问服务器时,设置一个 cookie,后续的请求都需要把这个cookie 取出来添加到参数 URL 中,然后服务器需要对 cookie 的数据和 URL 上的参数进行比较。恶意网站无法获取 cookie 自然就无法拼出正确的 URL 了。这种方法不涉及分布式访问的问题,但是如果存在 XSS 漏洞,就会失效,这种方法不能做到子域名的隔离。

5.3.1 修改 index.js

彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码),面试题穿成串一网打尽,前端,安全,csrf

5.3.2 修改 index.html

彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码),面试题穿成串一网打尽,前端,安全,csrf这样修改之后,在恶意网站就无法请求成功了,因为恶意网站请求的地址没变!因为我们没有修改 index2.html

彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码),面试题穿成串一网打尽,前端,安全,csrf

5.3.3 提交代码 

5.4 cookie 设置 SameSite

在服务端设置 cookie 属性的时候设置 SameSite 限制cookie不能被第三方使用,这个是服务端设置的。samesite 取值 none/Strict/Lax,默认为 Lax,chrome 浏览器的开发者工具中显示的空,其实就是Lax。

严格模式 Strict,cookie 在任何情况下都不可能作为第三方cookie使用;

宽松模式下 Lax,cookie可以被提交get表单、会发生页面跳转的请求使用a 标签/link标签,但是如果在第三方中使用post方法或者使用 img/iframe 等标签加载 URL 这些场景不会携带 cookie。

将 Samesite 设为 Lax ,这种模式称为宽松模式,也是目前浏览器中的默认值。如果这个请求是个 GET 请求,并且这个请求改变了当前页面或者打开了新的页面,那么这个 cookie 可以作为第三方 cookie【和本篇文章 4.2 中的例子一样】,其余情况下都不能作为第三方 cookie。使用这种方法的缺点是,因为它不支持子域,所以子域没有办法与主域共享登录信息,每次转入子域的网站,都需要重新登录。还有一个问题就是它的兼容性不够好。

5.4.1 设置 sameSite

彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码),面试题穿成串一网打尽,前端,安全,csrf

因为chrome浏览器默认的 cookie 的 samesite 值是 lax,虽然在开发者工具中显示的是空,所以如果我们模拟的 demo 中使用的是 firame 或者 src 就不会跨站携带 cookie.。要想我们的demo生效需要在服务端设置 cookie的时候同时设置 samesite=none & secure=true。但是 srcure 只有在https请求中可以设置成功,所以我们需要使用代理工具,将本地的ip地址映射成https:的域名,使用whistle工具很方便 w2 start即可

经过这样设置,基本上可以杜绝所有的 CSRF 攻击了。 

总结

模拟 CSRF 攻击的代码已经完成,我的仓库地址如下,欢迎查看

yangjihong2113/learn-express

内容较多,难免疏漏,如有问题,欢迎指正。

这是一系列的文章,我已经总结完关于 XSS 攻击的内容,关于网络安全的内容还有 CORS 和中间人攻击的内容没有总结,持续更新中,欢迎关注。文章来源地址https://www.toymoban.com/news/detail-773596.html

到了这里,关于彻底理解前端安全面试题(2)—— CSRF 攻击,跨站请求伪造攻击详解,建议收藏(含源码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 网络安全面试题汇总

    一眨眼2023年已经过去一大半,不知道大家有没有找到心仪的工作。作为一个安全老鸟,工作这么多年,面试过很多人也出过很多面试题目,也在网上收集了各类关于渗透面试题目,里面有我对一些问题的见解,希望能对大家有所帮助。 1.1、什么是 SQL 注入攻击?如何防止 S

    2024年02月10日
    浏览(59)
  • 2023秋招,网络安全面试题

     Hello,各位小伙伴,我作为一名网络安全工程师曾经在秋招中斩获🔟+个offer🌼,并在国内知名互联网公司任职过的职场老油条,希望可以将我的面试的网络安全大厂面试题和好运分享给大家~ 转眼2023年秋招已经到了金银🔟的关键阶段,宝子们简历抓紧准备投递起来呀,冲冲

    2024年02月15日
    浏览(48)
  • 移动安全面试题—调试&反调试

    Android反调试的几种手段 检测 TracerPid:在 /proc/self/status 文件中,TracerPid 字段表示调试进程的 PID。如果该值非零,则意味着当前进程被调试。 对抗方法:使用内核模块或 Xposed 插件拦截对 /proc/self/status 的读取,将 TracerPid 字段设置为 0。 检测调试端口:/proc/self/maps 文件中包含

    2024年01月19日
    浏览(40)
  • 网络安全面试题汇总(附答案)

    作为从业多年的网络安全工程师,我深知在面试过程中面试官所关注的重点及考察的技能点。网络安全作为当前信息技术领域中非常重要的一部分,对于每一个从事网络安全工作的人员来说,不仅需要掌握一定的技术能力,更需要具备全面的综合素质。 在我职业发展的过程中

    2024年02月13日
    浏览(53)
  • 网络安全书籍推荐+网络安全面试题合集

    一、计算机基础 《深入理解计算机系统》 《鸟哥的Linux私房菜》 《TCP/IP详解(卷1:协议)》 《HTTP权威指南》 《Wireshark数据包分析实战》 《Wireshark网络分析的艺术》 《Wireshark网络分析就这么简单》 二、网络渗透 《白帽子讲Web安全》 《Web安全深度剖析》 《SQL注入天书》

    2023年04月25日
    浏览(48)
  • 史上最全网络安全面试题+答案

    1、什么是SQL注入攻击 前端代码未被解析被代入到数据库导致数据库报错 2、什么是XSS攻击 跨站脚本攻击 在网页中嵌入客户端恶意脚本,常用s语言,也会用其他脚本语言 属于客户端攻击,受害者是用户,网站管理员也属于用户,攻击者一般也是靠管理员身份作为跳板 3、什么

    2024年02月13日
    浏览(54)
  • 史上最全网络安全面试题汇总

    最近有不少小伙伴跑来咨询: 想找网络安全工作,应该要怎么进行技术面试准备? 工作不到 2 年,想跳槽看下机会,有没有相关的面试题呢? 为了更好地帮助大家高薪就业,今天就给大家分享一份网络安全工程师面试题,希望它们能够帮助大家在面试中,少走一些弯路、更

    2024年02月07日
    浏览(55)
  • 2023网络安全面试题(附答案)+面经

    随着国家政策的扶持,网络安全行业也越来越为大众所熟知,相应的想要进入到网络安全行业的人也越来越多,为了拿到心仪的Offer之外,除了学好网络安全知识以外,还要应对好企业的面试。 所以在这里我归纳总结了一些网络安全方面的常见面试题,希望能对大家有所帮助

    2023年04月09日
    浏览(53)
  • 500道网络安全面试题集锦(附答案)

    本篇文章内容为网络安全各个方向涉及的面试题,但是无论如何都无法覆盖所有的面试问题,更多的还是希望由点达面,查漏补缺,然后祝各位前程似锦,都能找到自己满意的工作!   攻击者通过在web界面中嵌入恶意脚本(通常为js代码),造成用户在浏览网页时,控制用户

    2024年02月15日
    浏览(56)
  • 网络安全面试题整理——甲方类(含答案解析)

    以下是对目前部分热门的甲方面试/笔试题(偏管理和运营)的总结和思考,希望可以帮助到正在准备甲方面试的你们; 愿我们披荆斩棘,享受前进路上的每一处风景 1. 简述一下目前主流编程语言的相关漏洞 答:这个题的相关思路就是聊一聊目前主流语言的漏洞,你可以从两

    2024年02月08日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包