{"record":{"id":"77ce9dd5f38946f0","repo":"stablyai/orca","slug":"unsafe-computer-screenshot-temp-path-outputdir","errorCode":null,"errorMessage":"Unsafe computer screenshot temp path: ${outputDir}","messagePattern":"Unsafe computer screenshot temp path: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cli/computer-format.ts","lineNumber":110,"sourceCode":"    } as RuntimeRpcSuccess<TResult>\n  } catch {\n    // Why: temp-file export is an ergonomics optimization; keep inline screenshot\n    // data when disk, permissions, or path validation would otherwise fail --json.\n    return response\n  }\n}\n\nconst COMPUTER_SCREENSHOT_TTL_MS = 24 * 60 * 60 * 1000\nconst COMPUTER_SCREENSHOT_CLEANUP_INTERVAL_MS = 60 * 60 * 1000\nconst COMPUTER_SCREENSHOT_CLEANUP_MARKER = '.last-cleanup'\n\nfunction computerScreenshotTempDir(): string {\n  const outputDir =\n    process.env.ORCA_COMPUTER_SCREENSHOT_TMPDIR || join(tmpdir(), 'orca-computer-use')\n  mkdirSync(outputDir, { recursive: true, mode: 0o700 })\n  const stat = lstatSync(outputDir)\n  if (!stat.isDirectory() || stat.isSymbolicLink()) {\n    throw new Error(`Unsafe computer screenshot temp path: ${outputDir}`)\n  }\n  if (typeof process.getuid === 'function' && stat.uid !== process.getuid()) {\n    throw new Error(`Computer screenshot temp path is not owned by the current user: ${outputDir}`)\n  }\n  chmodSync(outputDir, 0o700)\n  return outputDir\n}\n\nfunction cleanupComputerScreenshots(outputDir: string): void {\n  const now = Date.now()\n  const markerPath = join(outputDir, COMPUTER_SCREENSHOT_CLEANUP_MARKER)\n  try {\n    // Why: agents can call computer-use CLI commands in loops; a marker keeps\n    // temp cleanup from becoming a synchronous directory scan per screenshot.\n    if (statSync(markerPath).mtimeMs > now - COMPUTER_SCREENSHOT_CLEANUP_INTERVAL_MS) {\n      return\n    }\n  } catch {","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/cli/computer-format.ts#L92-L128","documentation":"Thrown by computerScreenshotTempDir() after creating the screenshot temp dir: if the resolved path is not a directory or is a symbolic link, the path is considered unsafe for writing screenshots. This guards against symlink-traversal and non-directory inode attacks on a path the agent writes screenshot data into, since the directory is created with mode 0700 but an attacker could have pre-placed a symlink or file.","triggerScenarios":"ORCA_COMPUTER_SCREENSHOT_TMPDIR (or the default <tmpdir>/orca-computer-use) resolves to a regular file, a device, or a symlink rather than a real directory owned by the process.","commonSituations":"Setting ORCA_COMPUTER_SCREENSHOT_TMPDIR to an existing file or a symlink, a shared /tmp where another user or a broken cleanup script left a file at that name, or pointing the env var at a path inside a symlinked mount.","solutions":["Point ORCA_COMPUTER_SCREENSHOT_TMPDIR at a real directory you own, or unset it to use the default.","Remove the offending non-directory/symlink entry at the resolved path so mkdirSync can recreate it as a directory.","Avoid symlinks in the screenshot temp path; resolve them before setting the env var."],"exampleFix":"# before\nexport ORCA_COMPUTER_SCREENSHOT_TMPDIR=/tmp/my-link   # symlink\n\n# after\nexport ORCA_COMPUTER_SCREENSHOT_TMPDIR=/tmp/real-dir   # mkdir -p first","handlingStrategy":"validation","validationCode":"import { lstatSync } from 'node:fs'\n\nfunction safeScreenshotTmpdir(p: string): string {\n  const st = lstatSync(p)\n  if (!st.isDirectory() || st.isSymbolicLink()) {\n    throw new Error(`Refusing unsafe screenshot tmpdir: ${p}`)\n  }\n  return p\n}","typeGuard":"function isRealDirectory(p: string): boolean {\n  try {\n    const st = lstatSync(p)\n    return st.isDirectory() && !st.isSymbolicLink()\n  } catch {\n    return false\n  }\n}","tryCatchPattern":null,"preventionTips":["Never set ORCA_COMPUTER_SCREENSHOT_TMPDIR to a symlink.","Pre-create the directory owned by the runtime user before launch.","Keep the temp dir out of world-writable shared paths prone to tampering."],"tags":["security","filesystem","computer-use","temp-dir"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}