-
-
Notifications
You must be signed in to change notification settings - Fork 499
Description
Firstly, thank-you for the useful library, and your time to read this issue.
I use glob to scan a file system which I don't control, and can include aliases / symlinks. Example plugin file/folder structure:
|- plugin.vst3
|- LICENSE.md
|- VST Plug-Ins -> /Library/Audio/Plug-Ins/VST3
RunningglobSync('**/*.*');
follows the symlinks and outputs many more files:
[
'plugin.vst3',
'LICENSE.md',
'VST Plug-Ins/plugin2.vst3',
...
'VST Plug-Ins/plugin9999.vst3',
]
Trying with options such as { follow: false, nodir: true }
does not filter out the symlinks.
As mentioned in the README glob relies on bash behavior:
https://github.com/isaacs/node-glob/blob/main/README.md?plain=1#L537
And this comment mentioned that "do not follow symlinks" is not a supported feature:
#242 (comment)
If I run the same code with { realpath: true}
then its clearer what is happening:
[
'plugin.vst3',
'LICENSE.md',
'/Library/Audio/Plug-Ins/VST3/plugin2.vst3',
'/Library/Audio/Plug-Ins/VST3/plugin3.vst3',
...
]
I can prevent this behavior myself outside of glob such as:
1. Remove symlinks before running glob
import fs from 'fs/promises';
import path from 'path';
async function removeSymlinks(dir) {
try {
const entries = await fs.readdir(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isSymbolicLink()) {
await fs.unlink(fullPath);
console.log(`Removed symlink: ${fullPath}`);
} else if (entry.isDirectory()) {
await removeSymlinks(fullPath); // Recurse into subdirectories
}
}
} catch (err) {
console.error(`Error processing ${dir}:`, err);
}
}
// Example usage:
// removeSymlinks('/path/to/directory').catch(console.error);
2. Use glob realpath: true and filter out non matching paths
import fs from 'fs/promises';
import path from 'path';
import { globSync } from 'glob';
function filterDirectoriesOutsideBase(baseDir) {
const allPaths = globSync(`${baseDir}/**/*.*`, { realpath: true });
return allPaths.filter((p) => !p.startsWith(baseDir));
}
// Example usage:
// const filteredPaths = filterDirectoriesOutsideBase('/path/to/directory');
// console.log('Filtered directories outside base:', filteredPaths);
However if low level filesystems can filter out symlinks, it would be more optimal to filter out symlinks inside the glob
library. There are several benefits of a Do not follow symlinks
feature for glob users:
- Security - For clients who don't control the filesystem, disabling symlinks prevents a malicious actor using symlinks to trick the program/script into reading a malicious file, or scanning another drive containing other files, wasting resources or causing scripts to error.
- Performance - Symlinks could cause a script to scan many more paths than expected and recursive loops etc
- Developer time - I have already spent several hours on trying to find out why my script was copying the extra files, and incorrectly using
follow
options. Multiply the time-saving by the 190 million weekly downloads of this library, I think there is potential to a large amount of developer time.
Thank-you!