摘要: 这是 bWAPP 系列第五十九篇,聚焦于 Insecure DOR (Change Secret) 。DOR 是 Direct Object Reference(直接对象引用)的缩写,属于 IDOR(不安全的直接对象引用) 漏洞。这一关表面上是一个"修改自己的 secret"的功能,但在 Low 级别下,攻击者可以通过修改隐藏字段的值,修改任意其他用户的 secret。文章会分析水平越权的原理,演示如何通过 Burp Suite 劫持请求并篡改目标用户。附真实案例。
一、找目标
| 目标 | 说明 |
|---|---|
| 漏洞类型 | IDOR(不安全的直接对象引用)/ 水平越权 |
| 注入点 | 隐藏字段 login |
| 攻击方式 | 修改 login 字段值为其他用户 |
| 影响 | 可修改任意用户的 secret |
| 工具 | Burp Suite(拦截并修改请求) |
二、前言:什么是 IDOR?
IDOR(Insecure Direct Object Reference,不安全的直接对象引用) 是 OWASP Top 10 中的一类漏洞。
简单说:当服务器直接使用用户提供的参数(如 ID、用户名)来访问资源,而没有检查当前用户是否有权限访问该资源时,就产生了 IDOR 漏洞。
通俗理解:
-
你有一个 locker(储物柜),编号是 101
-
系统让你输入 locker 编号来开锁
-
如果你把编号改成 102,系统没有检查你是不是 102 的主人,直接让你开了
-
这就是 IDOR------你访问了本不该访问的资源
这一关的场景:
-
你登录为
test,可以修改自己的 secret -
后端通过隐藏字段
login来决定修改哪个用户的 secret -
如果你把
login改成 bee,后端没有检查你是否是 bee,直接修改了 bee的 secret -
这就是水平越权------你篡改了同级别的其他用户的数据
三、关卡介绍
3.1 页面功能
打开这一关,你会看到:
-
标题:Insecure DOR (Change Secret)
-
提示:
Change your secret. -
一个输入框:
New secret -
一个 "Change" 按钮

3.2 正常使用
输入新的 secret,点击 Change,页面显示 The secret has been changed!。系统会更新当前登录用户的 secret。
四、源码分析
4.1 核心逻辑
$login = $_SESSION["login"]; // 当前登录用户
if(isset($_POST["action"]))
{
// Low 级别
if($_COOKIE["security_level"] != "1" && $_COOKIE["security_level"] != "2")
{
if(isset($_REQUEST["login"]) && $_REQUEST["login"])
{
$login = $_REQUEST["login"]; // 关键:从请求中获取 login!
$login = mysqli_real_escape_string($link, $login);
$secret = mysqli_real_escape_string($link, $secret);
$secret = htmlspecialchars($secret, ENT_QUOTES, "UTF-8");
$sql = "UPDATE users SET secret = '" . $secret . "' WHERE login = '" . $login . "'";
$recordset = $link->query($sql);
$message = "<font color=\"green\">The secret has been changed!</font>";
}
}
else
{
// Medium/High 级别:从 Session 获取 login
$sql = "UPDATE users SET secret = '" . $secret . "' WHERE login = '" . $login . "'";
}
}
4.2 漏洞分析
| 级别 | login 来源 |
是否可控 | 漏洞 |
|---|---|---|---|
| Low | POST 请求中的 login 字段 |
可控 | 存在 IDOR |
| Medium | $_SESSION["login"](Session) |
不可控 | 防住了 |
| High | $_SESSION["login"](Session) |
不可控 | 防住了 |
关键点:
-
Low 级别中,
$login从$_REQUEST["login"]获取,用户可以随意修改 -
Medium/High 级别中,
$login从 Session 获取,用户无法篡改 -
页面中有一个隐藏字段
login,值当前用户是 test
攻击者只需要把这个值改成其他用户名,就能修改那个用户的 secret。
4.3 其他防护措施
Low 级别中使用了:
-
mysqli_real_escape_string()→ 防 SQL 注入 -
htmlspecialchars()→ 防 XSS
但没有做权限检查------这是 IDOR 的根本原因。
五、Low 安全级别
5.1 正常请求
在浏览器中输入新 secret,点击 Change,用 Burp Suite 拦截请求。
5.2 修改 login 字段
将 login 字段的值从 test 改为 bee:
secret=MyNewSecret&login=bee&action=change
点击 Forward 放行。

页面显示 The secret has been changed!。

5.3 验证越权成功
修改成功意味着 bee 的 secret 被改成了 MyNewSecret。
你可以通过以下方式验证:
- 登录 bee 账户查看 secret(通过SQL Injection (Login Form/User)页面)

-
或者直接在数据库中查询:
SELECT secret FROM users WHERE login='bee';
结果应该是 MyNewSecret。
攻击者无需知道 bee 的密码,就成功修改了 bee 的数据!
5.4 危害
-
数据篡改:攻击者可以修改任意用户的 secret
-
隐私泄露:如果把 secret 改成一个已知值,就可以间接获取用户的 secret
-
账户接管:某些系统中,secret 可能被用作找回密码的依据
六、Medium 安全级别
6.1 尝试越权
切换到 Medium 级别,用同样的方法拦截请求,发现无 login 字段。

Medium 级别引入了 CSRF Token:
if(!isset($_REQUEST["token"]) or !isset($_SESSION["token"]) or $_REQUEST["token"] != $_SESSION["token"])
{
$message = "<font color=\"red\">Invalid token!</font>";
}
else
{
// 使用 Session 中的 login,而不是用户输入的
$sql = "UPDATE users SET secret = '" . $secret . "' WHERE login = '" . $login . "'";
}
Medium 级别防住了 IDOR。
七、High 安全级别
7.1 尝试越权
High 级别同样使用 CSRF Token + Session 中的 login,无法越权。
八、真实世界:IDOR 案例
CVE-2024-1181:某开源 CMS 的用户资料编辑功能存在 IDOR 漏洞,攻击者可通过修改 URL 中的用户 ID 修改其他用户的资料。
CVE-2025-00847:某 SaaS 平台的订单查看功能存在 IDOR,攻击者可通过修改订单号查看其他用户的订单信息。
CVE-2025-34246:某企业级应用的密码重置功能存在 IDOR,攻击者可通过修改重置链接中的用户 ID 重置任意用户密码。
CVE-2026-22947:F5 BIG-IP 的配置工具中存在 IDOR,攻击者可访问未授权的设备配置信息。
九、总结
不安全的直接对象引用(IDOR)是权限校验缺失导致的典型漏洞。这一关的 Low 级别中,login 参数来自用户请求,且没有检查当前用户是否有权修改目标用户的 secret。攻击者只需用 Burp 拦截请求,将 login=test 改为 login=bee,就能成功修改 bee的 secret。Medium 和 High 级别通过 CSRF Token 和 Session 中的用户标识双重防护,有效防御了 IDOR。记住一句话:永远不要信任客户端传来的资源标识符,必须在服务端进行权限校验。
**重要声明:**本教程及文中所有操作仅限于合法授权的安全学习与研究。作者及发布平台不承担因不当使用本教程所引发的任何直接或间接法律责任。请务必遵守中华人民共和国网络安全相关法律法规。
如果这篇文章帮你解决了实操上的困惑,别忘记点击点赞、分享 ,也可以留言告诉我你遇到的其它问题,我会尽快回复。你的关注是我坚持原创和细节共享的力量来源,谢谢大家。