Skip to content

安全防护、审计与运行保障 ​

认证系统持续处理秘密、外部输入和账号控制权变化。防护措施需要对应具体攻击路径,并在依赖故障、缓存滞后和恢复过程中保持明确行为。

威胁与防线 ​

威胁发生条件主要防线
撞库与密码猜测攻击者批量提交候选凭据多维限流、泄露密码拦截、MFA、验证并发限制
账号枚举不同账号状态产生可区分响应公开响应收敛、耗时分析、接口限流
会话固定或盗用已知会话值被保留,或凭据泄露登录轮换、HTTPS、秘密隔离与撤销
CSRF浏览器自动携带凭据,攻击者能诱发请求CSRF Token、来源校验、SameSite 与接口约束
XSS不可信内容在本站执行上下文输出编码、安全模板、必要的 HTML 清洗
OAuth 登录混淆回调未关联正确浏览器和提供方事务绑定、PKCE、state、issuer 与令牌校验
越权与跨租户访问已登录主体访问其他资源对象级授权、租户约束和批量范围检查
恢复入口接管弱恢复路径绕过强认证单次凭据、版本约束、强证明与通知

威胁表是检查入口,不能代替各流程的状态与事务设计。

CSRF:自动携带凭据的代价 ​

Cookie 登录下,浏览器可能在攻击者诱导的请求中携带本站凭据。因此修改邮箱、退出、绑定认证器、刷新登录等状态变更也需要防护,不仅是支付接口。

OWASP CSRF Prevention讨论同步 Token、签名双重提交和来源校验。自有网站可优先使用框架提供的、绑定会话的 CSRF 机制;状态变更使用合适的非 GET 方法,同时精确检查受信来源。

  • Token 从受保护页面或端点取得,在请求头或表单中提交,不放入容易被日志记录的 URL。
  • 缺失或 null 的 Origin 不能直接判定为安全;要由其他有效防护或受控策略决定。
  • SameSite 是额外限制,不覆盖所有同站子域和导航场景。
  • CORS 允许列表不能无条件反射请求 Origin,携带凭据时更要精确配置。

使用显式 Bearer Header 的客户端通常不会被浏览器自动附加该凭据,但 Refresh Token 若放在 Cookie 中,刷新端点仍需独立分析。切换成 JWT 本身不会消除 CSRF。

XSS:HttpOnly 之后仍有风险 ​

HttpOnly 能减少脚本直接读取 Cookie 的机会,但恶意脚本仍可能利用当前会话读取数据、修改资料或发起敏感操作。防护重点是让不可信内容无法成为可执行代码。

按 OWASP XSS Prevention对 HTML、属性、URL 等不同上下文采用合适编码;确需展示富文本时,使用维护中的清洗库。不要把输入过滤当作所有输出上下文的通用替代。

CSP可以进一步约束脚本执行与资源来源,但需要结合实际页面部署与报告逐步验证。它是补充防线,不能用一段宽松策略覆盖 innerHTML、第三方脚本和不安全模板造成的问题。

认证与恢复页面尽量减少第三方脚本。错误收集、埋点、浏览器扩展和截图也可能获取敏感内容;日志脱敏不能只覆盖服务器端。

凭据传输与代理边界 ​

RFC 6750说明 Bearer Token 的持有者可以使用它,应通过受保护传输和规范化载体传递,避免 URL 暴露。对自有 API,优先使用 Authorization: Bearer ...,不在普通查询参数中放访问令牌。

TLS 终止代理之后的链路同样需要受保护。应用只信任已配置代理写入的协议、地址和身份头,清除来自外部的同名头;否则来源校验、限流和安全跳转可能都受伪造输入影响。

会话凭据、Authorization、密码、验证码、恢复链接、TOTP 种子和 Refresh Token 均不进入普通日志。代理、APM、消息队列和错误上报的默认采集也要检查。

安全审计事件 ​

OWASP Logging强调事件需要解释何时、何地、何人、发生了什么。建议采用结构化事件,而不是仅记录“登录接口返回 200”。

json
{
  "event_id": "evt_01",
  "event_type": "auth.session.revoked",
  "occurred_at": "2026-10-30T08:00:00Z",
  "actor_user_id": "user_123",
  "subject_user_id": "user_123",
  "tenant_id": null,
  "session_id": "sess_public_456",
  "reason": "password_reset",
  "result": "success",
  "request_id": "req_789"
}

这里的 session_id 是管理标识,不是可登录的会话凭据。失败登录中对账号是否存在的内部标记应限制访问;不存在账号的标识可以按隐私策略使用受控摘要,而不是长期保存原始输入。

需要审计登录成功与失败、绑定与解绑、密码重置、MFA 更换、刷新重用、退出、封禁、角色修改和客服恢复。管理员代操作同时记录操作者和被操作主体。

关键安全变更与 outbox 事件可在同一事务提交,降低“变更成功但事件丢失”的概率。审计消费者需要去重与受限重试;日志本身设置访问控制、保留策略、完整性保护和导出审批。

依赖故障如何处理 ​

故障建议的受控行为
会话或账号权威状态不可查询受保护操作失败,返回可重试的服务错误
JWKS 刷新失败已知且仍受信的缓存密钥按策略使用,未知密钥拒绝
短信或邮件超时记录发送状态,限频重试,避免重复收费与轰炸
MFA 服务不可用使用已登记备用方式或恢复流程,不自动跳过
事件总线积压监控撤销延迟,敏感操作回查权威状态
审计下游不可用关键事件先可靠落本地事务记录,不能无限吞掉失败

身份无效与依赖故障要在内部区分。依赖故障不应伪装成密码错误而诱导用户反复改密;客户端也不能对 401 无限刷新,形成请求风暴。

指标与告警 ​

建议至少观察:

  • 按认证方式与失败原因聚合的成功率、P95/P99 延迟。
  • 哈希验证并发、内存、排队、被限流请求和验证码费用。
  • OIDC 回调校验失败、未知密钥、刷新重用和恢复请求异常。
  • 封禁到各服务拒绝旧会话的传播延迟。
  • outbox 积压、目录同步延迟与单点退出失败。

用户 ID、邮箱、令牌与会话 ID 不作为指标标签,避免高基数和隐私泄露。告警还要考虑来源变化与误伤,失败数上升可能来自提供方故障,而不全是攻击。

验证与恢复演练 ​

安全验证需要同时覆盖正常路径与绕过路径:

范围必测场景
登录不存在账号、错误密码、长输入、并发验证、限流误伤
一次性凭据重复消费、到期边界、并发提交、旧安全版本
浏览器跨站表单、错误 Origin、XSS 注入点、Cookie 属性
OIDCstate/nonce/issuer 不匹配、重复回调、开放重定向
令牌错误受众、算法替换、过期、刷新重放、密钥轮换
权限跨租户、角色撤销、批量接口、后台任务
故障会话库丢失、备份恢复、事件延迟、提供方停机

备份恢复后特别检查旧会话、旧恢复请求和旧角色是否“复活”。密钥泄露演练应实际验证所有验证方停止接受旧签名,而非只确认签发方已换密钥。

参考资料 ​

工程实践与社区文章 ​