{"record":{"id":"bfa0a8cc5fd0a04a","repo":"remotion-dev/remotion","slug":"path-is-outside-of-the-parent-directory-not-allo","errorCode":null,"errorMessage":"Path is outside of the parent directory - not allowing reading of arbitrary files","messagePattern":"Path is outside of the parent directory - not allowing reading of arbitrary files","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/readers/from-node.ts","lineNumber":126,"sourceCode":"\tif (typeof src !== 'string') {\n\t\tthrow new Error('src must be a string when using `nodeReader`');\n\t}\n\n\treturn promises.readFile(src, 'utf8');\n};\n\nexport const nodeCreateAdjacentFileSource: CreateAdjacentFileSource = (\n\trelativePath,\n\tsrc,\n) => {\n\tif (typeof src !== 'string') {\n\t\tthrow new Error('src must be a string when using `nodeReader`');\n\t}\n\n\tconst result = join(dirname(src), relativePath);\n\tconst rel = relative(dirname(src), result);\n\tif (rel.startsWith('..')) {\n\t\tthrow new Error(\n\t\t\t'Path is outside of the parent directory - not allowing reading of arbitrary files',\n\t\t);\n\t}\n\n\treturn result;\n};\n\nexport const nodeReader: MediaParserReaderInterface = {\n\tread: nodeReadContent,\n\treadWholeAsText: nodeReadWholeAsText,\n\tcreateAdjacentFileSource: nodeCreateAdjacentFileSource,\n\tpreload: () => {\n\t\t// doing nothing, it's just for when fetching over the network\n\t},\n};\n","sourceCodeStart":108,"sourceCodeEnd":142,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/readers/from-node.ts#L108-L142","documentation":"Thrown by nodeCreateAdjacentFileSource as a security guard after computing the adjacent path: it joins relativePath with dirname(src), then checks the result with path.relative; if the result starts with '..' it means the requested file would escape the media's parent directory, which is treated as an arbitrary-file-read attempt and rejected.","triggerScenarios":"A media container references an adjacent file via a path containing '../' sequences or an absolute path that resolves outside the media's directory. For example, a crafted file listing 'tracks/../../etc/passwd' or '/etc/secret' as a companion resource.","commonSituations":"Parsing untrusted user-uploaded media whose metadata embeds path-traversal payloads. Bugs in relative-path computation that prepend too many '..' segments. Absolute paths supplied where relatives are expected.","solutions":["Treat the error as intentional: do not weaken it. Ensure the adjacent file legitimately lives under the media's parent directory.","If you control the companion path, use a path that stays within dirname(src), e.g. 'subtitles/en.vtt' not '../shared/en.vtt'.","For untrusted media, run the parser in a sandbox with a restricted root, and reject inputs that trigger this guard."],"exampleFix":"// before - companion path escapes parent dir\nadjacent: '../shared/captions.vtt' // -> throws\n\n// after - companion path stays under parent dir\nadjacent: 'captions.vtt'","handlingStrategy":"try-catch","validationCode":"import { relative, dirname, join, resolve } from 'node:path';\nfunction isSafeAdjacent(mediaSrc: string, rel: string): boolean {\n  const base = resolve(dirname(mediaSrc));\n  const target = resolve(base, rel);\n  const rel2 = relative(base, target);\n  return !rel2.startsWith('..') && !resolve(rel).startsWith('/');\n}\nisSafeAdjacent(src, companionRel);","typeGuard":"const staysInParent = (base: string, target: string) => !relative(base, target).startsWith('..');","tryCatchPattern":"try { await parseMedia({ src, fields }); } catch (e) { if (/outside of the parent directory/.test(String((e as Error).message))) { /* reject untrusted media or use inline assets */ } else throw e; }","preventionTips":["Treat this guard as a security feature; never bypass it.","Run parsers over untrusted media in a sandbox with a restricted root.","Prefer self-contained (inline) media to avoid adjacent-file references."],"tags":["media-parser","reader","node","security","path-traversal"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}