{"record":{"id":"367ad9bf81dd5e5a","repo":"angular/angular-cli","slug":"detected-a-potential-path-traversal-attempt-in","errorCode":null,"errorMessage":"Detected a potential path traversal attempt in '${pkgJsonPath}'. The path '${bestPracticesInfo.path}' escapes the package boundary. Falling back to the bundled guide.","messagePattern":"Detected a potential path traversal attempt in '(.+?)'\\. The path '(.+?)' escapes the package boundary\\. Falling back to the bundled guide\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/angular/cli/src/commands/mcp/tools/best-practices.ts","lineNumber":153,"sourceCode":"  try {\n    const pkgJsonContent = await readFile(pkgJsonPath, 'utf-8');\n    const pkgJson = JSON.parse(pkgJsonContent);\n    const bestPracticesInfo = pkgJson['angular']?.bestPractices;\n\n    if (\n      bestPracticesInfo &&\n      bestPracticesInfo.format === 'markdown' &&\n      typeof bestPracticesInfo.path === 'string'\n    ) {\n      const packageDirectory = dirname(pkgJsonPath);\n      const guidePath = resolve(packageDirectory, bestPracticesInfo.path);\n\n      // Ensure the resolved guide path is within the package boundary.\n      // Uses path.relative to create a cross-platform, case-insensitive check.\n      // If the relative path starts with '..' or is absolute, it is a traversal attempt.\n      const relativePath = relative(packageDirectory, guidePath);\n      if (relativePath.startsWith('..') || isAbsolute(relativePath)) {\n        logger.warn(\n          `Detected a potential path traversal attempt in '${pkgJsonPath}'. ` +\n            `The path '${bestPracticesInfo.path}' escapes the package boundary. ` +\n            'Falling back to the bundled guide.',\n        );\n\n        return undefined;\n      }\n\n      // Check the file size to prevent reading a very large file.\n      const stats = await stat(guidePath);\n      if (stats.size > 1024 * 1024) {\n        // 1MB\n        logger.warn(\n          `The best practices guide at '${guidePath}' is larger than 1MB (${stats.size} bytes). ` +\n            'This is unexpected and the file will not be read. Falling back to the bundled guide.',\n        );\n\n        return undefined;","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular/cli/src/commands/mcp/tools/best-practices.ts#L135-L171","documentation":"After resolving @angular/core's package.json, the tool computes the guide file's path and verifies it stays inside the package directory using a path.relative check (relative path must not start with '..' nor be absolute). If the resolved path escapes the package boundary — a potential path traversal — the tool warns and falls back to the bundled guide instead of reading the file.","triggerScenarios":"The path recorded in @angular/core's package.json (e.g. a guide path field) resolves outside the package directory — tampered/malicious package, symlink escapes, or an unusual package layout on case-insensitive filesystems.","commonSituations":"Compromised or patched node_modules packages; packages with symlinks pointing outside their directory; custom/renamed @angular/core forks with unexpected path fields.","solutions":["Reinstall dependencies (`npm ci`) to restore an untampered @angular/core package.","Check node_modules/@angular/core for unexpected symlinks or modified package.json path fields.","Audit installed package versions against the npm registry; rely on the bundled guide until resolved."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { relative, isAbsolute, resolve } from 'node:path';\nfunction isInsidePackage(pkgDir: string, target: string): boolean {\n  const rel = relative(resolve(pkgDir), resolve(target));\n  return !rel.startsWith('..') && !isAbsolute(rel);\n}\nif (!isInsidePackage(packageDirectory, guidePath)) {\n  console.warn('Resolved path escapes package boundary; use bundled guide.');\n}","typeGuard":null,"tryCatchPattern":"try {\n  assertInsidePackage(packageDirectory, guidePath);\n} catch {\n  return bundledGuide(); // safe fallback on traversal attempt\n}","preventionTips":["Keep node_modules pristine — use `npm ci` and verify integrity.","Inspect @angular/core for unexpected symlinks or modified path fields.","Keep the boundary check (relative path not starting with '..') in any path-based tooling."],"tags":["mcp","security","path-traversal","best-practices"],"backgroundTag":"path-traversal-detected","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}