@ -84,12 +84,19 @@ 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 ;
if ( totalSize > MAX_EXTRACT_SIZE ) {
if ( totalSize > MAX_EXTRACT_SIZE ) {