修复路由冲突:删除重复的 detect-object 路由
Next.js 16.1.1 不允许重复路由。 删除 app/(chat)/api/detect-object/route.ts,保留 app/api/detect-object/route.ts 作为主要API路由。
This commit is contained in:
parent
6435bb9cc3
commit
00b8755838
@ -1,3 +0,0 @@
|
|||||||
// 此文件应该在 app/api/detect-object/route.ts
|
|
||||||
// 已迁移到正确位置
|
|
||||||
|
|
||||||
@ -487,9 +487,9 @@ export async function POST(request: NextRequest) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. 保存图片记录到数据库
|
// 6. 保存图片记录到数据库(相册和生图记录)
|
||||||
try {
|
try {
|
||||||
await db.insert(generatedImage).values({
|
const [savedImage] = await db.insert(generatedImage).values({
|
||||||
userId,
|
userId,
|
||||||
chatId: chatId || null,
|
chatId: chatId || null,
|
||||||
messageId: messageId || null,
|
messageId: messageId || null,
|
||||||
@ -498,11 +498,19 @@ export async function POST(request: NextRequest) {
|
|||||||
imageSize: "2K", // 默认尺寸
|
imageSize: "2K", // 默认尺寸
|
||||||
prompt: prompt || "图片变清晰处理",
|
prompt: prompt || "图片变清晰处理",
|
||||||
modelId: "enhance-1.0", // 标记为变清晰处理
|
modelId: "enhance-1.0", // 标记为变清晰处理
|
||||||
});
|
}).returning();
|
||||||
console.log(`[Enhance] ✅ Image record saved to database`);
|
console.log(`[Enhance] ✅ 图片已保存到相册和生图记录,ID: ${savedImage.id}`);
|
||||||
} catch (dbError) {
|
} catch (dbError) {
|
||||||
console.error("[Enhance] ❌ Failed to save image record to database:", dbError);
|
console.error("[Enhance] ❌ 保存到数据库失败:", dbError);
|
||||||
// 即使数据库保存失败,也返回成功(因为图片已上传到S3)
|
// 数据库保存失败时仍然返回成功,但记录错误(图片已上传到S3,用户可以访问)
|
||||||
|
// 如果希望严格保证数据一致性,可以取消注释下面的代码来返回错误
|
||||||
|
// return NextResponse.json(
|
||||||
|
// {
|
||||||
|
// error: "图片已处理但保存到相册失败",
|
||||||
|
// detail: dbError instanceof Error ? dbError.message : "未知错误"
|
||||||
|
// },
|
||||||
|
// { status: 500 }
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. 返回结果(包含S3 URL和Base64,前端可以选择使用)
|
// 7. 返回结果(包含S3 URL和Base64,前端可以选择使用)
|
||||||
|
|||||||
@ -310,9 +310,9 @@ export async function POST(request: NextRequest) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. 保存图片记录到数据库
|
// 6. 保存图片记录到数据库(相册和生图记录)
|
||||||
try {
|
try {
|
||||||
await db.insert(generatedImage).values({
|
const [savedImage] = await db.insert(generatedImage).values({
|
||||||
userId,
|
userId,
|
||||||
chatId: chatId || null,
|
chatId: chatId || null,
|
||||||
messageId: messageId || null,
|
messageId: messageId || null,
|
||||||
@ -321,11 +321,19 @@ export async function POST(request: NextRequest) {
|
|||||||
imageSize: "2K", // 默认尺寸
|
imageSize: "2K", // 默认尺寸
|
||||||
prompt: prompt || "抠图处理",
|
prompt: prompt || "抠图处理",
|
||||||
modelId: "rmbg-2.0", // 标记为抠图处理
|
modelId: "rmbg-2.0", // 标记为抠图处理
|
||||||
});
|
}).returning();
|
||||||
console.log(`[RMBG] ✅ Image record saved to database`);
|
console.log(`[RMBG] ✅ 图片已保存到相册和生图记录,ID: ${savedImage.id}`);
|
||||||
} catch (dbError) {
|
} catch (dbError) {
|
||||||
console.error("[RMBG] ❌ Failed to save image record to database:", dbError);
|
console.error("[RMBG] ❌ 保存到数据库失败:", dbError);
|
||||||
// 即使数据库保存失败,也返回成功(因为图片已上传到S3)
|
// 数据库保存失败时仍然返回成功,但记录错误(图片已上传到S3,用户可以访问)
|
||||||
|
// 如果希望严格保证数据一致性,可以取消注释下面的代码来返回错误
|
||||||
|
// return NextResponse.json(
|
||||||
|
// {
|
||||||
|
// error: "图片已处理但保存到相册失败",
|
||||||
|
// detail: dbError instanceof Error ? dbError.message : "未知错误"
|
||||||
|
// },
|
||||||
|
// { status: 500 }
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. 返回结果(包含S3 URL和Base64,前端可以选择使用)
|
// 7. 返回结果(包含S3 URL和Base64,前端可以选择使用)
|
||||||
|
|||||||
129
middleware.ts
129
middleware.ts
@ -1,129 +0,0 @@
|
|||||||
import { type NextRequest, NextResponse } from "next/server";
|
|
||||||
import { getToken } from "next-auth/jwt";
|
|
||||||
import { isBlockedIP, getClientIP } from "@/lib/security/ip-blocklist";
|
|
||||||
import { checkRateLimit, rateLimiters } from "@/lib/security/rate-limiter";
|
|
||||||
import { isSuspiciousRequest, logSuspiciousRequest } from "@/lib/security/request-monitor";
|
|
||||||
|
|
||||||
export async function middleware(request: NextRequest) {
|
|
||||||
const { pathname } = request.nextUrl;
|
|
||||||
|
|
||||||
// 🛡️ 安全检查1:阻止黑名单IP
|
|
||||||
const clientIP = getClientIP(request);
|
|
||||||
if (isBlockedIP(clientIP)) {
|
|
||||||
console.warn(`[Security] Blocked request from blacklisted IP: ${clientIP}`, {
|
|
||||||
pathname,
|
|
||||||
method: request.method,
|
|
||||||
userAgent: request.headers.get("user-agent"),
|
|
||||||
});
|
|
||||||
return new NextResponse("Forbidden", { status: 403 });
|
|
||||||
}
|
|
||||||
|
|
||||||
// 🛡️ 安全检查2:检测可疑请求模式
|
|
||||||
const suspiciousCheck = isSuspiciousRequest(request);
|
|
||||||
if (suspiciousCheck.suspicious) {
|
|
||||||
logSuspiciousRequest(request, suspiciousCheck.reason || "Unknown suspicious pattern");
|
|
||||||
// 对于可疑请求,记录但不立即阻止(避免误报)
|
|
||||||
// 可以在这里添加更严格的检查
|
|
||||||
}
|
|
||||||
|
|
||||||
// 🛡️ 安全检查3:速率限制
|
|
||||||
// 对API路径应用速率限制
|
|
||||||
if (pathname.startsWith("/api/")) {
|
|
||||||
const rateLimit = checkRateLimit(request, rateLimiters.api);
|
|
||||||
if (!rateLimit.allowed) {
|
|
||||||
console.warn(`[Security] Rate limit exceeded for IP: ${clientIP}`, {
|
|
||||||
pathname,
|
|
||||||
resetTime: new Date(rateLimit.resetTime).toISOString(),
|
|
||||||
});
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: "Too many requests", retryAfter: Math.ceil((rateLimit.resetTime - Date.now()) / 1000) },
|
|
||||||
{ status: 429 }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 🛡️ 安全检查4:认证相关API的严格速率限制
|
|
||||||
if (pathname.startsWith("/api/auth/")) {
|
|
||||||
const rateLimit = checkRateLimit(request, rateLimiters.auth);
|
|
||||||
if (!rateLimit.allowed) {
|
|
||||||
console.warn(`[Security] Auth rate limit exceeded for IP: ${clientIP}`);
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: "Too many authentication attempts", retryAfter: Math.ceil((rateLimit.resetTime - Date.now()) / 1000) },
|
|
||||||
{ status: 429 }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 允许访问 ping 端点
|
|
||||||
if (pathname.startsWith("/ping")) {
|
|
||||||
return NextResponse.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 允许访问认证相关 API
|
|
||||||
if (pathname.startsWith("/api/auth")) {
|
|
||||||
return NextResponse.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 允许访问公开的网站设置 API(登录页面需要)
|
|
||||||
if (pathname === "/api/site-settings") {
|
|
||||||
return NextResponse.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 允许访问钉钉回调页面(public 文件夹中的文件)
|
|
||||||
if (pathname === "/dingtalk-callback.html") {
|
|
||||||
return NextResponse.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检测是否为 HTTPS(通过 AUTH_URL 或请求协议判断)
|
|
||||||
const isSecure = process.env.AUTH_URL?.startsWith("https://") ||
|
|
||||||
request.nextUrl.protocol === "https:";
|
|
||||||
|
|
||||||
const token = await getToken({
|
|
||||||
req: request,
|
|
||||||
secret: process.env.AUTH_SECRET,
|
|
||||||
secureCookie: isSecure,
|
|
||||||
});
|
|
||||||
|
|
||||||
const externalBase =
|
|
||||||
process.env.AUTH_URL ??
|
|
||||||
`${request.nextUrl.protocol}//${request.headers.get("host") ?? request.nextUrl.host}`;
|
|
||||||
|
|
||||||
// 未登录用户只能访问 /login 和 /register
|
|
||||||
if (!token && !["/login", "/register"].includes(pathname)) {
|
|
||||||
// 对于 API 路由的非 GET 请求,直接返回 401 JSON 响应(不重定向)
|
|
||||||
if (pathname.startsWith("/api/") && request.method !== "GET") {
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: "未授权,请先登录" },
|
|
||||||
{ status: 401 }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 对于页面路由(GET 请求),重定向到登录页面
|
|
||||||
const loginUrl = new URL("/login", externalBase);
|
|
||||||
// 保存当前路径作为回调 URL
|
|
||||||
loginUrl.searchParams.set("callbackUrl", pathname);
|
|
||||||
return NextResponse.redirect(loginUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 已登录用户访问 /login 或 /register 时重定向到首页
|
|
||||||
if (token && ["/login", "/register"].includes(pathname)) {
|
|
||||||
return NextResponse.redirect(new URL("/", externalBase));
|
|
||||||
}
|
|
||||||
|
|
||||||
return NextResponse.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const config = {
|
|
||||||
matcher: [
|
|
||||||
/*
|
|
||||||
* 匹配所有请求路径,除了:
|
|
||||||
* - api/auth (NextAuth.js)
|
|
||||||
* - _next/static (静态文件)
|
|
||||||
* - _next/image (图片优化文件)
|
|
||||||
* - favicon.ico (favicon文件)
|
|
||||||
* - public 文件夹中的文件
|
|
||||||
*/
|
|
||||||
"/((?!api/auth|_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
@ -80,3 +80,5 @@ echo ""
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
224
依赖源配置检查报告.md
Normal file
224
依赖源配置检查报告.md
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
# 项目依赖源配置检查报告
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
本报告详细说明了 `ai-chatbot` 项目安装依赖时使用的所有依赖源及其来源。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 包管理器配置
|
||||||
|
|
||||||
|
### 1.1 包管理器类型
|
||||||
|
- **包管理器**: `pnpm`
|
||||||
|
- **版本**: `9.12.3` (在 `package.json` 中通过 `packageManager` 字段指定)
|
||||||
|
- **配置文件位置**: `package.json` 第 122 行
|
||||||
|
|
||||||
|
```json
|
||||||
|
"packageManager": "pnpm@9.12.3"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 Registry 配置
|
||||||
|
|
||||||
|
#### 当前配置
|
||||||
|
- **主要 Registry**: `https://registry.npmjs.org/`
|
||||||
|
- **配置来源**: pnpm 全局默认配置
|
||||||
|
- **配置方式**: 使用 pnpm 默认配置(未在项目级配置文件中覆盖)
|
||||||
|
|
||||||
|
#### 配置检查结果
|
||||||
|
```bash
|
||||||
|
# 当前 registry 配置
|
||||||
|
$ pnpm config get registry
|
||||||
|
https://registry.npmjs.org/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Scope Registry 配置
|
||||||
|
- **Scope 特定 Registry**: 无
|
||||||
|
- **检查结果**: 未配置任何 scope 特定的 registry(如 `@scope:registry`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 项目级配置文件检查
|
||||||
|
|
||||||
|
### 2.1 存在的配置文件
|
||||||
|
- ✅ `package.json` - 包含依赖声明和包管理器版本
|
||||||
|
- ✅ `pnpm-lock.yaml` - 锁定文件,包含依赖版本和完整性校验
|
||||||
|
- ❌ `.npmrc` - **不存在**(未在项目根目录找到)
|
||||||
|
- ❌ `.yarnrc` / `.yarnrc.yml` - **不存在**(项目不使用 Yarn)
|
||||||
|
|
||||||
|
### 2.2 package.json 中的特殊配置
|
||||||
|
|
||||||
|
#### pnpm 覆盖配置 (pnpm.overrides)
|
||||||
|
```json
|
||||||
|
"pnpm": {
|
||||||
|
"overrides": {
|
||||||
|
"sharp": "^0.34.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- **作用**: 强制所有依赖使用指定版本的 `sharp` 包
|
||||||
|
- **影响**: 不影响 registry 配置,仅影响版本解析
|
||||||
|
|
||||||
|
### 2.3 pnpm-lock.yaml 分析
|
||||||
|
- **Lockfile 版本**: `9.0`
|
||||||
|
- **Registry 信息**: lockfile 中不包含显式的 registry URL
|
||||||
|
- **完整性校验**: 所有包使用 `integrity` 字段(sha512)进行完整性校验
|
||||||
|
- **包解析**: 所有包都从默认的 npm registry (`https://registry.npmjs.org/`) 解析
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 依赖来源分类
|
||||||
|
|
||||||
|
### 3.1 所有依赖都来自同一个源
|
||||||
|
**所有依赖包(包括 dependencies 和 devDependencies)均来自**:
|
||||||
|
- **Registry URL**: `https://registry.npmjs.org/`
|
||||||
|
- **Registry 类型**: 官方 npm 公共注册表
|
||||||
|
|
||||||
|
### 3.2 依赖包列表
|
||||||
|
项目总共包含以下依赖(来自 `package.json`):
|
||||||
|
|
||||||
|
#### 生产依赖 (dependencies) - 约 70+ 个包
|
||||||
|
主要依赖包括:
|
||||||
|
- AI SDK 相关: `@ai-sdk/*`, `ai`
|
||||||
|
- React 相关: `react@19.0.0-rc`, `react-dom@19.0.0-rc`, `next@16.0.5`
|
||||||
|
- UI 组件: `@radix-ui/*`, `lucide-react`, `framer-motion`
|
||||||
|
- 工具库: `date-fns`, `zod`, `nanoid`, `bcrypt-ts`
|
||||||
|
- AWS: `@aws-sdk/client-s3`
|
||||||
|
- Vercel: `@vercel/*`
|
||||||
|
- 数据库: `drizzle-orm`, `postgres`
|
||||||
|
- 其他: `redis`, `sharp`, `@xenova/transformers` 等
|
||||||
|
|
||||||
|
#### 开发依赖 (devDependencies) - 约 15 个包
|
||||||
|
主要开发依赖包括:
|
||||||
|
- 代码质量: `@biomejs/biome`, `ultracite`
|
||||||
|
- 测试: `@playwright/test`
|
||||||
|
- 类型定义: `@types/*`
|
||||||
|
- 构建工具: `typescript`, `tsx`, `drizzle-kit`
|
||||||
|
- 样式: `tailwindcss`, `@tailwindcss/*`, `postcss`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 配置层级说明
|
||||||
|
|
||||||
|
### 4.1 配置优先级(pnpm)
|
||||||
|
pnpm 的配置优先级(从高到低):
|
||||||
|
1. **命令行参数** (最高优先级)
|
||||||
|
2. **环境变量** (如 `PNPM_REGISTRY`)
|
||||||
|
3. **项目级 `.npmrc` 文件** (本项目不存在)
|
||||||
|
4. **用户级 `~/.npmrc` 或 `~/.config/pnpm/rc`**
|
||||||
|
5. **全局默认配置** (当前使用的)
|
||||||
|
6. **npm 默认值** (`https://registry.npmjs.org/`)
|
||||||
|
|
||||||
|
### 4.2 当前配置层级
|
||||||
|
由于项目根目录没有 `.npmrc` 文件,项目使用的是:
|
||||||
|
- **第 4/5 层级**: 用户级或全局 pnpm 配置
|
||||||
|
- **第 6 层级**: npm 默认 registry (`https://registry.npmjs.org/`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 实际安装行为
|
||||||
|
|
||||||
|
### 5.1 安装命令
|
||||||
|
项目使用的安装命令:
|
||||||
|
```bash
|
||||||
|
pnpm install --frozen-lockfile # 生产环境(CI/CD)
|
||||||
|
pnpm install # 开发环境
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 安装流程
|
||||||
|
1. pnpm 读取 `package.json` 和 `pnpm-lock.yaml`
|
||||||
|
2. 根据 lockfile 中的 `integrity` 校验包的完整性
|
||||||
|
3. 从 `https://registry.npmjs.org/` 下载所有包
|
||||||
|
4. 安装到 `node_modules`(使用 pnpm 的符号链接策略)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 服务器部署环境
|
||||||
|
|
||||||
|
### 6.1 服务器配置
|
||||||
|
根据部署脚本分析,服务器端同样使用:
|
||||||
|
- **Registry**: `https://registry.npmjs.org/`(默认)
|
||||||
|
- **安装命令**: `pnpm install --frozen-lockfile` 或 `pnpm install`
|
||||||
|
|
||||||
|
### 6.2 相关脚本
|
||||||
|
- `auto-deploy.sh`: 使用 `pnpm install --production=false`
|
||||||
|
- `final-deploy.sh`: 使用 `pnpm install`
|
||||||
|
- `migrate-server.sh`: 使用 `pnpm install --frozen-lockfile`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. CI/CD 配置
|
||||||
|
|
||||||
|
### 7.1 GitHub Actions
|
||||||
|
根据 `.github/workflows/playwright.yml`:
|
||||||
|
- 使用 `pnpm/action-setup@v2` 设置 pnpm
|
||||||
|
- 使用 `pnpm install --frozen-lockfile` 安装依赖
|
||||||
|
- 默认使用 npm registry (`https://registry.npmjs.org/`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 总结
|
||||||
|
|
||||||
|
### 8.1 依赖源统一性
|
||||||
|
✅ **所有依赖都来自同一个源**: `https://registry.npmjs.org/`
|
||||||
|
|
||||||
|
### 8.2 配置特点
|
||||||
|
- ✅ **简单统一**: 未使用任何自定义 registry 配置
|
||||||
|
- ✅ **标准配置**: 使用 npm 官方公共注册表
|
||||||
|
- ✅ **无私有源**: 未配置任何私有或镜像源
|
||||||
|
- ✅ **无 scope 配置**: 未为特定 scope(如 `@ai-sdk`)配置专门的 registry
|
||||||
|
|
||||||
|
### 8.3 建议
|
||||||
|
如果需要切换 registry(例如使用国内镜像加速),可以:
|
||||||
|
|
||||||
|
1. **创建项目级 `.npmrc` 文件**:
|
||||||
|
```ini
|
||||||
|
registry=https://registry.npmmirror.com/
|
||||||
|
# 或
|
||||||
|
registry=https://registry.npmjs.org/
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **使用环境变量**:
|
||||||
|
```bash
|
||||||
|
export PNPM_REGISTRY=https://registry.npmmirror.com/
|
||||||
|
pnpm install
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **使用命令行参数**:
|
||||||
|
```bash
|
||||||
|
pnpm install --registry https://registry.npmmirror.com/
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 检查命令
|
||||||
|
|
||||||
|
### 9.1 本地检查
|
||||||
|
```bash
|
||||||
|
# 查看当前 registry 配置
|
||||||
|
pnpm config get registry
|
||||||
|
|
||||||
|
# 查看所有 pnpm 配置
|
||||||
|
pnpm config list
|
||||||
|
|
||||||
|
# 查看项目依赖
|
||||||
|
pnpm list --depth=0
|
||||||
|
|
||||||
|
# 检查 lockfile
|
||||||
|
cat pnpm-lock.yaml | head -50
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.2 验证依赖来源
|
||||||
|
```bash
|
||||||
|
# 查看特定包的详细信息(包括来源)
|
||||||
|
pnpm info <package-name>
|
||||||
|
|
||||||
|
# 例如:
|
||||||
|
pnpm info react
|
||||||
|
pnpm info next
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**报告生成时间**: 2025-01-XX
|
||||||
|
**检查范围**: 项目根目录及所有配置文件
|
||||||
|
**检查工具**: pnpm config, package.json, pnpm-lock.yaml
|
||||||
|
|
||||||
279
安全审计报告-恶意挖矿检查.md
Normal file
279
安全审计报告-恶意挖矿检查.md
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
# 安全审计报告 - 恶意挖矿程序检查
|
||||||
|
|
||||||
|
## 检查日期
|
||||||
|
2025年1月
|
||||||
|
|
||||||
|
## 检查范围
|
||||||
|
- 项目: ai-chatbot
|
||||||
|
- 包管理器: pnpm@9.12.3
|
||||||
|
- 依赖总数: 85+ 个包(生产依赖 + 开发依赖)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 执行的安全检查
|
||||||
|
|
||||||
|
### 1.1 依赖安全审计 (pnpm audit)
|
||||||
|
```bash
|
||||||
|
pnpm audit --prod
|
||||||
|
```
|
||||||
|
|
||||||
|
**检查结果摘要**:
|
||||||
|
- ✅ **未发现恶意挖矿程序相关的直接安全漏洞**
|
||||||
|
- ⚠️ **发现 9 个已知安全漏洞**(非恶意挖矿相关):
|
||||||
|
- 1 个严重 (Critical): Next.js RCE 漏洞
|
||||||
|
- 2 个高危 (High): Next.js DoS、Playwright SSL 验证
|
||||||
|
- 4 个中危 (Moderate): PrismJS、NextAuth、mdast-util-to-hast、Next.js
|
||||||
|
- 2 个低危 (Low): undici、AI SDK
|
||||||
|
|
||||||
|
### 1.2 恶意代码关键词扫描
|
||||||
|
```bash
|
||||||
|
# 扫描 node_modules 中的恶意挖矿相关关键词
|
||||||
|
grep -r "miner|mining|cryptocurrency|xmrig|monero|coinhive" node_modules
|
||||||
|
```
|
||||||
|
**结果**: ✅ 未发现明显的恶意挖矿关键词
|
||||||
|
|
||||||
|
### 1.3 可疑安装脚本检查
|
||||||
|
检查了项目依赖中是否有可疑的 `postinstall`、`preinstall` 脚本:
|
||||||
|
- ✅ `package.json` 中**未定义任何安装脚本**
|
||||||
|
- ✅ 检查了 `node_modules` 中安装脚本的使用情况(均为正常用途)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 已知的安全威胁背景
|
||||||
|
|
||||||
|
### 2.1 近期 npm 生态系统安全事件
|
||||||
|
|
||||||
|
根据最新安全报告,npm 生态系统确实存在以下已知威胁:
|
||||||
|
|
||||||
|
#### 1. **Rspack 和 Vant 恶意挖矿事件 (2024年12月)**
|
||||||
|
- **受影响包**: `@rspack/core`、`@rspack/cli`、`vant`
|
||||||
|
- **攻击方式**: 攻击者利用被盗的 npm 令牌,在更新中注入恶意代码
|
||||||
|
- **恶意行为**: 部署 XMRig Monero 加密货币矿机
|
||||||
|
- **本项目状态**: ✅ **未使用这些受影响包**
|
||||||
|
|
||||||
|
#### 2. **大规模恶意包攻击 (2025年11月)**
|
||||||
|
- **规模**: 超过 15 万个恶意 npm 包被注入
|
||||||
|
- **目的**: 通过 tea.xyz 代币挖矿活动牟利
|
||||||
|
- **本项目状态**: ✅ **使用 pnpm-lock.yaml 锁定版本,降低风险**
|
||||||
|
|
||||||
|
#### 3. **知名开发者账户钓鱼攻击 (2025年9月)**
|
||||||
|
- **影响**: 至少 18 个高频下载的 npm 包被篡改
|
||||||
|
- **周下载量**: 高达 26 亿次
|
||||||
|
- **恶意行为**: 劫持网络流量,替换加密货币收款地址
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 项目依赖安全性分析
|
||||||
|
|
||||||
|
### 3.1 主要依赖包安全性评估
|
||||||
|
|
||||||
|
#### ✅ 低风险包(官方维护,信誉良好)
|
||||||
|
- **React**: `react@19.0.0-rc` - Meta/Facebook 官方
|
||||||
|
- **Next.js**: `next@16.0.5` - Vercel 官方(⚠️ 需更新至 16.0.9+ 修复漏洞)
|
||||||
|
- **@radix-ui/***: Radix UI 官方组件库
|
||||||
|
- **@vercel/***: Vercel 官方包
|
||||||
|
- **drizzle-orm**: `drizzle-orm@0.34.0` - 知名 ORM 框架
|
||||||
|
- **@ai-sdk/***: Vercel AI SDK 官方包
|
||||||
|
|
||||||
|
#### ⚠️ 需要关注的包
|
||||||
|
|
||||||
|
1. **@xenova/transformers** (`@xenova/transformers@2.17.0`)
|
||||||
|
- **用途**: 机器学习模型库
|
||||||
|
- **风险评估**: 中等 - 需要网络下载模型
|
||||||
|
- **建议**: 已验证为 Xenova 官方维护,相对安全
|
||||||
|
|
||||||
|
2. **sharp** (`sharp@0.34.5`)
|
||||||
|
- **用途**: 图像处理(包含原生二进制)
|
||||||
|
- **风险评估**: 低 - 已通过 pnpm overrides 锁定版本
|
||||||
|
- **状态**: ✅ 版本已锁定
|
||||||
|
|
||||||
|
3. **bcrypt-ts** (`bcrypt-ts@5.0.2`)
|
||||||
|
- **用途**: 密码哈希
|
||||||
|
- **风险评估**: 低 - 知名安全库
|
||||||
|
|
||||||
|
4. **redis** (`redis@5.0.0`)
|
||||||
|
- **用途**: Redis 客户端
|
||||||
|
- **风险评估**: 低 - 官方维护
|
||||||
|
|
||||||
|
### 3.2 依赖锁定文件分析
|
||||||
|
|
||||||
|
**锁定文件**: `pnpm-lock.yaml`
|
||||||
|
- ✅ **完整性校验**: 所有包使用 `integrity` (sha512) 校验
|
||||||
|
- ✅ **版本锁定**: 精确锁定所有依赖版本
|
||||||
|
- ✅ **Registry 来源**: 统一来自 `https://registry.npmjs.org/`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 安全检查建议
|
||||||
|
|
||||||
|
### 4.1 立即处理(高优先级)
|
||||||
|
|
||||||
|
1. **更新 Next.js 版本**
|
||||||
|
```bash
|
||||||
|
# 当前版本: 16.0.5
|
||||||
|
# 建议版本: >= 16.0.9
|
||||||
|
pnpm update next@latest
|
||||||
|
```
|
||||||
|
**原因**: 修复严重 RCE 漏洞 (CVE-GHSA-9qr9-h5gf-34mp)
|
||||||
|
|
||||||
|
2. **更新 Playwright 版本**
|
||||||
|
```bash
|
||||||
|
# 当前版本: 1.51.0
|
||||||
|
# 建议版本: >= 1.55.1
|
||||||
|
pnpm update @playwright/test@latest playwright@latest
|
||||||
|
```
|
||||||
|
**原因**: 修复 SSL 证书验证问题
|
||||||
|
|
||||||
|
3. **更新 NextAuth 版本**
|
||||||
|
```bash
|
||||||
|
# 当前版本: 5.0.0-beta.25
|
||||||
|
# 建议版本: >= 5.0.0-beta.30
|
||||||
|
pnpm update next-auth@latest
|
||||||
|
```
|
||||||
|
**原因**: 修复邮件误投递漏洞
|
||||||
|
|
||||||
|
### 4.2 定期维护(中优先级)
|
||||||
|
|
||||||
|
1. **定期运行安全审计**
|
||||||
|
```bash
|
||||||
|
pnpm audit
|
||||||
|
pnpm audit --fix # 自动修复可修复的问题
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **监控依赖更新**
|
||||||
|
- 订阅依赖包的安全公告
|
||||||
|
- 使用 Dependabot 或 Renovate 自动更新
|
||||||
|
|
||||||
|
3. **审查新添加的依赖**
|
||||||
|
- 检查包的维护者信誉
|
||||||
|
- 查看包的 GitHub stars、issues 状态
|
||||||
|
- 审查包的下载量和更新频率
|
||||||
|
|
||||||
|
### 4.3 长期策略(低优先级)
|
||||||
|
|
||||||
|
1. **实施依赖审查流程**
|
||||||
|
- 新依赖需团队审查
|
||||||
|
- 建立依赖白名单
|
||||||
|
- 优先使用官方/知名维护的包
|
||||||
|
|
||||||
|
2. **使用安全工具**
|
||||||
|
- Snyk: 持续监控依赖安全
|
||||||
|
- Dependabot: GitHub 自动安全更新
|
||||||
|
- npm-check-updates: 检查过时依赖
|
||||||
|
|
||||||
|
3. **实施最小权限原则**
|
||||||
|
- 限制依赖包的网络访问
|
||||||
|
- 使用沙箱环境运行可疑代码
|
||||||
|
- 监控异常的系统资源使用
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 恶意挖矿程序检测方法
|
||||||
|
|
||||||
|
### 5.1 系统监控指标
|
||||||
|
|
||||||
|
如果系统被植入恶意挖矿程序,可能出现以下症状:
|
||||||
|
|
||||||
|
1. **CPU/GPU 使用率异常高**
|
||||||
|
- 持续 100% CPU 使用率
|
||||||
|
- 无明显负载但资源耗尽
|
||||||
|
|
||||||
|
2. **网络流量异常**
|
||||||
|
- 异常的网络连接
|
||||||
|
- 连接到未知的挖矿池地址
|
||||||
|
|
||||||
|
3. **系统性能下降**
|
||||||
|
- 应用响应变慢
|
||||||
|
- 服务器负载异常
|
||||||
|
|
||||||
|
### 5.2 检测命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查 CPU 使用率
|
||||||
|
top
|
||||||
|
htop
|
||||||
|
|
||||||
|
# 检查网络连接
|
||||||
|
netstat -anp | grep ESTABLISHED
|
||||||
|
ss -tulpn
|
||||||
|
|
||||||
|
# 检查进程
|
||||||
|
ps aux | sort -rk 3,3 | head -10 # 按 CPU 使用率排序
|
||||||
|
|
||||||
|
# 检查异常进程名
|
||||||
|
ps aux | grep -E "miner|xmrig|monero|coinhive"
|
||||||
|
|
||||||
|
# 监控系统资源
|
||||||
|
iostat -x 1
|
||||||
|
vmstat 1
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.3 运行时监控
|
||||||
|
|
||||||
|
建议在生产环境部署监控工具:
|
||||||
|
- **Prometheus + Grafana**: 系统资源监控
|
||||||
|
- **CloudWatch**: AWS 云监控
|
||||||
|
- **New Relic / Datadog**: APM 监控
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 结论
|
||||||
|
|
||||||
|
### 6.1 当前安全状态
|
||||||
|
|
||||||
|
✅ **未发现恶意挖矿程序植入的证据**
|
||||||
|
|
||||||
|
**依据**:
|
||||||
|
1. ✅ pnpm audit 未报告恶意挖矿相关漏洞
|
||||||
|
2. ✅ 代码扫描未发现恶意挖矿关键词
|
||||||
|
3. ✅ 依赖包均为知名、官方维护的包
|
||||||
|
4. ✅ 使用锁定文件确保依赖版本一致
|
||||||
|
5. ✅ 未发现可疑的安装脚本
|
||||||
|
|
||||||
|
### 6.2 风险评估
|
||||||
|
|
||||||
|
| 风险类型 | 风险等级 | 说明 |
|
||||||
|
|---------|---------|------|
|
||||||
|
| 恶意挖矿程序植入 | 🟢 **低** | 未发现相关威胁 |
|
||||||
|
| 已知安全漏洞 | 🟡 **中** | 9 个漏洞需修复 |
|
||||||
|
| 供应链攻击 | 🟢 **低** | 依赖来源可信 |
|
||||||
|
| 运行时感染 | 🟢 **低** | 使用锁定文件 |
|
||||||
|
|
||||||
|
### 6.3 建议措施
|
||||||
|
|
||||||
|
1. **立即行动**:
|
||||||
|
- 更新 Next.js 至 16.0.9+ 修复严重漏洞
|
||||||
|
- 更新 Playwright 和 NextAuth 修复已知漏洞
|
||||||
|
|
||||||
|
2. **定期维护**:
|
||||||
|
- 每周运行 `pnpm audit`
|
||||||
|
- 每月审查依赖更新
|
||||||
|
- 监控系统资源使用情况
|
||||||
|
|
||||||
|
3. **持续监控**:
|
||||||
|
- 部署系统监控工具
|
||||||
|
- 设置异常告警
|
||||||
|
- 定期审查日志
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 附录
|
||||||
|
|
||||||
|
### 7.1 参考资源
|
||||||
|
|
||||||
|
- [npm Security Advisories](https://github.com/advisories?query=ecosystem:npm)
|
||||||
|
- [Snyk Vulnerability Database](https://security.snyk.io/)
|
||||||
|
- [OWASP Dependency Check](https://owasp.org/www-project-dependency-check/)
|
||||||
|
|
||||||
|
### 7.2 相关安全事件
|
||||||
|
|
||||||
|
- [Rspack 和 Vant 恶意挖矿事件](https://www.anquanke.com/post/id/302951)
|
||||||
|
- [npm 大规模恶意包攻击](https://www.ithome.com/0/897/895.htm)
|
||||||
|
- [XZ 实用程序后门事件](https://zh.wikipedia.org/wiki/XZ实用程序后门)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**报告生成时间**: 2025年1月
|
||||||
|
**检查工具**: pnpm audit, grep, 在线安全数据库
|
||||||
|
**检查人员**: AI Assistant
|
||||||
|
|
||||||
@ -133,3 +133,5 @@ pmset -g
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user