{"record":{"id":"e3ff1b0df542b0fa","repo":"stablyai/orca","slug":"path-escaped-upload-root-during-staging-displa","errorCode":null,"errorMessage":"Path escaped upload root during staging: '${displayPath}'","messagePattern":"Path escaped upload root during staging: '(.+?)'","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ipc/filesystem-mutations.ts","lineNumber":641,"sourceCode":"    }\n  } finally {\n    await fileHandle.close()\n  }\n}\n\nasync function assertRealPathInsideRoot(\n  rootRealPath: string,\n  candidatePath: string,\n  displayPath: string\n): Promise<void> {\n  const candidateRealPath = await realpath(candidatePath)\n  const relativeToRoot = relative(rootRealPath, candidateRealPath)\n  // Why: `..name` is a valid child path; only `..` and `../...` escape.\n  if (\n    relativeToRoot !== '' &&\n    (relativeToRoot === '..' || relativeToRoot.startsWith(`..${sep}`) || isAbsolute(relativeToRoot))\n  ) {\n    throw new Error(`Path escaped upload root during staging: '${displayPath}'`)\n  }\n}\n\nfunction assertRemoteUploadBudget(\n  relativePath: string,\n  fileBytes: number,\n  totalBytes: number\n): void {\n  if (fileBytes > REMOTE_IMPORT_MAX_FILE_BYTES) {\n    throw new Error(`'${relativePath}' is too large for remote import`)\n  }\n  if (totalBytes > REMOTE_IMPORT_MAX_TOTAL_BYTES) {\n    throw new Error('Remote import is too large')\n  }\n}\n\nfunction normalizeRelativeUploadPath(path: string): string {\n  return path.replace(/[\\\\/]+/g, '/').replace(/^\\/+/, '')","sourceCodeStart":623,"sourceCodeEnd":659,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/filesystem-mutations.ts#L623-L659","documentation":"Thrown by assertRealPathInsideRoot during remote upload directory staging. The function resolves the candidate path with realpath and checks whether the resolved path is still within the upload root. If the relative path from root to the candidate starts with '..' or is absolute, the path escaped the root boundary. This catches cases where an intermediate directory component was replaced (e.g., a directory swapped for a symlink or bind mount) after the pre-scan, allowing the resolved path to point outside the authorized subtree.","triggerScenarios":"During stageDirectoryEntries traversal, realpath on a child path resolves outside rootRealPath. An intermediate directory in the tree was replaced by a symlink or mount point between the pre-scan and the per-file staging, causing the canonical path to escape the upload root.","commonSituations":"Importing a directory tree that contains mount points or bind mounts pointing outside the root. A shared or adversarial workspace where a sibling process replaces a directory with a symlink during import. Linux /proc or /sys style virtual filesystem entries that resolve outside the apparent tree.","solutions":["Examine the flagged displayPath and its parent directories for symlinks or mount points using `readlink -f` or `find -type l`.","Ensure the source tree does not contain mount points or symlinks to external locations.","Copy the subtree to a clean temp directory with `cp -r --no-dereference` excluded, then import from there."],"exampleFix":"// before: import /shared/project where /shared/project/lib -> /usr/lib\n// after: remove or resolve the escaping link\n//   rm /shared/project/lib\n//   cp -r /actual/lib /shared/project/lib","handlingStrategy":"validation","validationCode":"const { realpath } = await import('node:fs/promises')\nconst { relative, isAbsolute, sep } = await import('node:path')\n\nasync function assertPathInsideRoot(rootReal: string, candidate: string): Promise<void> {\n  const resolved = await realpath(candidate)\n  const rel = relative(rootReal, resolved)\n  if (rel !== '' && (rel === '..' || rel.startsWith(`..${sep}`) || isAbsolute(rel))) {\n    throw new Error(`Path escapes root: ${candidate} -> ${resolved}`)\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await stageRemoteImport(sourcePath)\n} catch (error) {\n  if (error instanceof Error && error.message.includes('Path escaped upload root')) {\n    showUserError('The source tree contains a path that escapes the import root. Check for mount points or replaced directories.')\n    return\n  }\n  throw error\n}","preventionTips":["Check source trees for mount points and bind mounts with `mountpoint` or `findmnt`.","Run `find <source> -type l` to detect symlinks that could resolve outside the root.","Import from a clean copy that has no external links or mounts."],"tags":["path-traversal","security","filesystem","upload-staging","symlink","ipc"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}