《白帽子讲 Web 安全》之跨站请求伪造

news2025/4/24 18:17:35

引言

在数字化时代,网络已深度融入人们生活的方方面面,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, session

app = Flask(__name__)

app.secret_key = 'your_secret_key'

@app.route('/generate_token')

def generate_token():

    import secrets

    token = secrets.token_hex(16)

    session['csrf_token'] = token
    
    return 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验证失败', 403

    if 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 Flask

from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)

app.secret_key = 'your_secret_key'

csrf = CSRFProtect(app)

# 其他路由和视图函数

在 HTML 表单中,使用Flask - WTF生成 CSRF 保护字段:

{{ form.csrf_token }}

通过这种方式,开发者可以利用框架提供的工具轻松增强应用的安全性。但需要注意的是,在使用这些工具时,要正确配置和使用,仔细阅读框架文档,避免因配置不当而出现漏洞,确保应用能够有效抵御 CSRF 攻击。

总结

跨站请求伪造(CSRF)是一个复杂且不断演变的 Web 安全问题。无论是开发者、安全研究人员还是普通用户,都需要持续关注其发展动态。开发者要将安全意识贯穿于整个开发周期,不仅要熟练运用现有的防御技术,还要积极探索新的安全防护手段;安全研究人员需深入研究攻击者的新手法,为安全防护提供理论支持;而普通用户则要提高自身的安全意识,谨慎点击不明链接,避免访问可疑网站。只有各方共同努力,才能在这场与 CSRF 攻击的较量中取得胜利,保障 Web 应用的安全和用户的权益。

喜欢就点点赞和评论关注一起进步呗

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

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

相关文章

K8S学习之基础五十:k8s中pod时区问题并通过kibana查看日志

k8s中pod默认时区不是中国的&#xff0c;挂载一个时区可以解决 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代理前端请求

一&#xff0c;项目配置 我在 ip 为 192.168.31.177 的机器上使用 vue3 开发前端项目&#xff0c;项目中使用 axios 调用后端接口。 这是 axios 的配置&#xff1a; import axios from axios;const request axios.create({baseURL: http://192.168.31.177:8001,// 设置请求…

Android生态大变革,谷歌调整开源政策,核心开发不再公开

“开源”这个词曾经是Android的护城河&#xff0c;如今却成了谷歌的烫手山芋。最近谷歌宣布调整Android的开源政策&#xff0c;核心开发将全面转向私有分支。翻译成人话就是&#xff1a;以后Android的核心更新&#xff0c;不再公开共享了。 这操作不就是开源变节吗&#xff0c;…

银行分布式新核心的部署架构(两地三中心)

银行的核心系统对可用性和性能要求均非常严苛&#xff0c;所以一般都采用两地三中心部署模式。 其中&#xff1a; 同城两个主数据中心各自部署一套热备&#xff0c;平时两个中心同时在线提供服务&#xff0c;进行负载均衡假如其中一个数据中心出现异常&#xff0c;则由另外一个…

MantisBT在Windows10上安装部署详细步骤

MantisBT 是一款基于 Web 的开源缺陷跟踪系统&#xff0c;以下是在 Windows 10 上安装部署 MantisBT 的详细步骤&#xff1a; 1. 安装必要的环境 MantisBT 是一个基于 PHP 的 Web 应用程序&#xff0c;因此需要安装 Web 服务器&#xff08;如 Apache&#xff09;、PHP 和数据…

9.4分漏洞!Next.js Middleware鉴权绕过漏洞安全风险通告

今日&#xff0c;亚信安全CERT监控到安全社区研究人员发布安全通告&#xff0c;Next.js 存在一个授权绕过漏洞&#xff0c;编号为 CVE-2025-29927。攻击者可能通过发送精心构造的 x-middleware-subrequest 请求头绕过中间件安全控制&#xff0c;从而在未授权的情况下访问受保护…

OpenCV图像拼接(5)图像拼接模块的用于创建权重图函数createWeightMap()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::detail::createWeightMap 是 OpenCV 库中用于图像拼接模块的一个函数&#xff0c;主要用于创建权重图。这个权重图在图像拼接过程中扮演着重…

CTF类题目复现总结-[MRCTF2020]ezmisc 1

一、题目地址 https://buuoj.cn/challenges#[MRCTF2020]ezmisc二、复现步骤 1、下载附件&#xff0c;得到一张图片&#xff1b; 2、利用010 Editor打开图片&#xff0c;提示CRC值校验错误&#xff0c;flag.png应该是宽和高被修改了&#xff0c;导致flag被隐藏掉&#xff1b;…

linux打包前端vue,后端springboot项目

第一步先对整个项目进行通过maven进行clean在进行compile 第二步直接进行打包package和install都可以 第三部把对应的jar放到服务器上 把jar包放到服务器上某个地址下&#xff0c;然后cd到这个目录下&#xff0c;然后执行命令 nohup java -jar ruoyi-admin.jar > springbo…

Elasticsearch:使用 AI SDK 和 Elastic 构建 AI 代理

作者&#xff1a;来自 Elastic Carly Richmond 你是否经常听到 AI 代理&#xff08;AI agents&#xff09;这个词&#xff0c;但不太确定它们是什么&#xff0c;或者如何在 TypeScript&#xff08;或 JavaScript&#xff09;中构建一个&#xff1f;跟我一起深入了解 AI 代理的概…

Docker 快速入门指南

Docker 快速入门指南 1. Docker 常用指令 Docker 是一个轻量级的容器化平台&#xff0c;可以帮助开发者快速构建、测试和部署应用程序。以下是一些常用的 Docker 命令。 1.1 镜像管理 # 搜索镜像 docker search <image_name># 拉取镜像 docker pull <image_name>…

自顶向下学习K8S--部署Agones

本文在本人博客&#xff0c;原文地址&#xff1a;http://viogami.tech/index.php/blog/346/ 我是gopher&#xff0c;离不开云原生&#xff0c;自然也逃不了理解docker和K8S这俩。今天抽空想玩下agones&#xff0c;进而对K8S有实践性的理解。 学一个新事物从底层理论学肯定是最…

unity中Xcharts图表鼠标悬浮表现异常

鼠标悬浮在面板附近&#xff0c;只显示单独的一个项目 而且无论鼠标如何移动&#xff0c;根本没有效果。 解决方案&#xff1a; 需要在对应的Canvas上绑定主相机才可以 鼠标移动到项目上就有信息展示了

【Java SE】包装类 Byte、Short、Integer、Long、Character、Float、Double、Boolean

参考笔记&#xff1a;java 包装类 万字详解&#xff08;通俗易懂)_java包装类-CSDN博客 目录 1.简介 2.包装类的继承关系图 3.装箱和拆箱 3.1 介绍 3.2 手动拆装箱 3.3. 自动拆装箱 ​4.关于String类型的转化问题 4.1 String类型和基本类型的相互转化 4.1.1 String —…

口腔种植全流程AI导航系统及辅助诊疗与耗材智能化编程分析

一、系统架构与编程框架设计 口腔种植全流程人工智能导航系统的开发是一项高度复杂的多学科融合工程,其核心架构需在医学精准性、工程实时性与临床实用性之间实现平衡。系统设计以模块化分层架构为基础,结合高实时性数据流与多模态协同控制理念,覆盖从数据采集、智能决策到…

Java 集合中ArrayList与LinkedList的性能比较

一、需求&#xff1a; 头部插入‌&#xff1a;向列表头部插入10万个整数。‌随机访问‌&#xff1a;从列表中间位置连续获取1万个元素。‌头部删除‌&#xff1a;从列表头部连续删除10万个元素。 二、 使用ArrayList与LinkedList测试 //常量定义&#xff0c;用于测试操作的次数…

漏洞发现:AWVS 联动 XRAY 图形化工具.(主动+被动 双重扫描)

漏洞发现&#xff1a;AWVS 联动 XRAY 图形化工具. 漏洞发现是网络安全领域的关键环节&#xff0c;指通过技术手段识别计算机系统、网络设备或软件中存在的设计缺陷、配置错误或代码漏洞的过程。这些漏洞可能被攻击者利用&#xff0c;导致数据泄露、服务中断或权限提升等风险。…

Linux ping/telnet/nc命令

在Linux操作系统中&#xff0c;ping命令用于测试网络连接和发送数据包到目的主机。 然而&#xff0c;ping命令默认情况下只能测试IP地址和域名&#xff0c;而无法直接测试端口号。 ping www.baidu.comping 192.168.0.1 测试端口 如果你想测试特定端口是否开放并响应&#xff…

Netty - 从Nginx 四层(TCP/UDP)流量中获取客户端真实/网络出口IP

文章目录 一、背景与原理1.1 问题场景网络架构影响分析1.1 客户端与Nginx之间存在的NAT/VPN1.2 Nginx与RPC服务之间的NAT 1.2 技术原理 二、环境配置验证2.1 Nginx配置2.2 版本要求 三、Netty服务端实现3.1 Pipeline配置&#xff08;核心代码&#xff09;3.2 协议处理器实现3.3…

Ubuntu下载docker、xshell

配置&#xff1a;VMware虚拟机、Ubuntu24.04.1 首先打开vm启动虚拟机 下载docker Ubuntu启动之后&#xff0c;按CTRLALTT 打开终端 1.更新软件包索引并安装依赖 sudo apt-get updatesudo apt-get install \ca-certificates \curl \gnupg \lsb-release 2.添加docker官方的GP…