From 7d792933ddc2e092177dfceec66f8b9610dd9b26 Mon Sep 17 00:00:00 2001 From: kfluous Date: Sat, 5 Sep 2026 18:28:39 +0800 Subject: [PATCH] fix(auth): allow non-empty short access passwords Co-authored-by: HiFox Agent --- docs/auth-portainer.md | 5 +++-- src/server/auth/config.ts | 2 +- src/server/auth/password.test.ts | 4 +++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/auth-portainer.md b/docs/auth-portainer.md index f764b38..71f61f0 100644 --- a/docs/auth-portainer.md +++ b/docs/auth-portainer.md @@ -22,7 +22,7 @@ environment: | 名称 | 固定密码模式 | SSO 模式 | | --- | --- | --- | | BI_AUTH_MODE | password | sso | -| BI_AUTH_PASSWORD | 独立随机密码,至少 16 字符 | 留空 | +| BI_AUTH_PASSWORD | 非空密码,允许短密码,推荐独立随机密码 | 留空 | | JWT_SECRET | 独立随机密钥,至少 32 字符 | 保留部署专用密钥 | 不要把真实密码提交进 Git。Portainer 中填写的 Stack 变量必须通过上面的 environment 映射才能进入容器。 @@ -36,7 +36,8 @@ environment: - 会话有效期 8 小时。更换密码、JWT_SECRET 或切换模式后,原密码会话失效。 - 每个服务实例 15 分钟最多 20 次密码验证请求;多副本需在网关配置共享限流。共享限流可能被恶意请求耗尽,建议只在内网或受控网络开放。 - 外网必须使用 HTTPS,避免明文传输密码和令牌。密码/环境变量对拥有容器管理权限的人可见。 -- 密码少于 16 字符或签名密钥少于 32 字符时拒绝登录;无默认访问密码。不要沿用镜像中的旧默认 JWT_SECRET。 +- 密码为空或全为空白,或签名密钥少于 32 字符时拒绝登录;无默认访问密码。不要沿用镜像中的旧默认 JWT_SECRET。 +- 短密码容易被猜中,仅建议在内网或受限访问环境使用;登录限流保持开启。 - DB_READ_ONLY=1 时密码登录仍可用,业务写入仍被禁止。 - 测试未登录访问、错误密码、正确密码、刷新恢复会话;切回 sso 后检查跳转登录。 - 开发免登录仅 SSO 开发模式生效,生产必须保持 DEV_BYPASS_AUTH=0。 diff --git a/src/server/auth/config.ts b/src/server/auth/config.ts index f5e7253..91b9966 100644 --- a/src/server/auth/config.ts +++ b/src/server/auth/config.ts @@ -11,7 +11,7 @@ export function authMode() { export function passwordConfig() { const password = process.env.BI_AUTH_PASSWORD || ''; const secret = process.env.JWT_SECRET || ''; - if (password.length < 16 || secret.length < 32) throw new Error('Password authentication is not configured securely'); + if (!password.trim() || secret.length < 32) throw new Error('Password authentication is not configured securely'); return { password, key: createHmac('sha256', secret).update(`bi-password:${password}`).digest('hex') }; } diff --git a/src/server/auth/password.test.ts b/src/server/auth/password.test.ts index 31b567f..0d4b2e1 100644 --- a/src/server/auth/password.test.ts +++ b/src/server/auth/password.test.ts @@ -12,7 +12,7 @@ test('固定密码模式默认关闭、失败限流、只读权限及换密失 try { delete process.env.BI_AUTH_MODE; process.env.JWT_SECRET = 'test-signing-secret-with-at-least-32-characters'; - process.env.BI_AUTH_PASSWORD = 'test-password-only-123456'; + process.env.BI_AUTH_PASSWORD = 'short'; process.env.DEV_BYPASS_AUTH = '0'; const app = new Hono(); app.use('/api/*', readOnlyMiddleware); @@ -48,6 +48,8 @@ test('固定密码模式默认关闭、失败限流、只读权限及换密失 process.env.BI_AUTH_MODE = 'password'; delete process.env.BI_AUTH_PASSWORD; assert.equal((await login('')).status, 503); + process.env.BI_AUTH_PASSWORD = ' '; + assert.equal((await login(' ')).status, 503); process.env.BI_AUTH_PASSWORD = 'a-different-password-123456'; for (let i = 0; i < 20; i++) await login('wrong'); assert.equal((await login(process.env.BI_AUTH_PASSWORD)).status, 429);