sensitive-info-exposure

star 72

敏感信息未脱敏检测 — 检测接口响应、日志回显、导出内容中是否暴露未脱敏敏感信息;适用于用户信息、认证信息、财务信息与系统配置场景。

Q16G By Q16G schedule Updated 6/7/2026

name: sensitive-info-exposure description: 敏感信息泄露检测 — 检测 API 响应、错误回显、日志、响应头、备份/元数据文件中是否暴露未脱敏的 PII / 凭证 / 内部地址 / 系统配置;适用于所有返回业务数据或错误信息的端点。 when-to-use: 当需要检查接口响应、日志回显、导出内容是否暴露未脱敏的 PII/认证/财务/系统配置信息时 allowed-tools: bash,read_file,list_files,rg user-invocable: false

敏感信息泄露检测

成因引用

敏感信息泄露成因:source(任何请求)→ sink(API 响应 / 页面响应 / 错误消息 / 日志 / Set-Cookie / 响应头 / robots.txt / sitemap / HTML 注释 / 缓存 / 备份文件 / 元数据端点 / swagger / git 元数据)。PII / 凭证 / 内部地址 / SQL 错误原文明文返回,无脱敏或最小化暴露。详见同根目录 pentest/web-security-testing/SKILL.md 漏洞成因图谱 · 敏感信息泄露行(不在本 skill 重复成因)。

关键 sink 形态:sink 不仅是"接口返回字段"——响应头、Set-Cookie、错误堆栈、日志查看接口、HTML 注释、JSON-LD、robots.txt 暴露的路径都是同一 sink 范畴。任何"服务端把信息发到客户端可见之处"都属 sink,按"信息是否真实敏感 + 接收方是否应见"判定,而非按字段名筛选。

触发线索(基线检查项)

以下是已知的常见敏感信息泄露触发线索,作为基线起点而非必检硬清单:

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

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

  • 业务列表 / 详情 API:用户列表、订单详情、客服记录、审计列表 — 可能含他人 PII(手机号、邮箱、身份证、卡号)
  • 错误响应:SQL 错误原文、堆栈跟踪、模板渲染错误 — 泄露内部路径 / 类名 / 数据库结构
  • 调试 / 诊断端点/debug/* / /actuator/* / /_info / /metrics — 内部信息全集
  • 元数据端点/swagger.json / /api-docs / /openapi.yaml — 接口结构 + 敏感字段定义
  • 静态文件 / 备份残留/.env / /.git/* / /backup.zip / /db.sql / /.DS_Store — 凭证 + 源码
  • robots.txt / sitemap.xml:暴露内部路径或后台入口
  • HTML 注释 / JSON-LD / 模板渲染产物:源码注释含 TODO / 密钥 / 内部 IP / 调试信息
  • 响应头Server / X-Powered-By / 自定义 X-Internal-* / Set-Cookie 中含可解码的会话 / 令牌信息
  • 日志查看接口:管理后台调试日志中含明文请求体(密码 / token / PII)
  • 缓存控制不当:含敏感数据的响应被 CDN / 浏览器缓存
  • 代码模式:后端代码出现 c.JSON(user) 直接序列化整个 ORM 对象(含 password_hash / secret 字段);或 panic / 错误对象直接 String() 返回响应

思考检查点

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

  • 这个响应的接收方是谁?匿名 / 普通用户 / 低权限角色 / 管理员?字段内容他/她应不应该看到?
  • 脱敏是服务端做的还是前端做的?API 返回的是 133****1234 还是明文 13312341234?前端脱敏不算脱敏。
  • 该业务实体(用户 / 订单 / 工单 / 发票 / 合同)的所有相关 API 是否都查过?同实体不同变体(列表 vs 详情 vs 导出)的脱敏可能不一致。
  • 信息泄露面除了响应 body,是否还包括响应头、Set-Cookie、错误堆栈、HTML 注释、robots / sitemap、缓存控制?
  • 子系统 A 的脱敏方案是否假定可推广到 B/C/D?还是每个子系统都需独立测?

前置条件与安全边界

  • 仅在授权环境与测试数据集执行;命中真实敏感数据时立即停止扩展。
  • 导出 / 列表类接口仅做小样本验证(如 limit=5),禁止批量拉取。
  • 证据留存时必须二次脱敏(如 138****5678),避免二次传播。
  • 错误回显 / 堆栈类信息可直接留存(属于系统内部,不含用户 PII)。
  • 静态备份残留如包含真实凭证,仅证明可访问性后立即停止下载并通报。

检测步骤

Step 1:基线与敏感面探测

  1. 从端点账本(recon-methodology 产出的 endpoint-ledger.jsonl)查询:
    • 所有列表 / 详情 / 导出 API(按业务实体分组:用户 / 订单 / 工单 / 发票 / 合同 / 客服 / 日志 / 审计)
    • 静态资源命中(/.env / /.git/HEAD / /backup.zip / /swagger.json / /robots.txt / /sitemap.xml
    • 调试 / 诊断端点(/debug / /actuator / /_info / /metrics
  2. 用合法账号调用每类基线请求,保存完整响应(含 body / headers / Set-Cookie)
  3. 标记可疑字段(按 PII / 凭证 / 财务 / 内部配置 / 系统标识 五类初分)

Step 2:脱敏与最小化校验

对每个响应字段逐项对照敏感信息基线:

类别 字段示例 期望脱敏形态
身份标识 姓名 / 手机号 / 邮箱 / 身份证 / 护照 / 银行卡 张* / 133****1234 / 110101********1234
认证凭证 密码哈希 / JWT / session ID / API Key / AccessKey / Authorization 完全不返回
地址设备 详细住址 / IP / MAC / 设备 UUID / 定位 仅返回脱敏区域,不返回精准定位
财务业务 CVV / 完整卡号 / 税号 / 交易流水 / 内部备注 CVV 永不返回,卡号脱敏
系统内部 DB 连接串 / 内网地址 / 服务账号 / 私钥 / 内部错误堆栈 完全不返回

Step 3:触发错误回显

  • 构造异常输入(缺字段 / 类型错误 / 超长 / 非法字符)观察错误响应是否含 SQL 原文 / 堆栈 / 内部路径
  • 触发认证异常 / 权限异常观察 WWW-Authenticate / 错误消息是否泄露后端组件版本
  • 触发 5xx 看是否落到默认错误页(含框架版本 / 调试栈)

Step 4:被动面扫描

  • robots.txt / sitemap.xml 是否暴露内部路径或管理后台入口
  • HTML 注释 / <script> 内嵌 JSON / JSON-LD 是否含密钥 / 内部地址 / TODO
  • 响应头 Server / X-Powered-By / 自定义头 / Set-Cookie 是否泄露版本或凭证
  • 缓存控制:含 PII 的响应是否设置 Cache-Control: no-store / private

示例库

正例形态(代码层根因)

  • c.JSON(http.StatusOK, user) 直接序列化整个 ORM 对象,含 password_hash / secret_key 字段(list-api-pii-plaintext-exposure
  • panic(err)c.String(500, err.Error()) 把 SQL 错误原文 / 文件路径返回客户端(error-stacktrace-internal-ip-exposure
  • /.env / /.git/config 等静态文件可访问,含 DB_PASSWORD= / AWS_SECRET_ACCESS_KEY=static-env-file-credential-exposure
  • Set-Cookie: session=<base64 含明文 user_id+role> 而非随机 ID(response-header-token-leak
  • HTML 模板渲染时把整个 user 对象注入 <script>var user = {{.}}</script>,含 password_hash(html-template-object-pii-exposure

窄化反例(必须避免)

以下是敏感信息泄露维度的典型窄化误判:

  • "前端显示已脱敏 133****1234 → 安全" — 错。脱敏必须服务端做。检查 Network 面板里 API 实际返回的是 133****1234 还是明文 13312341234。前端脱敏可被任何拿到接口的攻击者绕过。
  • "已测了用户详情 API → 跳过订单 / 工单 / 客服 API" — 错。每种业务实体的 PII 暴露面独立,订单可能含收货人手机号、工单可能含投诉人身份证、客服记录可能含完整对话原文。
  • "已在子系统 A 测了脱敏方案 → 假定 B/C/D 同样" — 错。跨子系统独立结账;不同团队 / 不同时期开发的子系统,脱敏组件可能完全不同。
  • "返回看起来不是用户数据 → 跳过" — 错。后端配置、内网 IP、错误堆栈、SQL 原文、组件版本、私钥片段、内部账号同样敏感,sink 范围不止 PII。
  • "已隐藏 password / detail 字段 → 安全" — 错。可能在响应头、Set-Cookie、其他 endpoint variant(列表 vs 详情)、HTML 注释、JSON-LD、错误响应、日志查看接口等位置泄露。同实体不同入口需独立测。

反例义务(必须遵守)

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

写"未发现敏感信息泄露"或"已脱敏"前,产物必须包含:

  • 测过的敏感面入口完整清单(按 sink 语义枚举:业务列表/详情/导出 API + 错误响应 + 调试端点 + 元数据 + 静态备份残留 + robots/sitemap + 响应头/Set-Cookie + HTML 注释 + 日志查看;多子系统场景按子系统独立分组结账)
  • 每个入口测过的敏感类别(PII / 凭证 / 财务 / 内部配置 / 系统标识)
  • 每个入口的响应证据(脱敏前后字段对比、响应头快照、错误响应触发样本)
  • 同实体跨变体(列表 vs 详情 vs 导出)的脱敏一致性证据

清单不完整 → 结论降级为 partial-coverage 并显式声明未覆盖范围。

特别警示:以"前端已脱敏"为由判 safe 的,结论降级为 partial-coverage-frontend-only——必须给出 API 真实响应体的明文 / 脱敏证据,否则不得宣称服务端已脱敏。

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

通用闭环口径见同根目录 common/closure-verification.md(技能表 path 列同一抽取根下,需要时 read_file 读取)。核心:完整证据链才判 confirmed,中间信号最多 suspected。本漏洞特有要点:

  • 仅凭"字段名疑似敏感 / 响应含占位 / 字段位置可疑"不得判 confirmed,需证明真实敏感数据被读取
  • 不应获得该信息的接收方(匿名 / 普通用户 / 低权限角色)真实看到完整敏感明文,才构成完整证据链
  • 若只是部分片段、样例值、占位符或不确定是否真实敏感数据,最多 suspected
  • 静态备份残留类(.env / .git)需验证是否真含凭证内容,不仅靠"文件可访问"

判定标准

现象 判定
对外响应稳定返回完整敏感信息明文,且接收方范围不应获得这些真实数据(含响应头/Set-Cookie/错误堆栈/静态文件等任一 sink) confirmed
存在部分敏感字段疑似暴露,或暴露范围 / 真实性仍需进一步确认(如疑似密钥但未验证有效) suspected
敏感字段均按最小暴露原则脱敏,且响应头 / 错误响应 / 静态文件 / 元数据各 sink 都有覆盖证据 not vulnerable
只测了部分入口或部分敏感类别(如仅业务 API,未测错误响应/静态备份) partial-coverage(不得宣称 safe)

修复建议

  • 建立统一脱敏组件,按字段类型强制掩码输出(手机号 / 身份证 / 卡号 / 邮箱 / IP 各有标准脱敏规则),脱敏必须服务端做
  • 响应 DTO 与 ORM 模型分离,禁止直接序列化 ORM 对象;凭证类字段(password / token / secret)从 DTO 层移除
  • 错误响应统一化:生产环境只返回通用错误码 + 唯一 trace_id,详细堆栈写入服务端日志
  • 调试 / 诊断 / 元数据端点(/debug / /actuator / /swagger)生产环境关闭或加强鉴权
  • 静态资源服务禁止暴露 .env / .git / .DS_Store / 备份文件,CI 阻断包含敏感文件的发布
  • 响应头最小化:移除 Server / X-Powered-By;Set-Cookie 使用随机不可解码的 session ID
  • 缓存策略:含 PII 的响应强制 Cache-Control: no-store,CDN 配置排除敏感路径
  • 按角色最小化返回字段(如普通用户列表不返回他人手机号),导出接口做二次审计与审批
Install via CLI
npx skills add https://github.com/Q16G/aster --skill sensitive-info-exposure
Repository Details
star Stars 72
call_split Forks 6
navigation Branch main
article Path SKILL.md
More from Creator