fix(contracts): reject OS-invalid local paths in binary and artifact tools (#1925)
* fix(contracts): reject OS-invalid local paths in binary and artifact tools Enforce localPathStringSchema across inspect_pe_resources, inspect_binary_layout, inspect_recorded_crash, inspect_wasm_artifact, and inspect_evm_interface input schemas to reject embedded NUL bytes at the contract boundary instead of failing later during filesystem operations. Add corresponding acceptance test cases to the advertised MCP contracts matrix in localToolContracts.test.ts. Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com> * style(contracts): wrap pe resources path description under print width Wrap the inspectPeResourcesInputSchema path property description to keep lines within the 80-column oxfmt limit. Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com> --------- Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>
This commit is contained in:
parent
eaf88aca2a
commit
976c2c083e
|
|
@ -1,14 +1,15 @@
|
|||
import { z } from "zod";
|
||||
|
||||
import { localPathStringSchema } from "../localPath.js";
|
||||
|
||||
const byteOffset = z.number().int().nonnegative();
|
||||
const sha256 = z.string().regex(/^[a-f0-9]{64}$/);
|
||||
|
||||
/** Select the carrier representation explicitly; no RPC or deployed-contract lookup is implied. */
|
||||
export const inspectEvmInterfaceInputSchema = z.strictObject({
|
||||
path: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("Absolute path to caller-selected local bytecode carrier"),
|
||||
path: localPathStringSchema.describe(
|
||||
"Absolute path to caller-selected local bytecode carrier",
|
||||
),
|
||||
encoding: z
|
||||
.enum(["raw", "hex"])
|
||||
.describe(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { z } from "zod";
|
||||
|
||||
import { localPathStringSchema } from "../localPath.js";
|
||||
import { CANONICAL_BASE64_PATTERN } from "../stringPatterns.js";
|
||||
|
||||
const unsignedHex = z.string().regex(/^0x(?:0|[1-9a-f][0-9a-f]{0,15})$/);
|
||||
|
|
@ -16,10 +17,9 @@ const name = z.strictObject({
|
|||
|
||||
/** Explicit local object selection, independent of an active disassembler target. */
|
||||
export const inspectBinaryLayoutInputSchema = z.strictObject({
|
||||
path: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("Absolute filesystem path to the selected binary"),
|
||||
path: localPathStringSchema.describe(
|
||||
"Absolute filesystem path to the selected binary",
|
||||
),
|
||||
});
|
||||
|
||||
/** File and linked-image evidence; numeric ELF values never pass through unsafe JSON numbers. */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { z } from "zod";
|
||||
|
||||
import { localPathStringSchema } from "../localPath.js";
|
||||
|
||||
const uint = z.number().int().min(0).max(0xffffffff);
|
||||
const range = z.strictObject({ offset: uint, bytes: uint });
|
||||
const identity = z.discriminatedUnion("kind", [
|
||||
|
|
@ -14,7 +16,9 @@ const identity = z.discriminatedUnion("kind", [
|
|||
|
||||
/** Complete bounded inspection of a caller-selected PE image, without execution. */
|
||||
export const inspectPeResourcesInputSchema = z.strictObject({
|
||||
path: z.string().min(1).describe("Absolute filesystem path to a PE image"),
|
||||
path: localPathStringSchema.describe(
|
||||
"Absolute filesystem path to a PE image",
|
||||
),
|
||||
max_file_bytes: z
|
||||
.number()
|
||||
.int()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { z } from "zod";
|
||||
|
||||
import { localPathStringSchema } from "../localPath.js";
|
||||
import { CANONICAL_BASE64_PATTERN } from "../stringPatterns.js";
|
||||
import { recordedNoteCoverageIssues } from "./recordedCrashNoteCoverage.js";
|
||||
|
||||
|
|
@ -50,10 +51,9 @@ const supportedRegisters = new Set(RECORDED_LINUX_AMD64_REGISTERS);
|
|||
|
||||
/** Select an explicit recording and optionally request debugger-derived mapping context. */
|
||||
export const inspectRecordedCrashInputSchema = z.strictObject({
|
||||
path: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("Absolute filesystem path to a supplied Linux ELF core"),
|
||||
path: localPathStringSchema.describe(
|
||||
"Absolute filesystem path to a supplied Linux ELF core",
|
||||
),
|
||||
include_debugger_context: z
|
||||
.boolean()
|
||||
.default(false)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { z } from "zod";
|
||||
|
||||
import { localPathStringSchema } from "../localPath.js";
|
||||
|
||||
const digest = z.string().regex(/^[a-f0-9]{64}$/);
|
||||
const artifact = z.strictObject({
|
||||
path: z.string().min(1),
|
||||
|
|
@ -8,12 +10,11 @@ const artifact = z.strictObject({
|
|||
});
|
||||
/** All artifacts are explicitly selected local files; references never trigger acquisition. */
|
||||
export const inspectWasmArtifactInputSchema = z.strictObject({
|
||||
path: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("Absolute selected local WASM artifact path"),
|
||||
glue_paths: z.array(z.string().min(1)).max(16).default([]),
|
||||
candidate_paths: z.array(z.string().min(1)).max(16).default([]),
|
||||
path: localPathStringSchema.describe(
|
||||
"Absolute selected local WASM artifact path",
|
||||
),
|
||||
glue_paths: z.array(localPathStringSchema).max(16).default([]),
|
||||
candidate_paths: z.array(localPathStringSchema).max(16).default([]),
|
||||
});
|
||||
/** Upstream output stays intact; import/export names are never split on ambiguous punctuation. */
|
||||
export const wasmArtifactSchema = z
|
||||
|
|
|
|||
|
|
@ -96,6 +96,16 @@ const pathRequests: readonly [string, Record<string, unknown>][] = [
|
|||
"export_web_scripts",
|
||||
{ capture_path: nul, output_directory: "/tmp/exported-scripts" },
|
||||
],
|
||||
["inspect_pe_resources", { path: nul }],
|
||||
["inspect_binary_layout", { path: nul }],
|
||||
["inspect_recorded_crash", { path: nul }],
|
||||
["inspect_wasm_artifact", { path: nul }],
|
||||
["inspect_wasm_artifact", { path: "/tmp/sample.wasm", glue_paths: [nul] }],
|
||||
[
|
||||
"inspect_wasm_artifact",
|
||||
{ path: "/tmp/sample.wasm", candidate_paths: [nul] },
|
||||
],
|
||||
["inspect_evm_interface", { path: nul, encoding: "raw" }],
|
||||
[
|
||||
"export_web_scripts",
|
||||
{ capture_path: "/tmp/capture.json", output_directory: nul },
|
||||
|
|
|
|||
Loading…
Reference in New Issue