跳到主要内容 访问控制失效漏洞解析:WebGoat 实战演练 | 极客日志
Java java
访问控制失效漏洞解析:WebGoat 实战演练 访问控制失效的概念 访问控制(Access Control),也称为授权(Authorization),是安全模型中的核心环节。它发生在认证(Authentication,即验证用户身份)之后,负责决定'一个已认证的用户是否有权限执行某项操作或访问某个资源'。 访问控制损坏(Broken Access Control)就是指应用程序未能正确地实施这些权限控制,导致攻击者能够绕过授权机制,访问本应无…
不知所云 发布于 2026/4/6 更新于 2026/4/13 78K 浏览访问控制失效的概念
访问控制(Access Control),也称为授权(Authorization),是安全模型中的核心环节。它发生在认证(Authentication,即验证用户身份)之后,负责决定'一个已认证的用户是否有权限执行某项操作或访问某个资源'。
访问控制损坏(Broken Access Control)就是指应用程序未能正确地实施这些权限控制,导致攻击者能够绕过授权机制,访问本应无权访问的功能或数据。简单来说,就是'越权'。
访问控制失效是一种常见的安全漏洞,在 OWASP Top 10 2021 榜单中位列第一,是 Web 应用程序安全的主要威胁之一。
![图片]
注:OWASP Top 10:OWASP 前十名 | OWASP 基金会
微信扫一扫,关注极客日志 微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
访问控制失效的核心问题在于应用程序未能强制执行'最小权限原则',导致用户可以执行超出其权限范围的操作。这种漏洞可能表现为水平越权(同一权限级别的用户访问其他用户的数据)或垂直越权(低权限用户访问高权限功能)。
访问控制失效的类型 访问控制失效(Broken Access Control)是一个大类,包含多种具体的表现形式。主要可以划分为三大类。
1. 水平越权 同一权限级别的用户能够访问其他用户的数据或功能。例如,用户 A 可以查看或修改用户 B 的账户信息。核心问题:系统在处理请求时,没有验证当前登录的用户是否是所请求数据的所有者。
2. 垂直越权 低权限用户能够访问高权限功能。例如,普通用户能够访问管理员功能。核心问题:系统没有基于用户的角色(Role)来限制对功能或页面的访问。
3. 上下文相关的访问控制缺失 用户有权执行某个操作,但不能在当前业务流程的上下文中执行,或者操作的顺序和状态不正确。例如在一个网购流程中(添加商品->支付->确认订单),攻击者直接跳过'支付'步骤,访问'确认订单'的 API 端点,从而未支付就完成了订单。核心问题:系统没有验证操作是否符合业务逻辑的流程和状态。
访问控制失效的示例 下面我们通过 WebGoat 靶场学习访问控制失效(Broken Access Control)。
下载下来后放在一个文件夹里,然后在这个文件夹里打开命令行,在命令行里运行命令:
java -Dfile.encoding=UTF-8 -jar webgoat-2025.3.jar
java -jar webgoat-2025.3.jar --webgoat.port=8001 --webwolf.port=8002
左侧栏对 OWASP Top 10 都有讲解。点击 Broken Access Control,可以看到有 4 个示例。
1. Hijack a Session:劫持会话 会话劫持是一种攻击手段,攻击者通过某种方式获取用户的会话标识符(Session ID),然后使用这个标识符来冒充用户,非法访问该用户的账户和数据。简单来说,就是攻击者'偷走了你的登录状态',系统误以为他是你。
这一关的意图是让我们预测一个已经登录了的用户的 hijack_cookie,利用这个 cookie 访问属于其他人的经过身份验证的会话。
可以看到 response 里 set-cookie 返回了一个 hijack_cookie,值为 5313965668152351398-1756258343191,下面显示的是失败信息。我们再发几次,返回的 hijack_cookie 如下:
第二次:hijack_cookie=5313965668152351399-1756258415125
第三次:hijack_cookie=5313965668152351401-1756258489500
第四次:hijack_cookie=5313965668152351402-1756258526446
可以看到前面的数字是递增的,每次 +1,但是第二次末尾是 399,第四次则直接是 401,这意味着有一个用户拿到了末尾是 400 的 cookie,这个 hijack_cookie 就是我们的目标。但是后面还有一串数字,它们虽都不同,但是十分接近,猜测可能是时间戳之类的。我们暴力破解。
我们查看源码,看看这个 hijack_cookie 的构造方式。
自增 ID-当前时间戳毫秒值,其格式过于简单导致能够被攻击方预测。
2. Insecure Direct Object References 不安全的直接对象引用 这种应用程序使用客户端提供的输入来访问数据和对象的方式就是直接对象引用。
攻击者是经过了身份验证,但是没有授权,这里我们先登录,它给了一个账号和密码。
这一节的意思是原始响应的数据通常不会完全显示在屏幕上,我们点击 view profile 按钮,界面会显示个人信息,但是响应里会有一些数据不会显示,让我们把没有显示的两个属性填写在下面的输入框内。
在具有用户角色的系统中,仅仅使用 /profile 通常指的是当前认证用户自己的个人资料。这是通过会话(Session)或令牌(Token)来隐式确定的,那么,'显式地'使用直接对象引用来查看自己资料的可能模式是什么?
这一节就是让我们猜测一个 url 能查看自己的个人资料。
前一节抓包看到是 /WebGoat/IDOR/profile,且 response 里返回了 userId。猜测用 userId 可以访问。
输入 /WebGoat/IDOR/profile/2342384
View Another Profile 我们可以使用上面的路径去查看别人的个人资料,用 bp 拦截后更改 userId,但是我们不知道其他的 userId,尝试爆破。
成功爆破出一个名为 Buffalo bill 的用户。
Edit Another Profile 下面部分是让我们更改这个找出来的用户的信息,把它的角色改为较低的角色,颜色改成红色。那还是抓包,更改 content-type 和 HTTP 请求方式。
Insecure Direct Object References(不安全的对象引用),其原因是后端的验证逻辑有问题。服务器在处理客户端请求时,过度信任客户端提供的参数来进行逻辑处理,并且没有验证当前登录的用户是否有权访问该特定对象,从而导致越权访问。
间接引用:不使用真实的数据库 ID,而是使用一种难以猜测的、随机的映射值。
访问控制检查:在每一个处理用户请求、试图访问数据的函数中,强制验证当前登录的用户是否拥有访问所请求数据的权限。这是最根本的解决方法。
基于策略的访问控制:定义清晰的用户权限策略。
3. Missing Function Level Access Control 缺少功能级别访问控制 造成 IDOR 的核心问题是用户能否访问某个特定数据对象,而缺少功能级别访问控制的核心问题在于用户能否执行某个功能/动作(Function/Action)。
Missing Function Level Access Control(缺少功能级别访问控制)是一种应用程序级别的安全漏洞,它发生在服务器没有对用户是否拥有执行某个功能(或访问某个 URL 端点)的权限进行校验的情况下。
简单来说,应用程序的 UI(用户界面)可能会根据用户角色隐藏或显示某些功能按钮(例如'删除用户'、'访问管理后台'),但服务器端的对应 API 端点却没有进行同样的权限检查。攻击者可以通过猜测、枚举或中间人抓包等方式发现这些隐藏的功能端点,并直接调用它们,从而执行本应被禁止的操作。
假设一个 web 应用有普通用户和管理员,普通用户只能查看自己的资料,而管理员可以管理所有用户。在前端界面,当管理员登录后,页面有一个明显的'用户管理'功能,点击后会跳转到某一个链接,而当普通用户登录后,页面不会显示这个功能。前端界面根据当前登录角色隐藏了它。但是如果后端没有实施任何权限检查,即验证请求这个 url 的用户是否真的有管理员角色,那么攻击者可以通过某种方式得到这个链接,然后直接访问,从而获得管理员角色的权限。
这个漏洞和 IDOR 的区别就在于 IDOR 更像是一个'水平'或'横向'访问控制问题,而缺少功能级访问控制是垂直越权且会'暴露功能'。
因为角色的不同,不同的用户的界面也会不同,前端会根据用户的角色隐藏功能,这一节就是寻找隐藏的菜单项,F12 查看元素。
这一节是让我们从已经收集到的隐藏菜单项提取用户列表,找到指定用户的哈希值。
access-control/users
access-control/users-admin-fix
access-control/config
这里要求请求的 Content-Type 头必须为 application/json,那我们添加 content-type: application/json。
这一节说是公司已经修复了问题,我们访问 access-control/users-admin-fix 这个页面试试。
返回 403,看来只有管理员才能访问了。我们查看源码。
有一个处理 post 请求的 adduser 方法,看来是添加用户的,我们尝试看能不能利用这个方法把我们的账户提升为管理员。
成功返回用户列表,可以看到 jerry 的哈希值跟上面的普通用户模式下的明显不一样。
总而言之,在服务端一定要做好校验,不要试图只通过前端隐藏让用户无法访问。
4. Spoofing an Authentication Cookie 伪造身份验证 Cookie 因为 HTTP 协议是无状态的,这意味着服务器处理每个请求时,都将其视为一个全新的、独立的请求,它不会记住之前来自同一个浏览器的任何请求。为了解决这个问题,诞生了 cookie 和 session。它们共同协作,在无状态的 HTTP 协议之上'模拟'出有状态的行为。
但是,如果某人的 cookie 被窃取或者被伪造出来,攻击者就可以绕过身份验证,从而冒充其他用户。
为了阻止这种风险,cookie 的生成必须唯一,复杂且不可预测,而且服务器在生成 Cookie 后,要对其进行'签名'。一个经过签名的 Cookie 会包含一个只有服务器知道的密钥生成的 MAC(消息认证码)。当 Cookie 被客户端修改后,签名就会失效,服务器能够立即识别并拒绝该 Cookie。同时需要为存放 Session ID 的 Cookie 设置 HttpOnly 和 Secure 属性,防止 XSS 窃取和明文传输。
题目是让我们伪造 cookie,以 Tom 的身份登录,并且给了两个已知的账户,我们先用它给出的账户登录。
cookie= NDM3YTRlNzU0MTZhNjI2MTc1NzM3NDYxNmY2NzYyNjU3Nw==
437a4e75416a6261757374616f67626577
cookie=NDM3YTRlNzU0MTZhNjI2MTc1NzM2ZTY5NmQ2NDYx
base64 解码出来 437a4e75416a626175736e696d6461
看不出来是什么,我们随便传一个 cookie,看看有没有什么报错信息。
响应里 output 里 Detected a Non-hex character at 1 or 2 position 意思是在 1 或 2 位置检测到非十六进制字符,这串数字有没有可能是 16 进制转换?尝试用 16 进制解码。
转换之后可以看到,前面一段字符串是相同的,后面则是 webgoat 和 admin 反过来,看来这就是 cookie 的构造方式,我们以此构造 Tom 的 cookie。
CzNuAjbausmot 437a4e75416a626175736d6f74
NDM3YTRlNzU0MTZhNjI2MTc1NzM2ZDZmNzQ=
总结 对于访问控制失效,其防御的核心思想始终如一:在服务器端对每一个请求实施强制性的、基于角色和上下文的权限检查,绝不信任客户端传来的任何信息(如 URL 参数、隐藏字段、HTTP 头)来判断用户的权限。