From 4ea06a66c80dd857a35db22770fc02f8042d779a Mon Sep 17 00:00:00 2001 From: kevin9327 <5299031+kevin9327@users.noreply.github.com> Date: Thu, 10 Sep 2026 19:40:47 +0900 Subject: [PATCH] fix(scan): reject unsafe finding location paths in imported JSON `scan import --csv` refuses a row whose `path` escapes the repository, is absolute, or carries a drive letter, backslash or control character. The `--json` branch of the same command validated only against the findings JSON schema, which constrains `locations[].path` to a non-empty string, so the same path was accepted. `--dry-run` therefore reported such a document as importable, and the real import failed later in finalization with a message about findings not being preserved, after the source had already been persisted and a scan registered. Apply the existing `safeFindingPath` check to imported JSON finding locations, reporting the finding index the way the duplicate `occurrenceId` check beside it already does. --- sdk/typescript/src/findings-import.ts | 5 +++++ sdk/typescript/tests-ts/findings-import.test.ts | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/sdk/typescript/src/findings-import.ts b/sdk/typescript/src/findings-import.ts index 6ca87b12b..d316560d0 100644 --- a/sdk/typescript/src/findings-import.ts +++ b/sdk/typescript/src/findings-import.ts @@ -164,6 +164,11 @@ export async function parseImportedFindings( ); } occurrenceIds.add(finding.occurrenceId); + if (finding.locations.some((location) => !safeFindingPath(location.path))) { + throw new CodexSecurityError( + `Findings JSON finding ${index + 1} has an invalid path.`, + ); + } } return document.findings; } diff --git a/sdk/typescript/tests-ts/findings-import.test.ts b/sdk/typescript/tests-ts/findings-import.test.ts index 6c4ba695f..9a66780f0 100644 --- a/sdk/typescript/tests-ts/findings-import.test.ts +++ b/sdk/typescript/tests-ts/findings-import.test.ts @@ -145,4 +145,19 @@ describe("findings import formats", () => { ), ).rejects.toThrow("duplicate occurrenceId"); }); + + test("rejects an unsafe finding location path in either import format", async () => { + const document = await sourceDocument(); + document.findings[0]!.locations[0]!.path = "../../../outside/secrets.env"; + await expect( + parseImportedFindings(JSON.stringify(document), "json", PLUGIN_ROOT), + ).rejects.toThrow("has an invalid path"); + await expect( + parseImportedFindings( + CSV_SOURCE.replace("src/extract.ts", "../../../outside/secrets.env"), + "csv", + PLUGIN_ROOT, + ), + ).rejects.toThrow("has an invalid path"); + }); });