fix(security): resolve symlinks in path-suggestions home directory check (fixes #52) (#54)

The isWithinHome() check used path.relative() which is purely string-based
and does not follow symlinks. A symlink inside the home directory pointing
to an external path would bypass the containment check, allowing directory
listing of arbitrary filesystem locations.

Now uses fs.realpathSync() to resolve symlinks before the containment
comparison, ensuring the real filesystem path is validated.

Co-authored-by: ThankNIXlater <ThankNIXlater@users.noreply.github.com>
This commit is contained in:
Nix
2026-03-24 21:33:24 +05:30
committed by GitHub
parent 88b1e9b749
commit 6666be0652
+11 -1
View File
@@ -42,8 +42,18 @@ const normalizeQuery = (query: string): string => {
return `~/${withoutLeading}`;
};
const resolveRealPath = (value: string): string => {
try {
return fs.realpathSync(value);
} catch {
return path.resolve(value);
}
};
const isWithinHome = (target: string, home: string): boolean => {
const relative = path.relative(home, target);
const resolvedTarget = resolveRealPath(target);
const resolvedHome = resolveRealPath(home);
const relative = path.relative(resolvedHome, resolvedTarget);
if (!relative) return true;
return !relative.startsWith("..") && !path.isAbsolute(relative);
};