访问控制失效:安全漏洞解析(WebGoat Broken Access Control讲解)

访问控制失效的概念

访问控制(Access Control),也称为授权(Authorization),是安全模型中的核心环节。它发生在认证(Authentication,即验证用户身份) 之后,负责决定“一个已认证的用户是否有权限执行某项操作或访问某个资源”。

访问控制损坏(Broken Access Control)就是指应用程序未能正确地实施这些权限控制,导致攻击者能够绕过授权机制,访问本应无权访问的功能或数据。简单来说,就是 “越权”。

访问控制失效是一种常见的安全漏洞,在OWASP Top 10 2021榜单中位列第一,是Web应用程序安全的主要威胁之一。

注:OWAPS TOP 10:OWASP 前十名 |OWASP 基金会 --- OWASP Top Ten | OWASP Foundation

访问控制失效的核心问题在于应用程序未能强制执行“最小权限原则”,导致用户可以执行超出其权限范围的操作。这种漏洞可能表现为水平越权(同一权限级别的用户访问其他用户的数据)或垂直越权(低权限用户访问高权限功能)。

访问控制失效的类型

访问控制失效(Broken Access Control)是一个大类,包含多种具体的表现形式。主要可以划分为三大类。

1、水平越权

同一权限级别的用户能够访问其他用户的数据或功能。例如,用户A可以查看或修改用户B的账户信息。核心问题:系统在处理请求时,没有验证当前登录的用户是否是所请求数据的所有者。

2、垂直越权

低权限用户能够访问高权限功能。例如,普通用户能够访问管理员功能。核心问题:系统没有基于用户的角色(Role)来限制对功能或页面的访问

3、上下文相关的访问控制缺失

用户有权执行某个操作,但不能在当前业务流程的上下文中执行,或者操作的顺序和状态不正确。例如在一个网购流程中(添加商品->支付->确认订单),攻击者直接跳过“支付”步骤,访问“确认订单”的 API 端点,从而未支付就完成了订单。核心问题:系统没有验证操作是否符合业务逻辑的流程和状态。

访问控制失效的示例

下面我们通过webgoat靶场学习访问控制失效(Broken Access Control)

webgoat的搭建很简单,只需要下载webgoat的jar文件,链接https://github.com/WebGoat/WebGoat/releases

下载下来后放在一个文件夹里,然后在这个文件夹里打开命令行,在命令行里运行命令

java -Dfile.encoding=UTF-8 -jar webgoat-2025.3.jar

如果想要在不同的端口运行webgoat,可以添加参数来实现。命令

java -jar webgoat-2025.3.jar --webgoat.port=8001 --webwolf.port=8002

访问http://127.0.0.1:8001/webgoat

注册账户

左侧栏对OWAPS 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 不安全的直接对象引用

它这里首先解释了什么是直接的对象引用,例如

https://some.company.tld/dor?id=12345

https://some.company.tld/images?img=12345

这种应用程序使用客户端提供的输入来访问数据和对象的方式就是直接对象引用。

然后介绍了什么是不安全的直接对象引用。

假如可以通过https://some.company.tld/app/user/23398查看个人资料,后面的数字对应用户的id,如果更改后面的数字(例如改为/user/23399)可以查看id为23399的用户的个人资料,这种情况就属于不安全的直接对象引用。

攻击者是经过了身份验证,但是没有授权,这里我们先登录,它给了一个账号和密码

这一节的意思是原始响应的数据通常不会完全显示在屏幕上,我们点击view profile按钮,界面会显示个人信息,但是响应里会有一些数据不会显示,让我们把没有显示的两个属性填写在下面的输入框内

没有显示的是role和userId

在具有用户角色的系统中,仅仅使用 /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(不安全的对象引用),其原因是后端的验证逻辑有问题。服务器在处理客户端请求时,过度信任客户端提供的参数来进行逻辑处理,并且没有验证当前登录的用户是否有权访问该特定对象,从而导致越权访问。

防御IDOR的措施通常包括

1)间接引用:不使用真实的数据库ID,而是使用一种难以猜测的、随机的映射值。

2)访问控制检查:在每一个处理用户请求、试图访问数据的函数中,强制验证当前登录的用户是否拥有访问所请求数据的权限。这是最根本的解决方法。

3)基于策略的访问控制:定义清晰的用户权限策略。

3、Missing Function Level Access Control 缺少功能级别访问控制

造成IDOR的核心问题是用户能否访问某个特定数据对象,而缺少功能级别访问控制的核心问题在于用户能否执行某个功能/动作(Function/Action)。

Missing Function Level Access Control(缺少功能级别访问控制)是一种应用程序级别的安全漏洞,它发生在服务器没有对用户是否拥有执行某个功能(或访问某个URL端点)的权限进行校验的情况下。

简单来说,应用程序的UI(用户界面)可能会根据用户角色隐藏或显示某些功能按钮(例如“删除用户”、“访问管理后台”),但服务器端的对应API端点却没有进行同样的权限检查。攻击者可以通过猜测、枚举或中间人抓包等方式发现这些隐藏的功能端点,并直接调用它们,从而执行本应被禁止的操作。

假设一个web应用有普通用户和管理员,普通用户只能查看自己的资料,而管理员可以管理所有用户。在前端界面,当管理员登录后,页面有一个明显的“用户管理“功能,点击后会跳转到某一个链接,而当普通用户登录后,页面不会显示这个功能。前端界面根据当前登录角色隐藏了它。但是如果后端没有实施任何权限检查,即验证请求这个url的用户是否真的有管理员角色,那么攻击者可以通过某种方式得到这个链接,然后直接访问,从而获得管理员角色的权限。

这个漏洞和IDOR的区别就在于IDOR 更像是一个“水平”或“横向”访问控制问题,而缺少功能级访问控制是垂直越权且会“暴露功能”。

因为角色的不同,不同的用户的界面也会不同,前端会根据用户的角色隐藏功能,这一节就是寻找隐藏的菜单项,F12查看元素

Users和Config

这一节是让我们从已经收集到的隐藏菜单项提取用户列表,找到指定用户的哈希值

上一节我们找到了三个链接

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的哈希值跟上面的普通用户模式下的明显不一样

总而言之,在服务端一定要做好校验,不要试图只通过前端隐藏让用户无法访问。

因为HTTP协议是无状态的,这意味着服务器处理每个请求时,都将其视为一个全新的、独立的请求,它不会记住之前来自同一个浏览器的任何请求。为了解决这个问题,诞生了cookie和session。它们共同协作,在无状态的 HTTP 协议之上“模拟”出有状态的行为。

但是,如果某人的cookie被窃取或者被伪造出来,攻击者就可以绕过身份验证,从而冒充其他用户。

为了阻止这种风险,cookie的生成必须唯一,复杂且不可预测,而且服务器在生成Cookie后,要对其进行“签名”。一个经过签名的Cookie会包含一个只有服务器知道的密钥生成的MAC(消息认证码)。当Cookie被客户端修改后,签名就会失效,服务器能够立即识别并拒绝该Cookie。同时需要为存放 Session ID 的 Cookie 设置 HttpOnly 和 Secure 属性,防止 XSS 窃取和明文传输。

题目是让我们伪造cookie,以Tom的身份登录,并且给了两个已知的账户,我们先用它给出的账户登录

创建了一个cookie

cookie= NDM3YTRlNzU0MTZhNjI2MTc1NzM3NDYxNmY2NzYyNjU3Nw==

看着像是base64编码,解码试试

437a4e75416a6261757374616f67626577

不知道是什么

登录admin

cookie=NDM3YTRlNzU0MTZhNjI2MTc1NzM2ZTY5NmQ2NDYx

base64解码出来437a4e75416a626175736e696d6461

看不出来是什么,我们随便传一个cookie,看看有没有什么报错信息

响应里output里Detected a Non-hex character at 1 or 2 position意思是在1或2位置检测到非十六进制字符,这串数字有没有可能是16进制转换?尝试用16进制解码

CzNuAjbaustaogbew

CzNuAjbausnimda

转换之后可以看到,前面一段字符串是相同的,后面则是webgoat和admin反过来,看来这就是cookie的构造方式,我们以此构造Tom的cookie

CzNuAjbausmot 437a4e75416a626175736d6f74

NDM3YTRlNzU0MTZhNjI2MTc1NzM2ZDZmNzQ=

用这个cookie试试

成功。

总结

对于访问控制失效,其防御的核心思想始终如一:在服务器端对每一个请求实施强制性的、基于角色和上下文的权限检查,绝不信任客户端传来的任何信息(如URL参数、隐藏字段、HTTP头)来判断用户的权限。

Read more

【Java Web学习 | 第14篇】JavaScript(8) -正则表达式

【Java Web学习 | 第14篇】JavaScript(8) -正则表达式

🌈个人主页: Hygge_Code🔥热门专栏:从0开始学习Java | Linux学习| 计算机网络💫个人格言: “既然选择了远方,便不顾风雨兼程” 文章目录 * JavaScript 正则表达式详解 * 什么是正则表达式🤔 * JavaScript 正则表达式的定义与使用🥝 * 1. 字面量语法 * 2. 常用匹配方法 * test() 方法🍋‍🟩 * exec() 方法🍋‍🟩 * 正则表达式的核心组成部分🐦‍🔥 * 1. 元字符 * 边界符 * 量词 * 字符类 * 2. 修饰符 * 简单示例🍂 JavaScript 正则表达式详解 正则表达式是处理字符串的强大工具,在 JavaScript 中被广泛应用于表单验证、文本处理和数据提取等场景。本文将从正则表达式的基本概念出发,详细介绍其语法规则和实际应用方法。 什么是正则表达式🤔 正则表达式是用于匹配字符串中字符组合的模式,在 JavaScript

Flutter 三方库 jwt_io 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、严谨、全能的 JSON Web Token (JWT) 加解密与身份安全验证引擎

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 jwt_io 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、严谨、全能的 JSON Web Token (JWT) 加解密与身份安全验证引擎 在鸿蒙(OpenHarmony)系统的端云一体化登录、政企应用的安全审计或复杂的跨端权限校验场景中,如何确保来自云端授信中心的 JWT Token 既能被正确解析(Decode),又能被严密地校验其合法性与过期时间?jwt_io 为开发者提供了一套工业级的、基于 RFC 7519 标准的 JSON Web Token 深度处理方案。本文将深入实战其在鸿蒙应用安全底座中的应用。 前言 什么是 JWT IO?它不仅是一个简单的 Base64 解码器,而是一个具备深厚 RFC

Spring MVC 全面详解(Java 主流 Web 开发框架)

Spring MVC 全面详解(Java 主流 Web 开发框架) 一、Spring MVC 是什么 & 定位 Spring MVC 是 Spring Framework 框架的核心模块之一,是一款基于MVC 设计模式的轻量级 Java Web 开发框架,也是目前 Java 后端主流的 Web 开发技术(没有之一)。 价值:简化 Java Web 开发,将 Web 开发中的「请求接收、参数封装、业务处理、响应返回」等流程标准化、解耦化; 理念:遵循 约定优于配置 + 面向接口编程,兼顾灵活性和开发效率; 特性: