使用allowlisted_jwts表主键作为JTI的潜在风险探讨
使用数据库主键作为JWT的JTI(替代随机字符串列)的风险分析
我查阅了devise-jwt文档的Allowlist章节,想搞明白用表主键作为JTI(JSON Token Identifier),而非随机值专用字符串列的实际弊端。
如果给每个签发的JWT都在允许列表中添加一条记录,主键确实能保证唯一性、长度更短且索引查询更快,但它是自增的,很容易被猜测。我有两个核心疑问:
- 可被猜测的JTI属于严重风险吗?
- 若JTI是简单自增值,但JWT采用RS256(或更安全的算法)签名,且包含IAT(签发时间)、ISS(签发者)、AUD(受众)、EXP(过期时间)等完整声明,可能存在哪些攻击场景?
文档中的示例迁移代码如下:
def change create_table :allowlisted_jwts do |t| t.string :jti, null: false #<-- what makes this better than the table's PKEY? t.string :aud # If you want to leverage the `aud` claim, add to it a `NOT NULL` constraint: # t.string :aud, null: false t.datetime :exp, null: false t.references :your_user_table, foreign_key: { on_delete: :cascade }, null: false end add_index :allowlisted_jwts, :jti, unique: true end
核心风险与攻击场景分析
1. 可猜测JTI的风险等级
可猜测的JTI不算极端严重,但会引入不必要的攻击面,具体取决于系统安全边界:
- 若系统的允许列表操作API(比如手动吊销令牌的接口)存在权限校验漏洞,攻击者可通过猜测自增JTI批量吊销其他用户的有效令牌,引发拒绝服务问题。
- 即便未暴露允许列表操作API,攻击者也能通过猜测JTI试探系统令牌签发规律,或增加数据库无效查询负载。
2. 结合RS256签名与完整声明后的攻击场景
即便JWT有强签名和完整声明,自增JTI仍可能带来以下风险:
- 针对性令牌吊销攻击:若攻击者通过XSS等方式窃取了某用户的有效令牌,且知晓系统用自增JTI,可猜测该用户的其他未过期令牌JTI,若吊销接口权限控制不严,就能批量注销该用户所有会话,迫使用户重新登录。
- 敏感信息泄露:自增JTI会泄露系统令牌签发数量、频率等信息,攻击者可通过JTI增长速度推断用户活跃情况、业务峰值,为后续定向攻击做准备。
- 数据库枚举攻击:若令牌有效性验证的内部逻辑未做速率限制,攻击者可批量猜测JTI枚举数据库中的有效令牌记录,虽无法直接获取令牌内容,但能知晓哪些JTI对应未过期令牌,结合其他信息(如用户ID)展开进一步攻击。
3. 文档推荐专用随机JTI列的原因
文档示例用专用jti字符串列而非主键,核心原因是:
- 不可预测性:随机生成的JTI(如UUID)无法被猜测,从根源上避免枚举、针对性吊销等风险。
- 灵活性:JTI可独立于数据库主键规则,比如使用全局唯一UUID,支持跨服务的令牌允许列表同步。
- 安全冗余:即便后续系统权限控制出现漏洞,随机JTI也能大幅降低攻击者利用漏洞的成功率。
内容的提问来源于stack exchange,提问作者theycallmethesloth
相关产品推荐
相关产品推荐

