From a953bda39a146cb90f01a14ea3d4b21ba54df643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=BB=E5=8B=87=E7=A5=A5?= <237899745@qq.com> Date: Tue, 11 Nov 2025 13:17:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=89=E5=85=A8:=20=E4=BF=AE=E5=A4=8DJWT?= =?UTF-8?q?=E5=AF=86=E9=92=A5=E4=BD=BF=E7=94=A8=E9=BB=98=E8=AE=A4=E5=80=BC?= =?UTF-8?q?=E7=9A=84=E5=AE=89=E5=85=A8=E9=9A=90=E6=82=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题描述: - JWT_SECRET使用硬编码默认值,存在严重安全风险 - 生产环境token可被轻易伪造 修复内容: 1. 在auth.js中添加JWT密钥安全检查 - 检测默认密钥并发出警告 - 生产环境强制要求设置JWT_SECRET 2. 更新.env.example添加JWT_SECRET配置说明 - 提供密钥生成方法 - 添加其他安全配置项 3. 优化deploy.sh部署脚本 - 自动生成随机JWT密钥 - 检测并替换默认密钥 影响范围: 安全认证模块 测试建议: - 启动服务验证JWT_SECRET警告正常显示 - 使用deploy.sh部署验证自动生成密钥 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- backend/.env.example | 28 +++++++++++++++++++++---- backend/auth.js | 34 +++++++++++++++++++++++++++++- deploy.sh | 50 ++++++++++++++++++++++++++++++++++++++------ 3 files changed, 101 insertions(+), 11 deletions(-) diff --git a/backend/.env.example b/backend/.env.example index 80aa116..086189c 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -1,8 +1,28 @@ -# FTP服务器配置 +# 服务器配置 +PORT=40001 +NODE_ENV=production + +# JWT安全密钥 (必须设置!使用随机字符串) +# 生成方法: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" +JWT_SECRET=your-secret-key-change-in-production-PLEASE-CHANGE-THIS + +# 管理员账号配置 +ADMIN_USERNAME=admin +ADMIN_PASSWORD=admin123 + +# 存储根目录(本地存储模式) +STORAGE_ROOT=/app/storage + +# CORS允许的来源(多个用逗号分隔,* 表示允许所有) +# 生产环境建议设置为具体域名,例如: https://yourdomain.com,https://www.yourdomain.com +ALLOWED_ORIGINS=* + +# Cookie安全配置 +# 如果使用HTTPS,设置为true +COOKIE_SECURE=false + +# FTP服务器配置(可选,用户可在界面配置) FTP_HOST=your-ftp-host.com FTP_PORT=21 FTP_USER=your-username FTP_PASSWORD=your-password - -# 服务器配置 -PORT=3000 diff --git a/backend/auth.js b/backend/auth.js index 28f95f9..d5c65ee 100644 --- a/backend/auth.js +++ b/backend/auth.js @@ -1,9 +1,41 @@ const jwt = require('jsonwebtoken'); const { UserDB } = require('./database'); -// JWT密钥(生产环境应该放在环境变量中) +// JWT密钥(必须在环境变量中设置) const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-in-production'; +// 安全检查:验证JWT密钥配置 +const DEFAULT_SECRETS = [ + 'your-secret-key-change-in-production', + 'your-secret-key-change-in-production-PLEASE-CHANGE-THIS' +]; + +if (DEFAULT_SECRETS.includes(JWT_SECRET)) { + const errorMsg = ` +╔═══════════════════════════════════════════════════════════════╗ +║ ⚠️ 安全警告 ⚠️ ║ +╠═══════════════════════════════════════════════════════════════╣ +║ JWT_SECRET 使用默认值,存在严重安全风险! ║ +║ ║ +║ 请立即设置环境变量 JWT_SECRET ║ +║ 生成随机密钥: ║ +║ node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" +║ ║ +║ 在 backend/.env 文件中设置: ║ +║ JWT_SECRET=你生成的随机密钥 ║ +╚═══════════════════════════════════════════════════════════════╝ + `; + + if (process.env.NODE_ENV === 'production') { + console.error(errorMsg); + throw new Error('生产环境必须设置 JWT_SECRET!'); + } else { + console.warn(errorMsg); + } +} + +console.log('[安全] JWT密钥已配置'); + // 生成JWT Token function generateToken(user) { return jwt.sign( diff --git a/deploy.sh b/deploy.sh index f87f06f..21766d3 100644 --- a/deploy.sh +++ b/deploy.sh @@ -45,21 +45,55 @@ echo "📂 创建必要的目录..." mkdir -p certbot/conf mkdir -p certbot/www mkdir -p backend/uploads +mkdir -p storage echo "✓ 目录创建完成" echo "" -# 检查.env文件 +# 检查.env文件并生成JWT密钥 +echo "🔐 配置环境变量..." if [ ! -f "backend/.env" ]; then - echo "⚠️ 警告: backend/.env 文件不存在" + echo "⚠️ backend/.env 文件不存在,正在创建..." + if [ -f "backend/.env.example" ]; then - echo "正在从.env.example创建.env文件..." cp backend/.env.example backend/.env - echo "✓ 已创建.env文件,请根据需要修改配置" + echo "✓ 已从.env.example创建.env文件" else - echo "⚠️ 建议创建.env文件配置JWT密钥等参数" + echo "⚠️ .env.example不存在,创建基础配置" + cat > backend/.env << 'ENVEOF' +PORT=40001 +NODE_ENV=production +ADMIN_USERNAME=admin +ADMIN_PASSWORD=admin123 +STORAGE_ROOT=/app/storage +ALLOWED_ORIGINS=* +COOKIE_SECURE=false +ENVEOF + fi + + # 生成随机JWT密钥 + echo "🔑 生成随机JWT密钥..." + JWT_SECRET=$(openssl rand -hex 32 2>/dev/null || cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 64 | head -n 1) + + # 替换或添加JWT_SECRET + if grep -q "^JWT_SECRET=" backend/.env; then + sed -i "s|^JWT_SECRET=.*|JWT_SECRET=$JWT_SECRET|" backend/.env + else + echo "JWT_SECRET=$JWT_SECRET" >> backend/.env + fi + + echo "✓ JWT密钥已生成并保存" +else + echo "✓ backend/.env 文件已存在" + + # 检查JWT_SECRET是否为默认值 + if grep -q "^JWT_SECRET=your-secret-key" backend/.env; then + echo "⚠️ 检测到JWT_SECRET使用默认值,正在生成新密钥..." + JWT_SECRET=$(openssl rand -hex 32 2>/dev/null || cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 64 | head -n 1) + sed -i "s|^JWT_SECRET=.*|JWT_SECRET=$JWT_SECRET|" backend/.env + echo "✓ JWT密钥已更新" fi - echo "" fi +echo "" # 停止旧容器 echo "🔄 停止旧容器..." @@ -101,6 +135,10 @@ echo " 用户名: admin" echo " 密码: admin123" echo " ⚠️ 请立即登录并修改密码!" echo "" +echo "🔐 安全提示:" +echo " JWT密钥已自动生成,保存在 backend/.env 中" +echo " 请妥善保管该文件!" +echo "" echo "📚 查看日志:" echo " docker-compose logs -f" echo ""