← Back to PRs

#21245: fix(plugins): harden symlinked extension discovery

by victorGPT open 2026-02-19 20:46 View on GitHub →
size: S
## Summary - discover bundled plugin directories that are symlink entries - support symlinked extension file entries safely - ignore broken symlink entries without crashing discovery - add focused discovery tests for symlink file and broken-link edge cases ## Test Plan - pnpm -C /Users/farmer/.openclaw/workspace/repos-main/openclaw exec vitest run --config vitest.unit.config.ts src/plugins/discovery.test.ts <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR enables plugin discovery to handle symlinked directories and files safely by resolving symlink targets and ignoring broken symlinks. **Changes:** - Introduced `resolveDirentKind` helper that uses `fs.statSync` to resolve symlink targets when `entry.isFile()` and `entry.isDirectory()` return false - Modified file discovery to set `rootDir` to the symlink path itself for symlinked files, rather than the parent directory - Broken symlinks are caught and silently skipped during discovery - Added three focused tests: symlinked bundled plugin directories, symlinked extension files, and broken symlink handling **Security considerations:** For symlinked extension files, the `rootDir` is set to the file path itself (line `src/plugins/discovery.ts:375`), which causes the "source escapes root" check in `checkSourceEscapesRoot` to always pass (both paths resolve to the same realpath). This allows symlinked extensions to reference files anywhere on the filesystem, though they still must satisfy permission checks (not world-writable, correct ownership). This appears intentional based on the PR's goal to "support symlinked extension file entries safely," where safety is enforced through permission validation rather than path containment. <h3>Confidence Score: 4/5</h3> - This PR is safe to merge with minor caveats around the security model change for symlinked files - The implementation is solid with good test coverage for the symlink edge cases. The security posture shift (allowing symlinks to escape the extensions directory) is intentional and mitigated by permission checks. The code correctly handles broken symlinks and maintains existing security checks for package-based extensions. Score is 4 instead of 5 due to the subtle security model change that may warrant additional documentation or review. - No files require special attention - the implementation is straightforward and well-tested <sub>Last reviewed commit: 4712754</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs