fix(security): add archive extraction containment validation
Validate tar and zip entries before extraction to prevent path traversal: - Reject absolute paths in archives - Reject .. traversal paths - Reject symlinks pointing outside extraction dir - New archive-entry-validator module with comprehensive tests Addresses: security audit finding for unsafe archive extraction.
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
import { spawn, spawnSync } from "bun"
|
||||
import { release } from "os"
|
||||
|
||||
import { validateArchiveEntries } from "./archive-entry-validator"
|
||||
import { listZipEntriesWithPowerShell, listZipEntriesWithTar } from "./zip-entry-listing"
|
||||
|
||||
const WINDOWS_BUILD_WITH_TAR = 17134
|
||||
|
||||
function getWindowsBuildNumber(): number | null {
|
||||
@@ -41,6 +44,9 @@ function getWindowsZipExtractor(): WindowsZipExtractor {
|
||||
}
|
||||
|
||||
export async function extractZip(archivePath: string, destDir: string): Promise<void> {
|
||||
const entries = await listZipEntries(archivePath)
|
||||
validateArchiveEntries(entries, destDir)
|
||||
|
||||
let proc
|
||||
|
||||
if (process.platform === "win32") {
|
||||
@@ -81,3 +87,16 @@ export async function extractZip(archivePath: string, destDir: string): Promise<
|
||||
throw new Error(`zip extraction failed (exit ${exitCode}): ${stderr}`)
|
||||
}
|
||||
}
|
||||
|
||||
async function listZipEntries(archivePath: string) {
|
||||
if (process.platform === "win32") {
|
||||
const extractor = getWindowsZipExtractor()
|
||||
if (extractor === "tar") {
|
||||
return listZipEntriesWithTar(archivePath)
|
||||
}
|
||||
|
||||
return listZipEntriesWithPowerShell(archivePath, escapePowerShellPath, extractor)
|
||||
}
|
||||
|
||||
return listZipEntriesWithTar(archivePath)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user