《白帽子讲 Web 安全》之跨站请求伪造
引言
在数字化时代,网络已深度融入人们生活的方方面面,Web 应用如雨后春笋般蓬勃发展,为人们提供着便捷高效的服务。然而,繁荣的背后却潜藏着诸多安全隐患,跨站请求伪造(CSRF)便是其中极为隐蔽且危险的一种。它如同隐匿在暗处的黑客,趁用户在 Web 世界中畅游时,悄然发动攻击,严重威胁着用户的账户安全以及 Web 应用的稳定与信誉。吴翰清在《白帽子讲 Web 安全》中对其进行了深入剖析,接下来,让我们一同揭开 CSRF 的神秘面纱,深入剖析其原理、攻击手段与防御策略。
一、CSRF 简介
定义
CSRF,即 Cross Site Request Forgery 的缩写,是一种常见且隐蔽的 Web 攻击手段。攻击者精心设计诱导策略,使已登录目标网站的用户访问恶意网站,进而利用用户在目标网站的身份权限,在用户毫不知情的情况下,在目标网站执行非用户本意的操作。这一过程中,攻击者无需获取用户的登录凭证,仅借助浏览器的特性就可达成攻击目的。
示例
以社交网站为例,假设该网站的 “添加关注” 功能通过向http://example.com/follow?id=USERID发送 GET 请求来实现。当用户已登录example.com,此时若访问了恶意网站,而恶意网站中嵌入了<img src="http://example.com/follow?id=1234"/>。由于浏览器会自动加载图片,便会向该链接发送 GET 请求。又因为用户已登录example.com,浏览器会自动携带该网站的 Cookie,目标网站基于 Cookie 验证用户身份,将此请求视为用户的正常操作,最终导致用户在不知情的状况下关注了 UID 为 1234 的用户。
二、CSRF 详解
1.本质
CSRF 攻击成功的关键在于巧妙利用浏览器自动携带用户已登录网站 Cookie 的特性。当用户访问恶意网站时,恶意网站精心构造的请求会借助浏览器的自动行为,以用户身份被发送到目标网站。目标网站仅依据请求中携带的 Cookie 来验证用户身份,却无法判断该请求究竟是用户的真实意愿,还是攻击者伪造的。这种机制使得攻击者能够在用户不知情的情况下,在目标网站执行各种操作,如转账、修改用户信息等,给用户带来极大的损失。
2.GET 和 POST 请求
GET 请求
攻击者通常通过构造包含恶意操作的 URL 发起 GET 请求攻击。在恶意网站中设置一个图片链接,其src属性为目标网站的操作 URL,是常见的攻击手段。当用户访问恶意网站时,浏览器自动向该 URL 发送 GET 请求,恶意操作得以执行。
假设目标网站有一个删除用户评论的操作,对应的 URL 为http://example.com/delete_comment?id=COMMENTID。攻击者在恶意网站嵌入<img src="http://example.com/delete_comment?id=5678"/>,若用户已登录example.com且该评论属于此用户,那么用户在访问恶意网站时,浏览器会自动发送请求,导致用户的评论被删除。
POST 请求
对于 POST 请求,攻击者常采用自动提交表单的方式。在恶意网站中隐藏一个自动提交的表单,表单的action属性为目标网站的操作 URL。当用户访问恶意网站时,该表单会自动提交,以用户身份执行 POST 请求。
比如,目标网站有一个修改用户密码的功能,通过 POST 请求将新密码发送到http://example.com/change_password。攻击者在恶意网站创建如下表单:
<form action="http://example.com/change_password" method="post" style="display:none;"><input type="hidden" name="new_password" value="attacker_password"></form><script>document.forms[0].submit();</script>
当用户登录example.com后访问该恶意网站,表单会自动提交,用户的密码就被修改为攻击者设置的密码。
3.CSRF 蠕虫
CSRF 蠕虫是一种极其危险的 CSRF 攻击形式,其危害性远超普通的 CSRF 攻击。攻击者利用网站的 CSRF 漏洞,结合 XSS 攻击手段(例如通过 XSS 获取用户的好友列表),实现恶意操作的自动传播。举例来说,攻击者在用户页面自动发布包含恶意链接的内容,当其他用户访问该页面时,就会触发 CSRF 攻击。
假设某社交平台存在 CSRF 漏洞,攻击者利用 XSS 在用户 A 的页面发布一条动态,内容为<img src="http://example.com/send_spam?message=恶意广告内容&to=USERID"/>,其中USERID通过 XSS 获取的用户 A 的好友列表动态生成。当用户 A 的好友浏览其页面时,浏览器会自动向目标网站发送请求,以该好友的身份向其他用户发送恶意广告,如此循环,攻击范围像滚雪球一样迅速扩大,对整个社交平台的用户体验和安全造成严重影响。
三、防御 CSRF 攻击
1.验证码
在用户进行关键操作时,要求输入验证码是一种有效的防御 CSRF 攻击的手段。由于验证码只有用户可见,攻击者无法获取并伪造,这就确保了请求是用户的真实操作。
例如,在进行转账操作时,银行网站要求用户输入图形验证码或短信验证码。用户需要在页面上查看并输入验证码,只有输入正确才能完成转账。然而,频繁要求用户输入验证码会极大地影响用户体验,导致用户在使用过程中感到繁琐和不便,所以在实际应用中,需要在安全性和用户体验之间找到平衡,不能过度依赖验证码。
2.Referer 校验
通过检查 HTTP 请求中的 Referer 字段,Web 应用可以判断请求的来源是否合法。正常情况下,用户在目标网站内部进行操作时,请求的 Referer 应该是目标网站的内部页面。若 Referer 字段显示请求来自恶意网站,那么服务器可以拒绝该请求。
例如,用户在example.com进行修改个人信息的操作,该操作的请求 Referer 应该是example.com的相关页面,如个人设置页面。如果服务器接收到的请求 Referer 为MALICIOUS.COM,则很可能是 CSRF 攻击,服务器可直接拒绝。但需要注意的是,Referer 字段并非完全可靠。一方面,攻击者可以通过技术手段伪造 Referer 字段,使其看起来像是来自合法的来源;另一方面,在某些特殊情况下,如从 HTTPS 页面跳转到 HTTP 页面时,由于安全策略等原因,Referer 字段可能为空。因此,仅依靠 Referer 校验并不能完全确保应用免受 CSRF 攻击,它只能作为一种辅助的防御手段。
3.Anti - CSRF Token
原理
Anti - CSRF Token 是目前防御 CSRF 攻击最为常用且有效的方法之一。在用户登录或页面加载时,服务器会生成一个随机的 Token,并将其存储在用户的 Session 中。同时,服务器通过隐藏表单字段或 HTTP 头的方式将 Token 发送给客户端。当客户端发起请求时,会将 Token 包含在请求中。服务器在接收到请求后,会验证 Token 的有效性和一致性,即检查请求中的 Token 与存储在 Session 中的 Token 是否匹配。若两者不匹配,服务器将拒绝请求,从而有效阻止 CSRF 攻击。
使用原则
为了确保 Anti - CSRF Token 的有效性,需要遵循一些重要原则。首先,Token 要足够随机且难以预测,避免使用固定值或可猜测的值。
例如,使用高强度的加密算法生成 Token,保证其具有足够的长度和复杂度。其次,在不同页面或操作中,Token 应保持唯一性,防止攻击者通过复用 Token 来绕过防御机制。最后,服务器端要正确验证 Token,防止重放攻击等。例如,在验证 Token 后,及时将其从 Session 中移除或标记为已使用,确保同一个 Token 不会被多次使用。
示例
在 HTML 表单中添加一个隐藏的input字段来存储 Token 是常见的做法。例如:
<form action="http://example.com/do_something" method="post"><input type="hidden" name="csrf_token" value="随机生成的Token值"/><!-- 其他表单字段 --><input type="submit" value="提交"></form>
服务器端在处理请求时,会获取该 Token,并与存储在 Session 中的 Token 进行比对。以 Python 的 Flask 框架为例,代码如下:
from flask import Flask, request, sessionapp = Flask(__name__)app.secret_key = 'your_secret_key'@app.route('/generate_token')def generate_token():import secretstoken = secrets.token_hex(16)session['csrf_token'] = tokenreturn token@app.route('/do_something', methods=['POST'])def do_something():if 'csrf_token' not in session or 'csrf_token' not in request.form:return 'CSRF验证失败', 403if session['csrf_token'] != request.form['csrf_token']:return 'CSRF验证失败', 403# 处理正常业务逻辑return '操作成功'
在上述代码中,/generate_token路由用于生成 Token 并存储在 Session 中,/do_something路由在处理 POST 请求时,会验证请求中的 Token 与 Session 中的 Token 是否一致,若一致则处理正常业务逻辑,否则返回 CSRF 验证失败的提示。
四、相关要点
1.与 XSS 的关联
CSRF 和 XSS 作为 Web 安全中的两大重要问题,它们之间存在着紧密的关联。XSS 攻击可用于获取用户的 Cookie 等敏感信息,而这些信息正是 CSRF 攻击所依赖的。攻击者通过 XSS 将恶意脚本注入到用户浏览的页面中,当用户访问该页面时,恶意脚本会获取用户的 Cookie,并将其发送给攻击者。攻击者利用获取到的 Cookie,结合 CSRF 攻击手段,就可以以用户的身份在目标网站执行各种操作。另一方面,CSRF 攻击也可能结合 XSS 来扩大攻击范围和影响。例如,通过 CSRF 攻击在用户页面植入 XSS 代码,当其他用户访问该页面时,就会触发 XSS 攻击,进一步传播恶意代码,造成更大的危害。
2.常见应用场景
许多 Web 应用都存在 CSRF 风险,尤其是涉及用户资金交易、个人信息修改、关注点赞等操作的功能。在金融类应用中,若存在 CSRF 漏洞,攻击者可能诱导用户在已登录状态下执行转账操作,导致用户资金损失。在社交平台上,攻击者可能利用 CSRF 漏洞,以用户的名义发布不良信息、修改用户个人资料或关注恶意账号等。因此,开发者在开发 Web 应用时,应高度重视这些关键功能的安全性,采取有效的防御措施,防止 CSRF 攻击的发生。
3.不同框架的应对
不同的 Web 开发框架,如 Flask、Django、Spring 等,通常都提供了相应的 CSRF 防护机制或扩展。以 Flask 框架为例,可通过Flask - WTF扩展来实现 CSRF 防护。使用时,只需在应用中初始化扩展,并在表单中添加 CSRF 保护字段即可。例如:
from flask import Flaskfrom flask_wtf.csrf import CSRFProtectapp = Flask(__name__)app.secret_key = 'your_secret_key'csrf = CSRFProtect(app)# 其他路由和视图函数
在 HTML 表单中,使用Flask - WTF生成 CSRF 保护字段:
{{ form.csrf_token }}
通过这种方式,开发者可以利用框架提供的工具轻松增强应用的安全性。但需要注意的是,在使用这些工具时,要正确配置和使用,仔细阅读框架文档,避免因配置不当而出现漏洞,确保应用能够有效抵御 CSRF 攻击。
总结
跨站请求伪造(CSRF)是一个复杂且不断演变的 Web 安全问题。无论是开发者、安全研究人员还是普通用户,都需要持续关注其发展动态。开发者要将安全意识贯穿于整个开发周期,不仅要熟练运用现有的防御技术,还要积极探索新的安全防护手段;安全研究人员需深入研究攻击者的新手法,为安全防护提供理论支持;而普通用户则要提高自身的安全意识,谨慎点击不明链接,避免访问可疑网站。只有各方共同努力,才能在这场与 CSRF 攻击的较量中取得胜利,保障 Web 应用的安全和用户的权益。
喜欢就点点赞和评论关注一起进步呗
相关文章:
《白帽子讲 Web 安全》之跨站请求伪造
引言 在数字化时代,网络已深度融入人们生活的方方面面,Web 应用如雨后春笋般蓬勃发展,为人们提供着便捷高效的服务。然而,繁荣的背后却潜藏着诸多安全隐患,跨站请求伪造(CSRF)便是其中极为隐蔽…...
K8S学习之基础五十:k8s中pod时区问题并通过kibana查看日志
k8s中pod默认时区不是中国的,挂载一个时区可以解决 vi pod.yaml apiVersion: v1 kind: Pod metadata:name: counter spec:containers:- name: countimage: 172.16.80.140/busybox/busybox:latestimagePullPolicy: IfNotPresentargs: [/bin/sh,-c,i0;while true;do …...
nginx代理前端请求
一,项目配置 我在 ip 为 192.168.31.177 的机器上使用 vue3 开发前端项目,项目中使用 axios 调用后端接口。 这是 axios 的配置: import axios from axios;const request axios.create({baseURL: http://192.168.31.177:8001,// 设置请求…...
LibVLC —— 《基于Qt的LibVLC专业开发技术》视频教程
🔔 LibVLC/VLC 相关技术、疑难杂症文章合集(掌握后可自封大侠 ⓿_⓿)(记得收藏,持续更新中…) 《基于Qt的LibVLC专业开发技术》课程视频,(CSDN课程主页、51CTO课程主页) 适合具有一些C++/Qt编程基础,想要进一步提高或涉足音视频行业的。本课程分7章节,共计35小节。…...
Android生态大变革,谷歌调整开源政策,核心开发不再公开
“开源”这个词曾经是Android的护城河,如今却成了谷歌的烫手山芋。最近谷歌宣布调整Android的开源政策,核心开发将全面转向私有分支。翻译成人话就是:以后Android的核心更新,不再公开共享了。 这操作不就是开源变节吗,…...
Android Gradle 插件问题:The option ‘android.useDeprecatedNdk‘ is deprecated.
问题与处理策略 问题描述 在 Android 项目中,报如下警告 The option android.useDeprecatedNdk is deprecated. The current default is false. It has been removed from the current version of the Android Gradle plugin. NdkCompile is no longer supported…...
【web应用安全】关于web应用安全的几个主要问题的思考
文章目录 防重放攻击1. **Token机制(一次性令牌)**2. **时间戳 超时验证**3. **Nonce(一次性随机数)**4. **请求签名(如HMAC)**5. **HTTPS 安全Cookie**6. **幂等性设计****综合防御策略建议****注意事项…...
Git 基础入门:从概念到实践的版本控制指南
一、Git 核心概念解析 1. 仓库(Repository) Git 的核心存储单元,包含项目所有文件及其完整历史记录。分为本地仓库(开发者本地副本)和远程仓库(如 GitHub、GitLab 等云端存储),支持…...
银行分布式新核心的部署架构(两地三中心)
银行的核心系统对可用性和性能要求均非常严苛,所以一般都采用两地三中心部署模式。 其中: 同城两个主数据中心各自部署一套热备,平时两个中心同时在线提供服务,进行负载均衡假如其中一个数据中心出现异常,则由另外一个…...
Spring 及 Spring Boot 条件化注解(15个)完整列表及示例
Spring 及 Spring Boot 条件化注解完整列表及示例 1. 所有条件化注解列表 Spring 和 Spring Boot 提供了以下条件化注解(共 15 个),用于在配置类或方法上实现条件化注册 Bean 或配置: 注解名称作用来源框架Conditional自定义条件…...
MantisBT在Windows10上安装部署详细步骤
MantisBT 是一款基于 Web 的开源缺陷跟踪系统,以下是在 Windows 10 上安装部署 MantisBT 的详细步骤: 1. 安装必要的环境 MantisBT 是一个基于 PHP 的 Web 应用程序,因此需要安装 Web 服务器(如 Apache)、PHP 和数据…...
9.4分漏洞!Next.js Middleware鉴权绕过漏洞安全风险通告
今日,亚信安全CERT监控到安全社区研究人员发布安全通告,Next.js 存在一个授权绕过漏洞,编号为 CVE-2025-29927。攻击者可能通过发送精心构造的 x-middleware-subrequest 请求头绕过中间件安全控制,从而在未授权的情况下访问受保护…...
处理json,将接口返回的数据转成list<T>,和几个时间处理方法的工具类
接口或者其他方式返回json格式,也可以直接处理里边只有list的json数据 //第一种json格式,包含分页信息 {"code": 200,"msg": null,"data": {"records": [{"风速": "0.0","电流"…...
OpenCV图像拼接(5)图像拼接模块的用于创建权重图函数createWeightMap()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::detail::createWeightMap 是 OpenCV 库中用于图像拼接模块的一个函数,主要用于创建权重图。这个权重图在图像拼接过程中扮演着重…...
linux 运行脚本命令区别
文章目录 chmod 赋予权限运行sh script.sh适用场景 bash script.shsource 或 . 脚本 chmod 赋予权限运行 chmod x script.sh # 赋予执行权限 ./script.sh # 直接执行创建新的子进程,不会影响当前 shell 的环境变量。#!(Shebang) 指…...
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置
噩梦终结:Flutter 配安卓、鸿蒙、iOS 真机调试环境 问题背景 很多开发者在配置 Flutter 项目环境时遇到困难,尤其是在处理 Android、鸿蒙和 iOS 真机调试环境时。卓伊凡最近接手了一个项目,发现很多“专业程序员”在环境搭建上花费了大量时…...
C++11QT复习 (六)
类型转换函数和类域 **Day6-3 类型转换函数和类域****1. 类型转换函数(Type Conversion Functions)****1.1 概述****1.2 代码示例****1.3 关键优化** **2. 类域(Class Scope)****2.1 作用域 vs 可见域****2.2 代码示例****2.3 关键…...
区块链技术在投票系统中的应用:安全、透明与去中心化
区块链技术在投票系统中的应用:安全、透明与去中心化 【引言】 近年来,电子投票系统因其便捷性受到广泛关注,但随之而来的安全问题也屡见不鲜,如选票篡改、重复投票、数据泄露等。如何确保投票的公平性、透明度和安全性? 区块链技术或许是解决方案之一! 区块链的 去中…...
CTF类题目复现总结-[MRCTF2020]ezmisc 1
一、题目地址 https://buuoj.cn/challenges#[MRCTF2020]ezmisc二、复现步骤 1、下载附件,得到一张图片; 2、利用010 Editor打开图片,提示CRC值校验错误,flag.png应该是宽和高被修改了,导致flag被隐藏掉;…...
MetInfo6.0.0目录遍历漏洞原理分析
所需进行代码审计的文件路径: C:\phpStudy\WWW\MetInfo6.0.0\include\thumb.php C:\phpStudy\WWW\MetInfo6.0.0\app\system\entrance.php C:\phpStudy\WWW\MetInfo6.0.0\app\system\include\class\load.class.php C:\phpStudy\WWW\MetInfo6.0.0\app\system\include…...
linux打包前端vue,后端springboot项目
第一步先对整个项目进行通过maven进行clean在进行compile 第二步直接进行打包package和install都可以 第三部把对应的jar放到服务器上 把jar包放到服务器上某个地址下,然后cd到这个目录下,然后执行命令 nohup java -jar ruoyi-admin.jar > springbo…...
Elasticsearch:使用 AI SDK 和 Elastic 构建 AI 代理
作者:来自 Elastic Carly Richmond 你是否经常听到 AI 代理(AI agents)这个词,但不太确定它们是什么,或者如何在 TypeScript(或 JavaScript)中构建一个?跟我一起深入了解 AI 代理的概…...
SQLAlchemy 支持特殊字符
postgresql 实践 pydantic 实践(一)基础 pydantic 实践(二)数据校验 SQLAlchemy 介绍与实践 SQLAlchemy 支持特殊字符 SQLAlchemy 支持特殊字符 1. 字符集介绍分析2. MySQL 支持特殊字符2.1. 更新 MySQL 字符集为 utf8mb42.2 更新…...
Docker 快速入门指南
Docker 快速入门指南 1. Docker 常用指令 Docker 是一个轻量级的容器化平台,可以帮助开发者快速构建、测试和部署应用程序。以下是一些常用的 Docker 命令。 1.1 镜像管理 # 搜索镜像 docker search <image_name># 拉取镜像 docker pull <image_name>…...
计算机网络 - OSI 七层模型
OSI 七层模型 OSI(Open System Interconnection,开放系统互联)模型由 ISO(国际标准化组织) 制定,目的是为不同计算机网络系统之间的通信提供一个标准化的框架。它将网络通信划分为 七个层次,每…...
如何调整yarn.nodemanager.vmem-pmem-ratio参数?
调整 yarn.nodemanager.vmem-pmem-ratio 参数的步骤如下: 1. 打开 YARN 配置文件 找到 yarn-site.xml 文件,该文件通常位于 Hadoop 配置目录中,例如 /etc/hadoop/conf 或 /opt/module/hadoop-3.1.3/etc/hadoop。 2. 找到并修改 yarn.nodemana…...
自顶向下学习K8S--部署Agones
本文在本人博客,原文地址:http://viogami.tech/index.php/blog/346/ 我是gopher,离不开云原生,自然也逃不了理解docker和K8S这俩。今天抽空想玩下agones,进而对K8S有实践性的理解。 学一个新事物从底层理论学肯定是最…...
unity中Xcharts图表鼠标悬浮表现异常
鼠标悬浮在面板附近,只显示单独的一个项目 而且无论鼠标如何移动,根本没有效果。 解决方案: 需要在对应的Canvas上绑定主相机才可以 鼠标移动到项目上就有信息展示了...
2025年最新自动化/控制保研夏令营预推免面试真题分享(东南大学苏州校区/华东理工/南航/天大)
笔者来2021级本科自动化专业,以下部分将介绍我在夏令营以及预推免期间发生经历和问题 东南大学苏州校区蒙纳士大学联培 东南大学苏州校区的项目算是一个比较小众的项目,是第一年在苏州校区,二三年到南京校区找导师(不提供住宿自…...
【Java SE】包装类 Byte、Short、Integer、Long、Character、Float、Double、Boolean
参考笔记:java 包装类 万字详解(通俗易懂)_java包装类-CSDN博客 目录 1.简介 2.包装类的继承关系图 3.装箱和拆箱 3.1 介绍 3.2 手动拆装箱 3.3. 自动拆装箱 4.关于String类型的转化问题 4.1 String类型和基本类型的相互转化 4.1.1 String —…...
