AnythingLLM用户名枚举与密码恢复CVE-2026-21484
AnythingLLM 是一款开源、自托管的企业级私有化 LLM 知识库与对话平台,将内容片段转化为任何LLM在聊天过程中都可参考的上下文。
一、基本情况
AnythingLLM 可以将任意文档 / 数据转化为可对话的私有知识库,且全程数据不离开自有环境,核心价值是零代码搭建私有可对话知识库。
AnythingLLM 专为企业/团队解决本地文档 + 大模型的私有化问答、知识管理需求设计,无需依赖第三方云服务(ChatPDF、Notion AI)。

AnythingLLM 兼顾易用与隐私安全,适合个人快速构建知识问答系统,满足企业团队协作、权限管控需求,兼容本地开源模型、云端 API。
栋科技漏洞库关注到 AnythingLLM 受影响版本中存在一个安全漏洞,该安全漏洞被追踪为CVE-2026-21484,漏洞的CVSS 3.X评分为5.3。
二、漏洞分析
CVE-2026-21484漏洞是存在于在提交e287fab56089cf8fcea9ba579a3ecdeca0daa313之前版本中的安全漏洞
该漏洞源于密码恢复端点会根据用户名是否存在返回不同的错误消息,因此需要启用用户名枚举功能。
1、漏洞代码如下:
server/utils/PasswordRecovery/index.js
@@ -38,7 +38,7 @@ async function recoverAccount(username = "", recoveryCodes = []) {
// because this is a user who has not logged out and back in since upgrade.
const allUserHashes = await RecoveryCode.hashesForUser(user.id);
if (allUserHashes.length < 4)
return { success: false, error: "Invalid recovery codes" };
return { success: false, error: "Invalid recovery codes." };
// If they tried to send more than two unique codes, we only take the first two
const uniqueRecoveryCodes = [...new Set(recoveryCodes)]
@@ -55,7 +55,7 @@ async function recoverAccount(username = "", recoveryCodes = []) {
});
return valid;
});
if (!validCodes) return { success: false, error: "Invalid recovery codes" };
if (!validCodes) return { success: false, error: "Invalid recovery codes." };
const { passwordResetToken, error } = await PasswordResetToken.create(
user.id
2、该漏洞的问题在于
If user exists: "Invalid recovery codes"
If user doesn't exists: "Invalid recovery codes."
Difference is: "."
简单来说,就是
如果用户存在:“恢复码无效”
如果用户不存在:“恢复码无效。”
区别在于:“.”
三、POC概念验证
For existing user:
管理员已设置登录后刷新可查看For non-existing user:
管理员已设置登录后刷新可查看四、影响范围
AnythingLLM 库 < e287fab56089cf8fcea9ba579a3ecdeca0daa313
五、修复建议
AnythingLLM 库 >= e287fab56089cf8fcea9ba579a3ecdeca0daa313
六、参考链接
管理员已设置登录后刷新可查看