Idor vulnerability testing
Skill findscripter/everything-skills/08-security/idor-vulnerability-testing
当对已授权的 Web 应用做横向/纵向越权(IDOR)评估、需用参数篡改和枚举验证跨用户数据访问时使用;产出可复现的 IDOR 漏洞清单、PoC、受影响端点与修复建议;不适用于无书面授权的目标、纯认证缺失漏洞或访问真实用户敏感数据;触发词:IDOR、越权、Direct Object ReferenceFrom its SKILL.md
npx -y skills add findscripter/everything-skills --skill idor-vulnerability-testingAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
8.2 KB, ~2.6k tokens by cl100k_base, as published. Nobody here has run it
仅限授权使用:本技能只能用于获得书面授权的安全评估、防御验证或受控教学环境。
IDOR 越权漏洞测试
系统化地发现并验证 Web 应用中的不安全直接对象引用(IDOR)漏洞。覆盖数据库对象引用与静态文件引用两类,使用参数篡改与枚举进行检测,借助 Burp Suite 利用,并给出修复策略。
何时使用
适用:
- 对已获书面授权的目标做访问控制测试,怀疑接口仅凭客户端传入的
id/userId/文件名定位资源,而未校验归属。 - 验证水平越权(用户访问用户)与垂直越权(普通用户访问管理员功能)。
- 至少有两个测试账号(attacker / victim),可对比跨用户访问结果。
不该用(负边界):
- 没有明确书面授权的任何目标——直接停止。
- 不要访问、修改或外泄真实用户数据;测试只用自建的可识别数据。
- 纯认证缺失(未登录即可访问)属于另一类问题,不在本技能范围。
- 仅会话令牌绑定资源、不接受 ID 入参的场景,IDOR 不成立,转其他向量。
步骤
-
识别引用类型
- 数据库对象引用:
example.com/user/profile?id=2023→ 改id=2022试读他人数据。 - 静态文件引用:
example.com/static/receipt/205.pdf→ 改200.pdf试取他人文件。
- 数据库对象引用:
-
侦察与准备
- 建两个账号:
attacker(主测)、victim(目标数据)。 - 定位对象引用位置:URL 路径
/api/user/123、查询参数?id=123、请求体{"userId":123}、文件名receipt_123.pdf、UUID/profile/a1b2c3d4-...。 - 摸清 ID 规律:是否连续整数、自增、可预测。
- 建两个账号:
-
检测
- URL 参数篡改:保持 attacker 会话,把
id改成 victim 的值,若返回 victim 数据即存在漏洞。 - 请求体篡改:把 body 里的
userId改成目标值,观察是否越权写入/读取。 - HTTP 方法切换:
GET被 403 时,试POST/PUT是否 200。
- URL 参数篡改:保持 attacker 会话,把
-
利用(Burp Suite)
- 手动:浏览器代理走 Burp → 登录 attacker → 打开数据页 → Proxy 开 Intercept → 抓含 ID 的请求 → 改成 victim 的 ID → Forward → 看响应。
- 自动枚举(Intruder):发送到 Intruder(Ctrl+I)→ 清空 payload 位置 → 仅选 ID 参数 → 攻击类型 Sniper → Payload 选 Numbers,Range 1–10000,Step 1 → Start,筛 200 响应。
- 多位置同 ID:用 Battering Ram,对 URL 与 body 中的
§5§统一注入。
-
验证与定级
- 用 PII 标记(姓名、邮箱、创建时间、元数据)确认数据归属,比较响应长度/时延,给出数据暴露严重度。
指令
URL 参数篡改:
# 原始请求(attacker 会话)
GET /api/user/profile?id=1001 HTTP/1.1
Cookie: session=attacker_session
# 篡改 ID 指向 victim
GET /api/user/profile?id=1000 HTTP/1.1
Cookie: session=attacker_session
# 若返回 victim 数据 → 存在 IDOR
请求体篡改:
POST /api/address/update HTTP/1.1
Content-Type: application/json
Cookie: session=attacker_session
{"id": 5, "userId": 1000, "address": "..."} # userId 由 1001 改为 1000
HTTP 方法切换:
GET /api/admin/users/1000 → 403 Forbidden
POST /api/admin/users/1000 → 200 OK (可能存在漏洞)
PUT /api/admin/users/1000 → 200 OK (可能存在漏洞)
Burp Intruder 多位置枚举(Battering Ram):
PUT /api/addresses/§5§/update HTTP/1.1
{"id": §5§, "userId": 3}
Payload: Numbers 1-1000
常见 IDOR 位置速查:
- API:
/api/user/{id}、/api/order/{id}、/api/invoice/{id}、/api/address/{id}/update|delete - 文件下载:
/download/invoice_{id}.pdf、/static/receipts/{id}.pdf、/uploads/documents/{filename} - 查询参数:
?userId=、?orderId=、?documentId=、?file=report_123.pdf
测试清单:
| 测试 | 方法 | 漏洞特征 |
|---|---|---|
| 增减 ID | id=5→id=4 | 返回他人数据 |
| 用已知 victim ID | 替换为目标 ID | 获取 victim 资源 |
| 范围枚举 | 测 1–1000 | 命中他人有效记录 |
| 负值/0 | id=-1/id=0 | 异常数据或报错 |
| 超大值 | id=99999999 | 信息泄露 |
| 字符串/UUID | 改格式或改 UUID 片段 | 逻辑绕过/可预测 |
响应解读:
| 状态码 | 含义 |
|---|---|
| 200 | 疑似 IDOR,需核实归属 |
| 403 | 访问控制生效 |
| 404 | 资源不存在 |
| 401 | 需认证 |
| 500 | 可能存在输入校验问题 |
示例
示例 1 基础 ID 参数 IDOR:
# attacker(userId=1001) 登录后
GET /api/profile?id=1001 ... # 返回自己数据
GET /api/profile?id=1000 ... # 返回 victim 数据 → 漏洞
示例 2 地址更新越权:
PUT /api/addresses/5/update
{"id":5,"userId":1000,"street":"...","city":"..."} # userId 改为 victim
# 若 200 OK,则地址被挂到 victim 账号下
示例 3 静态文件 IDOR:
GET /api/download/5 → attacker 的回执 PDF
GET /api/download/3 → victim 的回执 PDF(漏洞)
示例 4 水平转垂直提权:
GET /api/user/1 → {"role":"user","id":1}
GET /api/user/3 → {"role":"admin","id":3}
# 用普通用户会话访问 /api/admin/dashboard?userId=3
# 若可访问,则实现垂直提权
注意事项
- 至少需两个有效账号才能验证;部分应用用会话绑定令牌而非 ID。
- UUID 不易枚举但非不可能:从响应体、JS 文件、列表接口、报错信息中找泄露的 UUID;UUID v1 时间相关可尝试预测。
- 速率限制可绕:Intruder 加延时、轮换 IP、只打高价值 ID、换等价端点、错峰测试。
- 全 403 时的备选向量:方法切换、加
X-Original-URL/X-Rewrite-URL头、参数污染?id=1001&id=1000、URL 编码(%31%30%30%30=1000)、大小写变体。 - 会话绑定资源时:测未认证端点、密码重置/邮箱验证流程、文件上传下载、API 版本(v1 vs v2)、移动端接口(常防护更弱)。
- 盲 IDOR/异步/WebSocket 场景响应不直接确认时,用唯一可识别数据、PII 标记、响应长度与时延差作旁证。
- 合规:仅测授权目标,记录全部测试活动,不碰真实用户数据,按正规渠道披露。
修复要点(服务端始终校验归属,不信任客户端入参):
# 1. 校验归属
def update_address(request, address_id):
address = Address.objects.get(id=address_id)
if address.user != request.user:
return HttpResponseForbidden("Unauthorized")
address.update(request.data)
# 2. 用间接引用:/api/address/123 → /api/address/current-user/billing
def get_address(request):
return Address.objects.filter(user=request.user).first()
# 3. 查询时强制按当前用户过滤
def download_receipt(request, receipt_id):
receipt = Receipt.objects.filter(id=receipt_id, user=request.user).first()
if not receipt:
return HttpResponseNotFound()
return FileResponse(receipt.file)
互见
- 访问控制 / 鉴权设计类技能(最小权限、间接引用映射)。
- 枚举与代理工具使用(Burp Suite Intruder、参数污染、编码绕过)。
- 漏洞披露与报告规范。
采编自 sickn33/antigravity-awesome-skills(原作者 zebbern,MIT 许可)。
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.