{"record":{"id":"ad2e805fb751c74c","repo":"Kong/insomnia","slug":"proto-path-escapes-temporary-directory-candida","errorCode":null,"errorMessage":"Proto path escapes temporary directory: \"${candidatePath}\"","messagePattern":"Proto path escapes temporary directory: \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/insomnia/src/network/grpc/write-proto-file.node.ts","lineNumber":26,"sourceCode":"import { database as db } from '../../common/database';\n\nconst { isProtoDirectory } = models.protoDirectory;\nconst { isProtoFile } = models.protoFile;\n\ninterface WriteResult {\n  filePath: string;\n  dirs: string[];\n}\n\nconst sanitizeName = (name: string): string => {\n  const base = path.basename(name);\n  return !base || base === '..' || base === '.' ? '_' : base;\n};\n\nconst assertWithinTempRoot = (tempRoot: string, candidatePath: string): void => {\n  const relative = path.relative(tempRoot, candidatePath);\n  if (relative.startsWith('..') || path.isAbsolute(relative)) {\n    throw new Error(`Proto path escapes temporary directory: \"${candidatePath}\"`);\n  }\n};\n\nconst recursiveWriteProtoDirectory = async (\n  dir: ProtoDirectory,\n  descendants: BaseModel[],\n  currentDirPath: string,\n  tempRoot: string,\n): Promise<string[]> => {\n  const dirPath = path.join(currentDirPath, sanitizeName(dir.name));\n  assertWithinTempRoot(tempRoot, dirPath);\n  fs.mkdirSync(dirPath, { recursive: true });\n  // Get and write proto files\n  const files = descendants.filter(isProtoFile).filter(f => f.parentId === dir._id);\n  await Promise.all(\n    files.map(protoFile => {\n      const fullPath = path.join(dirPath, sanitizeName(protoFile.name));\n      assertWithinTempRoot(tempRoot, fullPath);","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/Kong/insomnia/blob/d9bb2b0142600f21309832daea3317942d285984/packages/insomnia/src/network/grpc/write-proto-file.node.ts#L8-L44","documentation":"Security guard in assertWithinTempRoot: a resolved .proto file path would land outside the temporary proto directory (path traversal via crafted file or directory names), so writing the proto tree is refused to prevent arbitrary file writes.","triggerScenarios":"Thrown at packages/insomnia/src/network/grpc/write-proto-file.node.ts:26 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Rename proto files/directories to remove traversal segments ('..', absolute path prefixes)","Trust only proto directories imported through the app's normal import flow"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"d9bb2b0142600f21309832daea3317942d285984","analyzedAt":"2026-08-26T18:04:05.187Z","contentChangedAt":"2026-08-26T18:04:05.187Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}