Fix security vulnerabilities
This commit is contained in:
Vendored
+24
-3
@@ -1,15 +1,36 @@
|
||||
import { realpathSync } from "fs";
|
||||
import path from "path";
|
||||
export default function isSafePath({ filePath, allowedDir, }) {
|
||||
const allowed = path.resolve(allowedDir);
|
||||
const resolved = path.resolve(filePath);
|
||||
if (!resolved.startsWith(allowedDir + path.sep) && resolved !== allowedDir) {
|
||||
if (!isInside(resolved, allowed)) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const real = realpathSync(resolved);
|
||||
return (real.startsWith(allowedDir + path.sep) || real === allowedDir);
|
||||
return isInside(realpathSync(resolved), resolveRealDir(allowed));
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function isInside(target, dir) {
|
||||
return target === dir || target.startsWith(dir + path.sep);
|
||||
}
|
||||
const REAL_DIRS = new Map();
|
||||
/**
|
||||
* Resolves symlinks in the allowed directory itself (e.g. a project under a
|
||||
* symlinked path), so real file paths inside it still match.
|
||||
*/
|
||||
function resolveRealDir(dir) {
|
||||
const cached = REAL_DIRS.get(dir);
|
||||
if (cached)
|
||||
return cached;
|
||||
try {
|
||||
const real = realpathSync(dir);
|
||||
REAL_DIRS.set(dir, real);
|
||||
return real;
|
||||
}
|
||||
catch {
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user