{"record":{"id":"8cccb1f2bcb021c0","repo":"mastra-ai/mastra","slug":"invalid-file-path-filepath-path-traversal-is","errorCode":null,"errorMessage":"Invalid file path \"${filePath}\". Path traversal is not allowed.","messagePattern":"Invalid file path \"(.+?)\"\\. Path traversal is not allowed\\.","errorType":"validation","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"packages/server/src/server/handlers/skills-sh-shared.ts","lineNumber":114,"sourceCode":"}\n\n/**\n * Validate that a file path is safe (no traversal, no absolute paths).\n * Prevents malicious API responses from writing files outside the skill\n * directory.\n */\nexport function assertSafeFilePath(filePath: string): string {\n  if (filePath.startsWith('/') || filePath.startsWith('\\\\') || /^[a-zA-Z]:[\\\\/]/.test(filePath)) {\n    throw new HTTPException(400, {\n      message: `Invalid file path \"${filePath}\". Absolute paths are not allowed.`,\n    });\n  }\n  // Normalize backslashes to forward slashes so Windows-style traversal\n  // (e.g. \"..\\\\..\\\\etc\\\\passwd\") cannot bypass the segment check below.\n  const segments = filePath.split(/[\\\\/]/);\n  for (const segment of segments) {\n    if (segment === '..' || segment === '.') {\n      throw new HTTPException(400, {\n        message: `Invalid file path \"${filePath}\". Path traversal is not allowed.`,\n      });\n    }\n  }\n  return filePath;\n}\n\n// =============================================================================\n// API calls\n// =============================================================================\n\ninterface UpstreamSkillsList {\n  skills: Array<{\n    skillId: string;\n    name: string;\n    installs: number;\n    source: string;\n    owner: string;","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/skills-sh-shared.ts#L96-L132","documentation":"A 400 from `assertSafeFilePath` raised when any path segment equals '..' or '.', i.e. the path attempts directory traversal. Backslashes are normalized first so Windows-style traversal (\"..\\\\..\\\\etc\\\\passwd\") is caught too. This guards the skill directory sandbox.","triggerScenarios":"A skill file entry like '../../escape.txt' or '.\\\\..\\\\secret'; any relative path containing dot-dot segments submitted to skill file operations.","commonSituations":"Malicious or buggy upstream skill manifests using '..' to escape the skill directory; generating relative paths with string concatenation instead of path libraries.","solutions":["Remove '..' and '.' segments by resolving the path within the skill directory and re-relativizing it.","Skip/flag the offending file or skill rather than rewriting it blindly.","Use path.posix.normalize and verify the result stays inside the skill root before persisting.","Validate paths client-side with the same segment check before calling the API."],"exampleFix":"// before\nconst filePath = '../../etc/passwd';\nawait installSkillFile(skill, filePath);\n// after\nconst safe = filePath.split(/[\\\\/]/).every(s => s !== '..' && s !== '.');\nif (!safe) throw new Error('Refusing unsafe path');\nawait installSkillFile(skill, filePath);","handlingStrategy":"validation","validationCode":"const segments = filePath.split(/[\\\\/]/);\nif (segments.some(s => s === '..' || s === '.')) throw new Error(`Path \"${filePath}\" contains traversal segments.`);","typeGuard":null,"tryCatchPattern":"try {\n  await installSkill(skill);\n} catch (e) {\n  if (e instanceof MastraClientError && e.status === 400 && /Path traversal is not allowed/.test(e.message)) {\n    console.error('Skill file path attempts traversal — reject the file/skill as unsafe.');\n  } else throw e;\n}","preventionTips":["Normalize paths (path.posix.normalize) and re-check containment within the skill root before sending.","Reject any manifest path containing '..' or '.' segments at parse time.","Write tests for traversal payloads including Windows-style backslash variants."],"tags":["security","path-traversal","http-400","skills"],"backgroundTag":"path-traversal-blocked","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}