与SSO和 '~' 字符有关的问题

大家好,

最近我发现,如果在用户的个人简介中包含“~”字符,Discourse 会返回一个 base64 解码错误。它可以很好地处理各种其他特殊字符(空格、=、%、&),但不知何故无法处理“~”。

有其他人遇到过这个问题吗?

我的第一反应是我的编码可能不正确,但我还没能弄清楚。

这是我的 Python 编码实现:

return_payload = base64.urlsafe_b64encode(parse.urlencode(params).encode())

然后它(以及所有其他必要信息)被直接放入请求的“sso”中:

resp = requests.post(
       ".../admin/users/sync_sso",
        data={'sso': return_payload, ...}
        headers={...}
)

我已经将我的 Discourse 更新到最新版本(3.5.0.beta1-dev),问题仍然存在。

感谢任何帮助!

2 个赞

它可能应该被修复,但这超出了我的能力范围和技能。但出于纯粹的实际好奇:为什么有人会在简介中使用波浪号?

1 个赞

嗯,这确实是个合理的问题。

我运行着一个多语言论坛,在其他文化中,‘~’经常被使用。例如,在韩语中,它经常用在句末来缓和语气,就像“如果你有任何问题,请告诉我~”一样。

2 个赞

所以这是一个 Bug 报告而不是支持请求?

1 个赞

是吗? Bug 是指已完成但无法正常工作的。这更像是“是否已完成”的问题,如果不是支持问题,则更像是 #feature。

是的,我认为 Bug 是合适的。我相信我正在正确地进行 base64 编码,因此 discourse 也应该能够正确解码。

我认为这是一个漏洞(前提是我们能重现它)

2 个赞

看起来 urlsafe_b64encode 替换了 base64 编码中的一些字符。来自文档

使用 URL 和文件系统安全字母表对 bytes-like object s 进行编码,该字母表在标准 Base64 字母表中用 - 替换 +,用 _ 替换 /,并返回编码后的 bytes。结果仍然可能包含 =

这意味着结果不是标准的 base64,并且与 Discourse 的解码不兼容。

我建议改用普通的 b64encode 函数。如果需要,您的 HTTP 库应能处理 URL 转义。

5 个赞

经过进一步调查,我确实对其进行了错误的编码。

以下是我最终得到的代码,供以后参考:

return_payload = base64.b64encode(parse.urlencode(kwargs).encode("utf-8"))
h = hmac.new(secret.encode("utf-8"), return_payload, digestmod=hashlib.sha256)
resp = requests.post(
       ".../admin/users/sync_sso",
        data={"sso": return_payload, "sig": h.hexdigest()}
        headers={...}
)

如果您正在进行重定向,请确保对 {"sso"...} 进行 parse.urlencode 编码。

感谢 @sam@david 的帮助!

3 个赞

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.