#12645·zitadel

[错误]: 当 `response_mode=fragment` 时,重定向中 `state` 会被双重 URL 编码

作者: jhartman-mvi创建于 2026年8月26日更新于 2026年9月17日

飞行前核对清单

  • 在文件、现有问题或讨论中找不到解决办法
  • 我加入了ZITADEL聊天

环境

自办

翻译:

4.17.1(也转载于4.1.6.)

QQ 数据库

赞美音乐

QQ 数据库版本

页:1

描述这个错误造成的问题

当通过“reswer mode=fragment”返回授权响应时,“状态”参数是: 百分率编码了第二次。 包含需要编码字符的 " 状态 " 值将出现 带回 QQ 本身编码, 所以解码片段 一次产生不同的字符串 委托人送来的

同一请求** 未经**答复-mode= flagment'(Zitadel后来默认query')返回 `状态 ' 是正确的,因此缺陷似乎仅限于碎片组装。

这打破了任何验证状态 ' 的客户端与缓存值——这是每个符合的值。 OAuth客户,因为国家 ' 是CSRF的辩护人。 失败是沉默的:客户端无法匹配 对它待决请求的答复,因此它没有错误地丢弃它,而且通常应用 似乎没有诊断结果的"重定向"

Base64- 编码的 " 状态 " 值是野外常见的情况( 许多库编码了一个 JSON 对象) 并依凭于 =,所以这个是容易达到的。

###来再生.

任何OIDC应用程序(使用用户代理/PKCE应用程序复制). 发送其价值包含 需要编码的字符 - 这里的“ PADTEST ” , 作为“ PADTEST% 3D% 3D ” 发送 :

1. 加上 " 答复-模度=分解 " ——不正确

获得/oauth/v2/授权
* 客户 id % 客户- id>
响应  类型=代码( S)
镜像=开口( S)
% 2F% 2F 本地主机% 3A3001% 2F
& Code  challenge S256 挑战>
代码( C)
响应( S)
状态( S) = PADTEST% 3D% 3D

重定向为:

http://localhost:301/#code=. & state=PADTEST% 253D% 253D 互联网档案馆的存檔,存档日期2013-12-20.

2. 同文请求,Resign-mode'省略了(不履行query')——正确

http://localhost:301/?code=.&state=PADTEST%3D%3D 互联网档案馆的存檔,存档日期2011-10-02.

预期行为

在碎片中返回的 " 状态 " 应解码为客户发送的准确值:

#code=. & 状态=PADTEST% 3D% 3D = 解码为PADTEST ==

实际:

#code=. & 状态=PADTEST% 253D% 253D 解码为PADTEST% 3D% 3D

QQ 屏幕截图

n/a——可从地址栏复制。

++ 附加上下文

  • 转载于v4.16.0v4.17.1,通过正式`Docker-compose ' 堆栈自备。 并启用“让我们加密”覆盖, 登录 v2 。
  • 用于浏览器流的硬码片段的客户端无法围绕此工作. 举个例子 XAzure/msal-浏览器在公开请求类型中故意省略 " 反应模式 " (直接请求'、Popup请求'、SsoSilent请求'、Omit ' 、`Resignation Mode'等) 因为一个片段没有发送到服务器,所以将授权代码保留在服务器之外 日志和“参考”标题。 对于这些客户来说,没有 . . . . . . .

内容来源: zitadel/zitadel