From c6a2576aba1351f6de2c47b994336ccb4eb2c67e Mon Sep 17 00:00:00 2001 From: qorvr Date: Sat, 24 Oct 2026 19:43:34 +0530 Subject: [PATCH] fix(contracts): reject NUL bytes in objdump and rizin local path inputs (#3600) Co-authored-by: qorvr <330186599+qorvr@users.noreply.github.com> Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com> --- src/domain/reverseEngineering.ts | 5 +++-- tests/acceptance/tools/localToolContracts.test.ts | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/domain/reverseEngineering.ts b/src/domain/reverseEngineering.ts index 0e87c9bfbf..f79e0ccafd 100644 --- a/src/domain/reverseEngineering.ts +++ b/src/domain/reverseEngineering.ts @@ -1,5 +1,6 @@ import { z } from "zod"; import { commandEvidenceDetailSchema } from "./commandObservation.js"; +import { localPathStringSchema } from "./localPath.js"; /** Omitted one-shot objdump/rizin wall clock. Preflight shares it; the command gets it again. */ export const DEFAULT_REVERSE_COMMAND_TIMEOUT_MS = 120_000; @@ -33,7 +34,7 @@ export const OBJDUMP_ARTIFACT_OPERATIONS = [ const objdumpArtifactInputSchema = z .object({ - path: z.string().min(1), + path: localPathStringSchema, operation: z.enum(OBJDUMP_ARTIFACT_OPERATIONS).exclude(["disassemble"]), follow_debug_links: z.boolean().default(false), ...commandTimeoutMsField, @@ -74,7 +75,7 @@ export const objdumpInputSchema = z.discriminatedUnion("operation", [ /** Caller-selected Rizin command against one local artifact. */ export const rizinInputSchema = z .object({ - path: z.string().min(1), + path: localPathStringSchema, command: z .string() .min(1) diff --git a/tests/acceptance/tools/localToolContracts.test.ts b/tests/acceptance/tools/localToolContracts.test.ts index a6bfe651fb..e056259eaa 100644 --- a/tests/acceptance/tools/localToolContracts.test.ts +++ b/tests/acceptance/tools/localToolContracts.test.ts @@ -160,6 +160,8 @@ const pathRequests: readonly [string, Record][] = [ ["extract_firmware", { path: nul, output_directory: "/tmp/out" }], ["extract_firmware", { path: "/tmp/firmware.bin", output_directory: nul }], ["inspect_plist", { path: nul }], + ["inspect_with_objdump", { path: nul, operation: "file_headers" }], + ["execute_rizin_command", { path: nul, command: "iI" }], ...[ { kind: "function", name: "main\0suffix" }, { kind: "function", name: "main", module: "lib.dylib\0suffix" },