unauthorized-access

star 72

未授权访问检测 — 未登录用户可访问敏感接口、管理功能或核心数据的风险;适用于公开 API、管理端点与内部服务暴露场景。

Q16G By Q16G schedule Updated 6/7/2026

name: unauthorized-access description: 未授权访问检测 — 未登录用户可访问敏感接口、管理功能或核心数据的风险;适用于公开 API、管理端点与内部服务暴露场景。 when-to-use: 当需要验证未登录用户是否可访问敏感接口、管理功能或核心数据时 allowed-tools: bash,read_file,list_files,rg user-invocable: false

未授权访问检测

成因引用

未授权访问成因:source(任何请求——包含无凭证 / 空凭证 / 伪造 header)→ sink(应受保护端点的认证决策点:路由认证中间件、handler 入口的鉴权调用、网关路由表的 public/protected 分类、静态资源 Server 的目录映射)。该端点应受保护但实际"漏挂中间件 / 路由前缀错配 / 兜底拒绝缺失 / 仅前端隐藏"导致未认证可达。详见同根目录 pentest/web-security-testing/SKILL.md 漏洞成因图谱 · 未授权访问行(不在本 skill 重复成因)。

触发线索(基线检查项)

以下是已知的常见未授权访问触发线索,作为基线起点而非必检硬清单。结合目标代码与上下文动态调整:

  • 适用且已完成 → 标注 [x] done
  • 明确不适用 → 标注 [-] n/a (原因),原因要具体到代码事实
  • 基线未列出但实际发现 → 新增条目并标注 [+] added (来源)

基线触发线索按"sink 语义"分类(不按业务命名):

  • 管理后台 / admin 端点/admin/* / /manage/* / /console/* / /ops/*,应仅管理员可达
  • 内部 API/internal/* / /api/v1/internal/* / /_api/*,意图仅内部服务调用
  • 调试 / 开发遗留/debug/* / /pprof/* / /.env / /actuator/* / /.git/* / /.DS_Store / phpinfo
  • API 文档 / 内省/swagger.json / /openapi.json / /v3/api-docs / GraphQL __schema 内省
  • 数据导出 / 报表 / 日志/export/* / /report/* / /logs/*,含批量数据
  • 配置 / 健康检查暴露过多/health / /status 暴露版本号、内部地址、DB 连接 string、依赖列表
  • 静态资源下的敏感文件/static/.env / /uploads/backup.sql / /public/config.yml
  • OPTIONS 预检 / CORS 旁路:预检响应里泄露的端点列表
  • WebSocket / SSE 端点:仅前端隐藏入口,后端未做握手鉴权
  • 代码模式:路由表里 protected 分组之外的"漏挂端点";handler 入口缺 auth.Required() / middleware.Auth() 调用;静态文件服务挂载在含敏感文件的目录

思考检查点

加载本 skill 时按这些问题思考:

  • 这个端点应该"谁可访问"?前端隐藏不等于后端鉴权——后端是否独立校验?
  • 路由是否挂在 protected 分组下?handler 入口是否调了认证中间件?
  • 静态资源 Server 的根目录里是否混入了 .env / backup.sql / 配置文件?
  • "无凭证"和"空凭证"两种探测都做了吗?fail-open 缺陷常表现为"有头即放行"
  • 同子系统其他敏感端点的鉴权是逐项配置的吗?需要按端点账本独立测

前置条件与安全边界

  • 仅在授权环境执行验证,禁止越权改写生产数据。涉及删除/覆盖/不可逆写时,按 common/closure-verification.md 的《破坏性 / 不可逆动作的闭环边界》执行——优先哨兵自证或非破坏差分,二者都做不到就停 suspected,不得对真实业务数据执行破坏动作来强行闭环。
  • 单接口默认最多 6 次请求(基线 2 次 + 对照 2 次 + 复验 2 次)。
  • 单轮只改变"是否携带认证信息"一个变量,不联动改参数。
  • 一旦形成 confirmed 证据,立即停止扩展探测。

检测步骤

Step 1:基线与端点画像

  1. 从端点账本(recon-methodology 产出的 endpoint-ledger.jsonl)筛选"应受保护"端点(产品语义、文档、页面入口、业务字段含敏感数据)
  2. 使用有效登录态发送 1~2 次基线请求,记录状态码、响应体关键字段、业务副作用
  3. 区分"业务端点"和"基础设施端点"(debug / actuator / swagger)——后者常被遗忘

Step 2:无凭证对照

完全删除全部认证信息(Cookie、Authorization、自定义 Token 头、Session ID)后重放同请求,对比是否仍返回敏感业务数据或执行成功。

Step 3:空凭证 / fail-open 探测

保留认证头但把其值置空(Authorization: 、空 Token、user_id= 空、uid=0X-User-Id: 0),探测后端把"空身份"误判为可信/默认放行的 fail-open 缺陷——部分中间件"有头即放行、不校验值"。

Step 4:路径与方法变体

  • 同一资源不同方法(GET / POST / PUT / OPTIONS / HEAD)鉴权严格度可能不一致
  • 大小写 / 末尾斜杠 / %2e 编码绕过路由前缀匹配
  • 同一端点不同 API 版本(/v1 vs /v2)鉴权配置可能漂移
  • 对比有/空/无凭证三种结果,重点验证是否仍返回敏感业务数据
  • 对可疑结论重复至少 1 轮复验,确认可稳定复现

示例库

正例形态(代码层根因)

  • router.GET("/admin/users", handlers.ListUsers) — admin 端点漏挂认证中间件(no-cred-admin-endpoint-missing-middleware-unauth
  • http.Handle("/debug/", http.DefaultServeMux) — 调试路由暴露到公网(no-cred-debug-route-exposed-unauth
  • if r.Header.Get("Authorization") != "" { /* trust */ } — 有头即放行(empty-token-header-fail-open-unauth
  • http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./private")))) — 静态目录混入敏感文件(no-cred-static-sensitive-file-served-unauth

窄化反例(必须避免)

以下是未授权访问维度的典型窄化误判:

  • "前端不显示该入口 → 后端必然有保护" — 错。前端隐藏不等于后端鉴权,直连 API 即可绕过前端
  • "已测了 admin 路径 → 跳过其他敏感端点" — 错。每个端点的鉴权独立配置(中间件按路由分组 / 按 handler 调用),需按端点账本逐项测,不能用单点结论代表全站
  • "看起来是 healthcheck → 应该是公开的" — 错。healthcheck 可能泄露内部地址、版本号、依赖列表、数据库连接 string、堆栈信息,需逐字段判定敏感度
  • "已在某子系统命中未授权 → 其他子系统假定同样" — 错。跨子系统独立结账,不同子系统由不同团队 / 不同时期开发,鉴权命中率不可推广
  • "返回 200 但内容是 {} → 安全" — 错。需验证是否能从其他参数变体取到敏感数据(如改 GET 为 POST / 加分页参数 / 改 ID)

反例义务(必须遵守)

为什么这里是「必须」:反例义务属于交付契约——"未发现未授权访问"或"鉴权已生效"结论是覆盖完整性的产物声明,缺失反向验证清单会让下游误信"该维度全站安全"。

写"未发现未授权访问"或"全站鉴权已生效"前,产物必须包含:

  • 测过的"应受保护"端点完整清单(按 sink 语义枚举:管理后台 / 内部 API / 调试遗留 / API 文档 / 数据导出 / 健康检查 / 静态敏感文件 / WebSocket 等全部触发线索类别,不按 URL 前缀筛选)
  • 每个端点尝试的认证变体(有凭证基线、无凭证、空凭证、方法变体、路径编码变体、版本变体)
  • 每个端点的对照证据(基线响应 / 无凭证响应 / 空凭证响应 / 关键敏感字段)

清单不完整 → 结论降级为 partial-coverage 并显式声明未覆盖范围(例如:仅测了业务 API、未测 debug / swagger / 静态资源敏感文件)。

闭环验证要求(必须遵守)

通用闭环口径见同根目录 common/closure-verification.md(技能表 path 列同一抽取根下,需要时 read_file 读取)。核心:结论须形成「输入 → 处理 → 真实危害 → 可复核证据」完整证据链;仅凭状态码、跳转、页面轮廓等中间信号最多判 suspected,证明无/空凭证下真实读到敏感数据或写操作回读生效才判 confirmed

实际效果验证方向(至少证明一类)

  • 无凭证读敏感数据:无凭证情况下读取到本应受保护的真实业务数据(含具体字段 / 文件内容)
  • 无凭证执行写操作:无凭证情况下执行了本应受保护的写操作,并通过回读或状态变化证明生效。若该写为不可逆动作(删除/覆盖/批量改),回读证明改走哨兵自证或非破坏差分,不得对真实数据执行(见《破坏性 / 不可逆动作的闭环边界》)
  • 若只有 200、跳转异常或页面轮廓,但未证明真实数据/能力可用,不能给 confirmed

判定标准

现象 判定
无凭证仍可读取敏感数据或执行受限操作 confirmed
行为异常(如 200 空壳响应、含轮廓但无字段)但未证明数据/能力可用 suspected
无凭证返回 401/403/登录跳转且无敏感数据泄露 not vulnerable
只测了部分类型端点(如仅业务 API),未覆盖 debug / swagger / 静态敏感文件 partial-coverage(不得宣称 safe)

不可逆动作例外:上表 confirmed 行涉及删除/覆盖/不可逆写时,按 common/closure-verification.md《破坏性 / 不可逆动作的闭环边界》——不得对真实业务数据执行,改走哨兵自证或非破坏差分,二者都做不到则降 suspected

修复建议

  • 服务端强制执行统一鉴权中间件与资源级授权校验,禁止"漏挂端点"
  • "公开路由"和"受保护路由"做显式分组(白名单公开端点 + 兜底拒绝),禁止隐式放行
  • 调试 / 监控 / API 文档端点不上生产,或加独立鉴权与 IP 白名单
  • 静态资源 Server 的根目录单独隔离,禁止混入 .env / 备份 / 配置文件
  • 关键写操作增加审计日志,便于回溯未授权调用
  • 历史接口做回归测试,确保无凭证访问基线一致返回未授权
Install via CLI
npx skills add https://github.com/Q16G/aster --skill unauthorized-access
Repository Details
star Stars 72
call_split Forks 6
navigation Branch main
article Path SKILL.md
More from Creator