发布于22小时前22小时 在授权渗透测试中,常见问题是:测试账号能否读取其他用户的数据?如果发现异常,怎样证明这是权限边界缺失,而不是测试环境或缓存造成的假象?下面以只读的订单查询接口为例,给出一套可复核、低影响的验证方法。背景与边界假设测试范围已书面确认,目标应用提供 GET /api/orders/{id}。测试方有账号 A 和账号 B,分别只能访问各自的订单。验证前应确认测试环境、账号归属、允许访问的接口和数据范围;只使用预先准备的测试订单,不尝试枚举真实订单编号,也不修改或删除数据。问题定位先用账号 A 读取自己的订单,确认认证正常;再用账号 B 请求同一个订单。若 B 收到订单内容,而不是预期的 403 或 404,就需要进一步排除会话混用、代理缓存和测试数据配置错误。确认两次请求使用不同的 Cookie 或令牌,并分别记录账号、时间和请求 ID。确认订单确实归属 A,且 B 在应用界面中没有访问该订单的授权。使用 GET 等只读请求;不要通过批量改 ID 的方式扩大验证范围。必要时在浏览器开发者工具中核对实际请求,避免复制了错误的环境地址或旧令牌。技术分析与复现步骤下面的命令使用占位符。请将其替换为授权测试环境的地址和测试账号令牌,且仅请求已知的测试订单。命令不会跟随重定向,也不打印完整响应正文,降低意外暴露数据的风险。BASE=' /> ORDER_A='test-order-a-001' # 账号 A:基线请求,应能读取自己的测试订单 curl --silent --show-error --max-redirs 0 \ -H \"Authorization: Bearer $TOKEN_A\" \ -H 'Accept: application/json' \ -H 'Cache-Control: no-cache' \ -D /tmp/order-a.headers \ -o /tmp/order-a.body \ -w 'A status=%{http_code} bytes=%{size_download}\\n' \ \"$BASE/api/orders/$ORDER_A\" # 账号 B:仅对同一个已知测试订单做一次只读授权检查 curl --silent --show-error --max-redirs 0 \ -H \"Authorization: Bearer $TOKEN_B\" \ -H 'Accept: application/json' \ -H 'Cache-Control: no-cache' \ -D /tmp/order-b.headers \ -o /tmp/order-b.body \ -w 'B status=%{http_code} bytes=%{size_download}\\n' \ \"$BASE/api/orders/$ORDER_A\" # 只检查响应类型和缓存相关头,不在终端直接输出业务数据 grep -iE '^(HTTP/|content-type:|cache-control:|x-request-id:)' \ /tmp/order-a.headers /tmp/order-b.headers判断时不要只看 HTTP 状态码。若 B 返回 200,还应在受控环境中核对响应是否包含订单字段,并确认这些字段确属 A 的测试数据。若响应为 404,也应结合应用设计确认这是有意隐藏资源存在性,而非路由错误。响应体应按测试数据处理,记录必要的字段摘要即可,不要把完整个人信息粘贴进工单或公开报告。确认日志留痕在测试时间窗口内,使用响应头中的请求 ID 关联网关和应用日志。日志字段名称会因系统不同而变化,重点核对请求时间、路径、认证主体、响应状态、请求 ID 和上游服务;不要记录完整令牌或不必要的响应正文。# 示例:在 Nginx 访问日志中按请求 ID 或接口路径筛选 grep -E 'api/orders/test-order-a-001|REQ_ID_FROM_RESPONSE' \ /var/log/nginx/access.log # systemd 部署示例:按服务名和测试时间窗口查看应用日志 journalctl -u orders-api \ --since '2025-03-08 10:00:00' \ --until '2025-03-08 10:10:00' \ --no-pager若日志中只有状态码,没有认证主体或请求关联标识,调查时可能无法确认是哪一层放行了请求。建议通过请求 ID 串联反向代理、应用和审计日志,并在日志脱敏后保存证据。测试结束后按约定清理临时响应文件。风险与修复建议服务端逐对象授权:每次读取订单时,都根据已认证主体校验订单归属或明确授予的角色权限;不能仅依赖前端隐藏按钮。避免信任客户端标识:订单 ID 只是资源定位符,不是授权凭证。即使改用随机 ID,也不能替代服务端权限校验。覆盖测试:在自动化测试中建立 A、B 两个主体,验证 A 可读自己的订单、B 无法读取 A 的订单,并覆盖管理员等明确授权的角色。缓存隔离:对含用户数据的响应设置合适的缓存策略,确认代理缓存不会跨用户复用响应。日志与告警:记录主体、资源标识、判定结果和请求 ID;对短时间内大量越权拒绝或异常资源访问进行监测,同时避免记录访问令牌。复测闭环:修复后使用同一组测试账号和测试订单复测,并确认访问被拒绝、正常用户仍能访问自身资源,且日志能完整关联。总结这类验证的关键不是扩大请求量,而是用两个权限边界清晰的测试主体,对同一个已知测试资源做最小化对照,并将响应、授权判定和日志请求 ID 对齐。这样既能提供可复现证据,也能把验证影响限制在授权范围内。 网络请求、日志与边界流量分析示意 侦察、入口、横向移动与权限路径梳理示意
20小时前20小时 建议把“越权是否成立”和“日志能否关联到这次请求”放在同一个用例里验证。仅看返回 200 或 403 不够,最好准备两个同权限测试账号 A、B,以及一个明确归属于 B 的测试对象。 先做横向越权对照:A 访问自己的对象作为基线,再保持 A 的凭证不变,仅将对象 ID 换成 B 的;补一个不带凭证的请求。涉及修改操作时,只用可回滚的测试数据,不要批量枚举真实对象。 # 示例路径和凭证请替换;使用测试环境受信任的 CA,不要关闭 TLS 校验 BASE=' CASE="authz-$(date -u +%Y%m%dT%H%M%SZ)" curl -sS -D response.headers -o response.json \ -H "Authorization: Bearer ${TOKEN_A}" \ -H "X-Test-Case-ID: ${CASE}" \ "${BASE}/api/orders/${ORDER_B}" cat response.headers cat response.json 判断点是:是否返回了 B 的受保护字段,或者实际改变了 B 的数据。403、404 都可能是合理的拒绝方式;200 但响应为空也不能直接判定越权。写接口需要再用 B 的账号或只读数据库查询核对状态,不能只看响应码。纵向越权则用低权限账号直接请求管理接口,别只验证页面是否隐藏按钮。 日志核对要贯穿网关、应用和审计层:记录测试时间、方法、路径、测试对象 ID、响应状态,以及服务端返回的 request_id/trace_id。上面的测试标记只有在网关明确透传、应用明确记录后才有用,不能假设默认会留。客户端标记只用于关联,不应作为身份或可信审计依据。 # 单机文件日志示例;集中日志平台按同样字段检索 grep -F "$CASE" /var/log/nginx/access.log /var/log/app/audit.log 应用侧最关键的是记录认证主体、目标对象、操作、授权决策及拒绝原因,例如: { "request_id": "server-generated-id", "test_case_id": "authz-20260101T090000Z", "actor_id": "test-user-a", "action": "order.read", "resource_id": "test-order-b", "decision": "deny", "reason": "owner_mismatch", "status": 403 } 这里的 actor_id 必须来自服务端校验后的身份,不能取客户端传入的 user_id。不要把完整 Token、Cookie 或敏感响应正文写入日志。如果只有网关访问记录,没有应用层的授权决策,最多能证明“请求到过”,不能确认对象归属校验执行过。最后把允许、拒绝各一条请求及对应日志留作证据,并在修复后用同组用例回归。
创建帐户或登录后发表意见