Browse Source

Update Content-Security-Policy in projectController.ts for enhanced security and improve ZIP file extraction safety checks in fileUtils.ts to prevent path traversal and absolute path vulnerabilities.

deploy
dash 10 months ago
parent
commit
7ed7e0c448
  1. 2
      backend/src/controllers/projectController.ts
  2. 11
      backend/src/utils/fileUtils.ts

2
backend/src/controllers/projectController.ts

@ -392,7 +392,7 @@ export class ProjectController {
); );
// 设置CSP头 // 设置CSP头
ctx.set('Content-Security-Policy', "default-src 'self'; script-src 'unsafe-inline' 'unsafe-eval' 'self'; style-src 'unsafe-inline' 'self';"); ctx.set('Content-Security-Policy', "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: data:; worker-src 'self' blob: data:; img-src 'self' data: blob:; style-src 'self' 'unsafe-inline'; connect-src 'self' blob: data:; object-src 'none'; base-uri 'self';");
ctx.set('Content-Type', 'text/html; charset=utf-8'); ctx.set('Content-Type', 'text/html; charset=utf-8');
ctx.body = htmlContent; ctx.body = htmlContent;
} catch (error: any) { } catch (error: any) {

11
backend/src/utils/fileUtils.ts

@ -84,11 +84,18 @@ export async function extractZip(zipPath: string, extractTo: string): Promise<vo
zipfile.on('entry', (entry: yauzl.Entry) => { zipfile.on('entry', (entry: yauzl.Entry) => {
// 检查文件名安全性 // 检查文件名安全性
const sanitized = sanitizeFileName(entry.fileName); // 检查路径遍历攻击(..)和危险字符,但允许正常的目录结构
if (sanitized !== entry.fileName) { if (entry.fileName.includes('..') ||
/[<>:"|?*\x00-\x1f]/.test(entry.fileName)) {
reject(new Error('ZIP文件包含不安全的文件名')); reject(new Error('ZIP文件包含不安全的文件名'));
return; return;
} }
// 检查绝对路径(Windows: C:\ 或 Unix: /)
if (/^([a-zA-Z]:|\\\\|\/)/.test(entry.fileName)) {
reject(new Error('ZIP文件包含绝对路径'));
return;
}
// 检查解压后总大小(防止zip炸弹) // 检查解压后总大小(防止zip炸弹)
totalSize += entry.uncompressedSize; totalSize += entry.uncompressedSize;

Loading…
Cancel
Save