server: isAllowedPath: follow symlinks to validate the realpath

This prevents the attacker from downloading a soft symbol link first
and then use the symbol link to bypass the allowed paths validation.
This commit is contained in:
Jesse Chan
2020-10-31 21:26:50 +08:00
parent d8ee4e3249
commit d00728028e
3 changed files with 23 additions and 6 deletions
+17 -2
View File
@@ -20,15 +20,30 @@ export const isAllowedPath = (resolvedPath: string) => {
if (config.allowedPaths == null) {
return true;
}
let realPath: string | null = null;
let parentPath: string = resolvedPath;
while (realPath == null) {
try {
realPath = fs.realpathSync(parentPath);
} catch (e) {
if (e.code === 'ENOENT') {
parentPath = path.resolve(parentPath, '..');
} else {
return false;
}
}
}
return config.allowedPaths.some((allowedPath) => {
if (resolvedPath.startsWith(allowedPath)) {
if (realPath?.startsWith(allowedPath)) {
return true;
}
return false;
});
};
export const sanitizePath = (input: string) => {
export const sanitizePath = (input: string): string => {
if (typeof input !== 'string') {
throw accessDeniedError();
}