GH GambleHub

JWT:结构和漏洞

1)什么是JWT,在哪里使用

JWT是以"Base 64Url"格式提供的紧凑型自给自足的声明容器(claims)。Base64Url(payload).Base64Url(signature)`.

用于:
  • JWS(签名令牌-真实/完整性),
  • JWE(加密令牌-隐私),
  • OIDC/OAuth2 作为访问/ID令牌以及服务到服务的身份验证。

优点:自主性、可缓存性、低开销。缺点:错误验证的风险,复杂的召回案例。

2) JWT结构

2.1标题(header, JSON)

最小值:算法和密钥ID。

json
{ "alg": "ES256", "kid": "jwt-2025-10", "typ": "JWT" }

"alg":签名/加密算法(RS256/ES256/PS256/HS256等)。
"kid":指向密钥的指针(用于JWKS轮换)。

可选的密钥来源是"jku","x5u"(请参阅漏洞§6。3).

2.2有效载荷(payload, JSON)

标准化污名:
  • `iss` (issuer), `aud` (audience), `sub` (subject)
  • "exp"(到期时间),"nbf"(不早于),"iat"(发出)
  • "jti"(令牌ID,适合评论)
  • 领域污名:"scope/roles","tenant","kyc_level"等。

2.3签名(签名)

JWS = `sign(base64url(header) + "." + base64url(payload), private_key)`

验证:严格符合公共密钥,完全符合服务器期望的算法。

3)基本验证不变量

1.该算法由资源-服务器配置(allow-list)固定,而不信任内容的"头端"。alg`.

2.检查"iss"和"aud"的精确匹配,"exp/nbf"-考虑一小部分"clock_skew"(± 30-60 s)。
3.仅在单个密钥且没有旋转的情况下拒绝没有"kid"的令牌;否则-要求"孩子"。
4.不信任任何未经对象级别授权的污名(BOLA-first)。
5.Parsing-密码反驳后;解码前的基本尺寸检查。

4) JWS vs JWE

JWS:已签名,但我们正在阅读。不要放在付费的PII/秘密中。
JWE:加密payload;更难整合,关键模型至关重要。
在大多数API中,对付费中的敏感数据的JWS+禁令就足够了。

5)令牌生命周期

访问:短时间(5-30分钟)。
Refresh:更长(7-30天),rotate-on-use(一次性),保留"黑名单"'jti/sid'。
Revocation: TTL的"jti"列表,opaque令牌的内窥镜,事件中"exp"的缩写。
键轮换:重叠的JWKS(旧+新),请参阅"键轮换"文章。

6)频繁的漏洞以及如何关闭它们

6.1 'alg=none'/变换算法

底线:服务器信任"alg"字段并接受未签名的令牌。
保护:服务器上的硬allow-list算法;拒绝"无"和意想不到的含义。

6.2 RS256→HS256交换(对称化)

底线:攻击者将"alg"替换为HS256,并使用公共密钥作为HMAC秘密。
保护:通过配置绑定算法的关键;不要将对称/非对称提供者混为一体"kid"。

6.3键注射("kid/jku/x5u")

脚本:
  • "jku"表示攻击者控制的JWKS(将滑动其密钥)。
  • "x5u"/"x5c"滥用外部证书。
  • 带有路径/SQL注入的"kid"("……/……/privkey。pem""或""OR 1=1-"")。
保护:
  • 忽略已删除的"jku/x5u"或通过严格的allow-list域进行过滤。
  • "kid"仅用作本地目录(表/kesh)中的密钥,没有文件路径/SQL串联。
  • JWKS从受信任的URL,短的TTL,信道签名/插入装载。

6.4微弱的HS256秘密(野蛮人)

底线:HMAC秘密短/鸭→替换签名。
保护:仅在KMS中使用不对称性(RS/ES/PS)或秘密长度≥ 256位,秘密。

6.5缺失/未验证的污名

不"aud"/"iss"/"exp" →令牌交叉服务或无限。
太长的"exp" →损害的风险。
防守:要求全套污名,"exp"短,"nbf"/"iat"用"clock_skew"验证。

6.6 Replay和令牌盗窃

底线:令牌拦截/重播(log泄漏,XSS,MitM没有TLS)。

保护:
  • TLS везде, `Secure`+`HttpOnly` cookie, SameSite=Lax/Strict.
  • 合作伙伴的DPoP/PoP(令牌绑定到客户端密钥)和/或mTLS。
  • 短"exp",refresh旋转,设备绑定。

6.7通过XSS/存储泄漏

底线:JS可以在"localStorage"/"sessionStorage"中存储JWT →。
保护:将访问令牌存储在HttpOnly Cookie(如果可以使用Cookie)+严格的CSP/Trusted Types中。
对于没有Cookie的SPA,可以隔离内存中的令牌,最小程度地生活,并保护XSS。

6.8 CSRF

底线:在Cookie会议中,请求来自第三方网站。
保护:SameSite、anti-CSRF令牌(双submit)、"起源/参考"检查、Fetch-Metadata过滤器。

6.9 Oversize/大小滥用

底线:巨大的薪水/头条,DoS的解析。
保护:标题/主体尺寸限制,早期检索431/413,假粘贴套件。

6.10替代"typ"/"cty"

底线:嵌套的JOSE对象的类型混淆('typ:'JWT')。
保护:为了安全而忽略"typ/cty",依靠固定的算法和粘贴方案。

7)代币的储存和转让

7.1个服务器API(机器到机器)

mTLS/HMAC,最好是JWT的不对称性,渠道是通过mesh。
密钥库是KMS/HSM,定时轮换,重叠的JWKS。

7.2浏览器客户端

HttpOnly Secure Cookie для access/refresh;短的TTL;更新-仅通过HTTPS下的"SameSite=None"通过"silent refresh"。
严格CSP,Trusted Types,防止XSS;对于SPA-如果可能,不要将令牌存储在磁盘上。

8) JWKS,轮换和召回

JWKS由授权者发布;消费者缓存5-15分钟。
轮换计划:添加新的"kid" →开始签名→在N日后从 JWKS → purge中删除旧的。
评论:"jti/sid" c TTL列表;在事件中,暂时缩短"exp"和fors-logout(致残refresh)。

9) Multi-tenant和最小化数据

只有在架构上需要时,才在令牌中包含"tenant"/"org";否则,通过"子"从PDP中拉动属性。
没有PII;最低限度的污名→减少泄漏和污染的风险。

10)实用验证清单(资源服务器)

  • Parsim仅在验证签名和基本尺寸限制之后。
  • "alg"来自配置;拒绝意想不到的。
  • 检查'iss' ∧ 'aud '∧ 'exp' ∧ 'nbf' ∧ 'iat'(带有'clock_skew')。
  • 通过本地目录/JWKS(简称TTL)检查"kid"。
  • 筛选/归一化外部指针("jku/x5u"-仅allow-list")。
  • 限制粘合剂的长度/组成(图)。
  • 应用对象资源授权(BOLA-first)。
  • 标记"kid","sub","aud","iss","jti","exp","tenant","trace_id"(没有PII)。
  • 签名错误,逾期,轮换审核的度量。

11)安全策略示例(伪)

11.1算法期望配置

yaml jwt:
expected_issuer: "https://auth. example. com"
expected_audience: ["wallet-service"]
allowed_algs: ["ES256"] # fix the jwks_url: "https ://auth. example. com/.well-known/jwks. json"
jwks_cache_ttl: 600s clock_skew: 60s required_claims: ["iss","aud","sub","exp","iat"]

11.2远程"jku/x5u"豁免'

yaml reject_untrusted_key_sources: true allowed_jku_hosts: ["auth. example. com"] # if absolutely necessary

11.3评论列表示例(Redis)

pseudo if redis. exists("revoke:jti:" + jti) then deny()
if now() > exp then deny()

12)可观察性和力学

Метрики: `jwt_verify_fail_total{reason}`, `jwt_expired_total`, `jwks_refresh_total`, доля `kid`.

Logs(结构化):'iss/aud/sub/kid/jti/exp/tenant/trace_id'(故障原因)。
Dashbords:"即将到期",验证错误激增,按地区/客户分配。
Alerts: "verify_fail"(签名/算法)、JWKS错误、过期令牌比例的增长。

13)反模式

信任令牌中的"alg";支持"none"。
长寿命的访问令牌和没有refresh旋转。
在没有KMS的ENV中HS256简短的秘密/秘密。
从任何域接受"jku/x5u";动态地加载JWKS而不包含所有列表。
在JWS的付费下载中聚集PII/秘密。
如果存在XSS风险,则将令牌存储在"本地存储"中。
堵塞验证错误(返回200"软错误")。
缺乏BOLA检查,仅依赖"scope/role"。

14) iGaming/财务细节

克莱姆斯:"kyc_level","risk_tier","tenant",严格的"aud"。
用于写作操作(存款/收据),PoP/DPoP或mTLS的短TTL用于关键路由。
监管审核:不变的输入/故障日志,在区域范围内存储日志。
合作伙伴/PSP 具有单独的密钥/"aud",主键和单独的JWKS。

15)准备就绪支票清单

  • 硬allow-list算法;"none"被禁止。

[……]对iss/aud/exp/nbf/iat/jti"进行了检查;短的"exp"。

  • 重叠的JWKS,短缓存TTL;监视"kid"份额。
[] Refresh — rotate-on-use;TTL的"jti/sid"列表;评论的花花公子。
  • 关键路线上的PoP/DPoP或mTLS。
  • 浏览器的HttpOnly Cookie,CSP/Trusted Types诉XSS;CSRF保护。
  • 没有付费的PII;一组最小的粘合剂。
  • 关于验证和拒绝的度量/标志;Alerta JWKS/verify_fail。
  • 负面场景测试:RS→HS交换,'kid'注射,'jku' spoofing, oversize, clock-skew。

16) TL;DR

将算法和密钥锁定在服务器端,不要信任令牌中的"alg",要求"iss/aud/exp/nbf/iat/jti"。通过重叠的JWKS轮换钥匙,保持代币短寿命,refresh一次性。安全地存储令牌(Http-Only cookie for Web),尽量减少污名,不要放下PII。关闭"jku/x5u/kid"-vectors,避免使用弱秘密HS256,在关键路径上添加PoP/DPoP或mTLS,并始终对资源级别进行BOLA验证。

Contact

联系我们

如需任何咨询或支持,请随时联系我们。我们随时准备提供帮助!

Telegram
@Gamble_GC
开始集成

Email — 必填。Telegram 或 WhatsApp — 可选

您的姓名 可选
Email 可选
主题 可选
消息内容 可选
Telegram 可选
@
如果填写 Telegram,我们也会在 Telegram 回复您。
WhatsApp 可选
格式:+国家代码 + 号码(例如:+86XXXXXXXXX)。

点击按钮即表示您同意数据处理。