#1033·kutt

当电子邮件以数字开头(例如 [email protected])时,OIDC 身份验证会失败

作者: claudioguolo创建于 2026年8月7日更新于 2026年8月7日

环境 Kutt 版本: 3.2.6 数据库: PostgreSQL 14 身份验证: OIDC (Microsoft Entra ID) 部署: OpenShift 官方 Docker 镜像 描述 我们在 OIDC 身份验证期间发现了一个问题,当经过身份验证的用户的电子邮件地址以数字开头时,该问题会出现。 示例: [email protected] OIDC 身份验证成功,但登录后 Kutt 立即返回: OIDC 身份验证失败 PostgreSQL 日志显示: 错误: 无效的输入语法,类型为整数: "[email protected]" 根本原因 这个问题是由于使用 parseInt() 来确定用户过滤器是否表示数字用户 ID 或电子邮件地址引起的。 当前实现: 如果 (params?.user) { const id = parseInt(params.user); 如果 (Number.isNaN(id)) { query[knex.compatibleILIKE]("users.email", "%" + params.user + "%"); } 否则 { query.andWhere("links.user_id", params.user); } } 问题在于: parseInt("[email protected]") 返回: 12345 而不是 NaN。 因此, Kutt 假定该值是数字用户 ID,但仍将原始电子邮件字符串发送给 PostgreSQL: WHERE links.user_id = '[email protected]' 由于 links.user_id 是整数列, PostgreSQL 会引发: 错误: 无效的输入语法,类型为整数 PostgreSQL 日志 错误: 无效的输入语法,类型为整数: "[email protected]" 语句: select ... from "links" left join "domains" ... left join "users" ... where "links"."user_id" = $1 同一个问题也发生在计数查询中: select count(*) from links ... where links.user_id = $1 受影响的文件 相同的逻辑存在于: server/queries/link.queries.js totalAdmin() getAdmin() 以及可能存在类似代码在: server/queries/domain.queries.js 建议的修复 而不是依赖于 parseInt(),验证整个字符串是否为数字。 例如: const isNumericId = /^\d+$/.test(params.user); 如果 (isNumericId) { query.andWhere("links.user_id", Number(params.user)); } 否则 { query[knex.compatibleILIKE]("users.email", %${params.user}%); } 或任何等效验证,只接受完全由数字组成的值。 如何重现 配置 OIDC 身份验证。 使用电子邮件以数字开头的帐户进行身份验证。 示例: [email protected] 登录在身份提供商中成功。 用户被重定向到 Kutt。 Kutt 显示: OIDC 身份验证失败 PostgreSQL 日志包含: 错误: 无效的输入语法,类型为整数 预期行为 Kutt 应识别: [email protected] 作为电子邮件地址,而不是将其解释为数字用户标识符。 附加说明 在调查期间,我们验证了以下事实: OIDC 身份验证在 Microsoft Entra ID 中成功完成。 回调正确地到达 Kutt。 PostgreSQL、Redis 和 OpenShift 正常运行。 失败只发生在应用程序尝试检索经过身份验证的用户的链接时。 根本原因是使用 parseInt() 来区分

内容来源: thedevs-network/kutt