{"record":{"id":"ba8678e3cb154503","repo":"mihomo-party-org/clash-party","slug":"invalid-core-path-directory-traversal-detected","errorCode":null,"errorMessage":"Invalid core path: directory traversal detected","messagePattern":"Invalid core path: directory traversal detected","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main/core/permissions.ts","lineNumber":34,"sourceCode":"\n// 内核名称白名单\nconst ALLOWED_CORES = ['mihomo', 'mihomo-alpha', 'mihomo-smart'] as const\ntype AllowedCore = (typeof ALLOWED_CORES)[number]\ntype StopCoreBeforeAdminRestart = (force?: boolean) => Promise<void>\n\nlet stopCoreBeforeAdminRestart: StopCoreBeforeAdminRestart | null = null\n\nexport function setStopCoreBeforeAdminRestart(stopCore: StopCoreBeforeAdminRestart): void {\n  stopCoreBeforeAdminRestart = stopCore\n}\n\nexport function isValidCoreName(core: string): core is AllowedCore {\n  return ALLOWED_CORES.includes(core as AllowedCore)\n}\n\nexport function validateCorePath(corePath: string): void {\n  if (corePath.includes('..')) {\n    throw new Error('Invalid core path: directory traversal detected')\n  }\n\n  const dangerousChars = /[;&|`$(){}[\\]<>'\"\\\\]/\n  if (dangerousChars.test(path.basename(corePath))) {\n    throw new Error('Invalid core path: contains dangerous characters')\n  }\n\n  const normalizedPath = path.normalize(path.resolve(corePath))\n  const expectedDir = path.normalize(path.resolve(mihomoCoreDir()))\n\n  if (!normalizedPath.startsWith(expectedDir + path.sep) && normalizedPath !== expectedDir) {\n    throw new Error('Invalid core path: not in expected directory')\n  }\n}\n\nfunction shellEscape(arg: string): string {\n  return \"'\" + arg.replace(/'/g, \"'\\\\''\") + \"'\"\n}","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/mihomo-party-org/clash-party/blob/911e090537acdf7c50bee1c3aebecc2ef119a8b5/src/main/core/permissions.ts#L16-L52","documentation":"validateCorePath is a security guard for paths that will be handed to permission-granting commands (e.g. setuid/chmod for TUN). It rejects any core path containing '..' to prevent directory-traversal attacks where a caller could elevate or overwrite an unintended binary. The check is intentionally blunt: any '..' substring anywhere in the path throws immediately.","triggerScenarios":"Calling grantTunPermissions with a corePath containing '..' — e.g. a user-configured core path like '../opt/mihomo/mihomo' or a path built by naive string concatenation of a relative user setting with a base directory.","commonSituations":"Users typing relative paths in custom core-path settings; config migration producing '../../usr/bin/mihomo'; scripts/automation building paths with string concat instead of path.resolve; symlink-heavy setups where a relative shortcut seemed convenient.","solutions":["Pass an absolute, normalized path (path.resolve) to grantTunPermissions so no '..' segment remains.","Fix the user's custom core path setting to point directly at the binary (e.g. /opt/mihomo/mihomo).","If building paths programmatically, use path.join/path.resolve rather than string concatenation.","Reinstall the core to the app-managed location and clear the custom path override."],"exampleFix":"// before\nawait grantTunPermissions('../opt/mihomo/mihomo')\n\n// after\nconst corePath = path.resolve('/opt/mihomo/mihomo')\nif (corePath.includes('..')) throw new Error('bad core path')\nawait grantTunPermissions(corePath)","handlingStrategy":"validation","validationCode":"import path from 'path'\nfunction safeCorePath(input: string): string {\n  const resolved = path.resolve(input)\n  if (input.includes('..')) throw new Error('Directory traversal detected in core path')\n  if (!path.isAbsolute(resolved)) throw new Error('Core path must be absolute')\n  return resolved\n}\n// usage: await grantTunPermissions(safeCorePath(userCorePath))","typeGuard":"function isSafeCorePath(p: string): boolean {\n  return path.isAbsolute(p) && !p.includes('..') && path.basename(p).length > 0\n}","tryCatchPattern":"try {\n  validateCorePath(corePath)\n  await grantTunPermissions(corePath)\n} catch (e) {\n  if (String((e as Error).message).includes('traversal')) {\n    throw new Error(`Refusing unsafe core path \"${corePath}\"; use an absolute path without '..'`)\n  }\n  throw e\n}","preventionTips":["Always pass absolute paths built with path.resolve, never string-concatenated relative segments.","Restrict custom core paths to known install directories.","Treat any user-supplied path as untrusted and run the validator before any privileged operation."],"tags":["security","path-traversal","validation","permissions"],"backgroundTag":"path-traversal-detected","analyzedSha":"911e090537acdf7c50bee1c3aebecc2ef119a8b5","analyzedAt":"2026-08-30T13:00:49.174Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}