← [ BACK_TO_NOTES ]

Web 认证与浏览器安全边界

用信任链把 HTTP 语义、浏览器凭证、Authentication、Session/Token 生命周期、Authorization、CORS/CSRF/XSS 与安全响应头分层,避免把登录、JWT、Cookie 与浏览器安全混成一个问题。

#synthesis #growing #security #browser #http

[!info] related notes

Web 认证与浏览器安全边界

一张总图

一个 Web 请求要经过的不是“Token 对不对”这一关,而是多层信任链:

HTTP method / request contract
        ↓
browser transport / cookie / origin rules
        ↓
credential validation
        ↓
Authentication principal
        ↓
session / token lifecycle authority
        ↓
Authorization
        ↓
resource ownership / policy
        ↓
application action
        ↓
browser-side rendering / security policy

不同层回答不同问题。

1. HTTP 层:请求想做什么

HTTP method 先表达操作语义。GET 属于 safe + idempotent;POST 默认不保证幂等。

这一层决定哪些操作适合自动 retry、哪些操作需要 idempotency key,以及 crawler / prefetcher 是否可能安全访问。

它与“当前用户是谁”是不同问题。详见 HTTP 方法语义 与 GET vs POST。

2. Browser Transport:浏览器怎样携带凭证

浏览器可能通过 Cookie 自动携带,或由 JavaScript 设置 Authorization Header,也可能通过 WebAuthn / Passkey 等浏览器 API 完成认证交互。

Cookie 是浏览器存储/发送机制,不等于 Session。详见 Cookie、Session、Token 与 JWT 的关系。

3. Same-Origin / CORS:脚本能否跨源读取

Same-Origin Policy
→ 默认隔离跨源脚本能力

CORS
→ 服务器声明哪些跨源脚本可以读取 HTTP response

CORS 不回答用户是谁、是否有权限,也不等于 CSRF 防御。详见 CORS。

4. Authentication:这个请求代表谁

Authentication 的输出应是可信 principal:

credential
→ validate
→ authenticated principal

例如 user_id、tenant_id、session_id、scopes。

后续业务代码应依赖已经验证的 principal,而不是信任客户端自己提交的 body.user_id 或 query.owner_id。

5. Credential Entry:密码登录不是一次 Hash Compare

在建立 principal 之前,password authentication 还要经历一层在线攻击防御:

username / password input
→ account existence-safe lookup
→ password verifier
→ per-account + per-source throttling
→ breached/common-password policy(创建/改密阶段)
→ MFA / step-up when required
→ authenticated principal

这里要区分三类攻击:

  • Brute Force:一个账号尝试大量密码;
  • Password Spraying:少量常见密码横向尝试大量账号;
  • Credential Stuffing:拿其他站点泄漏的真实账号密码对来复用。

因此:

one IP rate limit
≠ complete login defense

five failures lock account
≠ complete login defense

真实系统需要 account、IP/device、跨账号扫描、风险信号等多维控制,并避免固定锁号被反向利用制造 DoS。

详见 在线密码攻击 与 认证限速与锁定。

6. Session / Token:登录状态怎样持续

Stateful Session

opaque session credential
→ session store lookup
→ principal

优势是 revoke 可立即生效、session/device 管理明确;代价是每请求依赖共享状态。

Stateless Access Token

signed short-lived token
→ local validation
→ principal

优势是普通请求不需要 session lookup;代价是已签发 token 通常在过期前仍有效。

Hybrid

ordinary API
→ short-lived Access Token

refresh / logout / revoke
→ durable Session / Grant authority

它把高频访问快路径与长期登录生命周期分开。完整关系见 Stateful、Stateless 与 Hybrid 认证架构。

Session 不是一个 Boolean

登录成功后,Session 最好不只保存:

user_id

还应能表达:

session_id
created_at / last_seen_at
auth_time
authentication methods
mfa_verified_at / assurance
device/browser context
risk state
revoked_at

于是系统可以区分:

session live
≠ auth fresh
≠ device trusted
≠ high-risk action allowed

Active Session、Trusted Device 和 Login History 也应基于这些状态分别投影,而不是全塞进一个“device_id”。

详见 Active Sessions & Device Management。

Trusted Device 只是受控便利信任

remember this device

通常表示:

strong authentication completed
→ issue revocable remembered-device credential
→ future low-risk login can reduce MFA friction

Browser fingerprint、IP、UA 只能作为 risk signal,不自动成为新的认证 factor。

高风险动作仍应检查 近期认证与 Assurance。

Security Events / Risk

认证系统还需要记录和关联:

login success/failure
new device
MFA failure
recovery
credential change
session revoke
suspicious login

这些事件可以驱动 Risk-Based Authentication:

low risk → allow
medium risk → step-up
high risk → deny / recovery / alert

而用户可见 Login History 只是内部安全事件的最小化投影。

7. JWT:格式,不是架构

JWT 回答 Token 怎样携带 claims 并被签名验证。

它不自动回答是否存在服务器 Session、revoke 是否即时、Refresh Token 怎样存、用户当前是否仍有资源权限。

JWT valid
≠ session live
≠ user exists
≠ resource authorized

详见 JWT。

8. Refresh:长期 credential lifecycle

Refresh Token 真正的安全问题是 storage、rotation、replay detection、family/session revoke 与 atomic single-winner transition。

详见 Refresh Token。

9. Authorization:身份已知以后能做什么

Authentication 回答你是谁;Authorization 回答你能对这个资源做什么。

典型层次:

principal
→ coarse role/scope
→ resource ownership
→ policy / business rule

前端隐藏按钮不是安全边界,真正约束必须发生在服务器端。

10. Resource Ownership / BOLA

如果接口只允许用户访问自己的对象,resource_id 必须和可信 principal / tenant policy 一起进入查询或授权判断。

知道资源 ID 不等于获得权限。

11. CSRF:借自动携带凭证发请求

CSRF 常和浏览器自动携带 credential 有关。防御可能组合 SameSite、CSRF Token、Origin/Referer validation 与正确的 HTTP method。

CORS 不能替代 CSRF 防御。详见 CSRF 与 XSS vs CSRF。

12. XSS:数据越过代码执行边界

XSS 的核心不是有没有 script 字符串,而是不可信数据是否进入 dangerous HTML / JS / URL sink。

防御包括 context-aware escaping、安全渲染、sanitization 与 CSP defense in depth。详见 XSS。

13. Security Headers:浏览器纵深防御

CSP
→ 哪些资源/脚本可以加载执行

HSTS
→ 以后必须走 HTTPS

X-Content-Type-Options
→ 不要 MIME sniff

frame-ancestors / X-Frame-Options
→ 谁可以 frame 当前页面

Referrer-Policy
→ 跨站时泄露多少来源 URL

它们不能替代 Authentication、Authorization 或输入验证。

14. Error Boundary:不要把内部失败直接暴露

安全相关错误仍需要稳定公共契约:401 表示未建立有效身份,403 表示身份已知但不允许,404 有时用于隐藏资源存在性,409 表示状态冲突。

内部 DB error、stack、provider details 应进入安全日志,而不是原样返回浏览器。详见 稳定 API 错误模型。

15. Recovery:另一条 Authentication Path

Account Recovery 不是 Authentication 之外的“辅助设置”。

它实际上是:

normal authenticators unavailable
→ alternate proof
→ bind/change credentials
→ restore account access

所以 Recovery 的 assurance 如果显著低于主认证,攻击者会绕开:

Password + MFA

直接攻击:

Forgot Password / MFA Reset / Email Change / Helpdesk

设计时应单独检查:

  • request enumeration;
  • reset-token entropy / single-use / expiry;
  • recovery channel assurance;
  • MFA recovery;
  • session/refresh revocation;
  • security notifications;
  • reauthentication after recovery。

详见 Password Reset & Account Recovery。

16. 最小设计检查表

设计 Web Auth 时依次回答:

  1. 请求使用什么 HTTP method?
  2. credential 存在哪里、怎样发送?
  3. 谁验证 credential?
  4. Authentication 输出什么 principal?
  5. 登录 lifecycle 的 authority 在哪里?
  6. Access credential 多久失效?
  7. revoke 多久生效?
  8. Refresh 是否 rotation / replay-safe?
  9. resource authorization 在哪里执行?
  10. Browser 是否有 CSRF/XSS/CORS 风险?
  11. 哪些 security headers 是 defense in depth?
  12. 错误如何安全投影到 HTTP?
  13. Password 登录是否有 account-level + source-level throttling?
  14. 是否区分 brute force、password spraying 与 credential stuffing?
  15. MFA/recovery/step-up 的 assurance boundary 在哪里?
  16. Password/MFA/Email recovery 完成后,哪些 Session/Refresh/remembered-device credential 必须撤销或降级?
  17. Session live、auth fresh、device trusted、risk low 为什么是四个不同判断?
  18. 哪些认证事件应进入内部 Security Event Log,哪些只适合投影给用户?

学习检查

不看正文:

  1. Cookie、Session、JWT、Access Token、Refresh Token 分别处在哪一层?
  2. 为什么 JWT valid 不能推出当前 resource authorized?
  3. Stateful 与 Hybrid 的 revoke semantics 有什么差异?
  4. CORS 与 CSRF 分别控制什么?
  5. 为什么 HttpOnly 能降低一种 XSS 风险,却不能自动防 CSRF?
  6. Authentication principal 为什么不能来自 body.user_id?
  7. Security Headers 为什么属于 defense in depth,而不是认证系统?
  8. 给一个浏览器登录后删除订单的请求,按 HTTP → credential-entry defense → authn → session/token → authz → browser security 画完整链路。
  9. 为什么 per-IP rate limit 与固定 5 次锁号都不能单独作为完整 Password 登录防线?
  10. MFA 为什么降低 credential stuffing 的直接接管风险,却不能替代 Password Policy 和 recovery security?
创建于 2026/9/10 更新于 2026/9/30
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本