From b2b8f73d0d28097848c094e1aa9c2518dfc67d1b Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 3 Apr 2026 17:28:22 +0900 Subject: [PATCH] Fix tar traversal error normalization Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- src/shared/binary-downloader.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/shared/binary-downloader.ts b/src/shared/binary-downloader.ts index 28b737311..9b0ce7f04 100644 --- a/src/shared/binary-downloader.ts +++ b/src/shared/binary-downloader.ts @@ -4,6 +4,10 @@ import { spawn } from "bun"; import { validateArchiveEntries, type ArchiveEntry } from "./archive-entry-validator"; import { extractZip } from "./zip-extractor"; +function isTarTraversalErrorOutput(output: string): boolean { + return /path contains '\.\.'|member name contains '\.\.'|removing leading [`'\"]?\.\.\//i.test(output) +} + export function getCachedBinaryPath(cacheDir: string, binaryName: string): string | null { const binaryPath = path.join(cacheDir, binaryName); return existsSync(binaryPath) ? binaryPath : null; @@ -43,6 +47,11 @@ export async function extractTarGz( const exitCode = await proc.exited; if (exitCode !== 0) { const stderr = await new Response(proc.stderr).text(); + + if (isTarTraversalErrorOutput(stderr)) { + throw new Error(`Unsafe archive entry: path contains path traversal (${archivePath})`) + } + throw new Error(`tar extraction failed (exit ${exitCode}): ${stderr}`); } } @@ -102,6 +111,10 @@ async function listTarEntries(archivePath: string, cwd?: string): Promise