Я пишу (expressjs) http-сервис, который получает относительный путь как пользовательский ввод для каждого вызова, считывает файл из файловой системы на основе этого пути и обрабатывает его, например:Safe path.resolve без выхода из родителя
app.get("/api", (req, res, next) => {
var filePath = path.resolve("./datasource", req.query.path);
fs.readFile(filePath, "utf8", (err, data) => {
processData(data, (err, processed) => {
res.json(processed);
});
});
});
Устранение ошибок для ясности. Проблема заключается в том, что можно вызвать URL /api?path=../../../etc/passwd
, и это приведет к утечке информации с самого сервера. Я бы хотел, чтобы этот api не обрабатывал файлы за пределами папки ./datasource
. Я думаю, что я мог бы использовать некоторую индивидуальную реализацию path.resolve
, которая не позволяет родителям, но похоже, что в модуле path
такой функции нет. Некоторые примеры я думал:
saferesolve("./datasource", "a/b") === "./datasource/a/b"
saferesolve("./datasource", "a/b/../c") === "./datasource/a/c"
saferesolve("./datasource", "../..") === "./datasource"
saferesolve("./datasource", "../../a/b") === "./datasource/a/b"
saferesolve("./datasource", "../../a/b/..") === "./datasource/a"
Любые идеи, как это сделать, не изобретая весь path
модуль?
Я чувствую себя хорошо об этом подходе, но не работает на окнах. Возможно, использование 'path.posix.resolve' было бы лучше. –
@TamasHegedus Я обновил свой ответ, чтобы добавить бит '.posix' в каждый вызов метода' path', но у меня нет доступа к компьютеру с Windows, чтобы вы могли сообщить мне, что для вас результат? Мне просто интересно, что происходит. – idbehold
Отлично, спасибо, я думаю, это то, что я искал! –