Как безопасно загрузить файлы в Node с помощью Express?

Существует много статей, учебных пособий и вопросов о загрузке файлов в узле, но в основном они предназначены для начинающих, и ни одна из них не объясняет полностью, как обеспечить загрузку файлов для производства. Я очень старался найти полный ответ о том, как это сделать, но это не удалось.

Ниже приводится объяснение моих выводов.

  1. Ограничить размер файла при загрузке:

    app.use(express.limit('4mb'));
    
  2. Ограничить загрузку файлов только определенными маршрутами: я не могу заставить это работать, но вот что я попробовал:

    Заменить:

    app.use(express.bodyParser());
    

    с

    app.use(express.json());
    app.use(express.urlencoded());
    

    и добавьте промежуточное программное обеспечение из нескольких частей к каждому маршруту загрузки:

    app.post('/upload', express.multipart(), uploadController.uploadPhoto);
    

    Эта часть не работает, но загрузка работает нормально, если я уйду express.bodyParser(), Так что я делаю не так?

  3. Проверка типа загруженного файла перед сохранением загрузки на диск:

    Я не мог понять эту часть, но было предложено написать специальное промежуточное программное обеспечение, которое использует огромные возможности для анализа загрузки файлов и попытки изменить размер файла до его сохранения (при условии, что это изображение) с использованием библиотеки, подобной магии изображений. Предполагалось, что это сделает изображение безопасным и гарантирует, что оно действительно является изображением (потому что процесс не будет выполнен, если это не изображение).

    Это будет работать только с изображениями, так что это не полное решение.

    Как я могу это реализовать? Любой пример кода?

Есть ли что-то еще, что я пропускаю для загрузки, чтобы быть безопасным?

2 ответа

Подход 2 действительно работает. Проблема у меня была в том, что

app.use(passport.session());

мешал ему работать. Итак, если вы используете passport.js для аутентификации это может быть проблемой. Если вы используете этот подход, просто убедитесь, что добавили безопасность на фактический маршрут.


Я в конечном итоге с помощью этого плагина

https://github.com/tih-ra/alleup

который отлично работает с загрузкой изображений, автоматически изменяет размеры файлов до нескольких версий и загружает их в amazon s3. Использование этого плагина было бы встроенным с использованием подхода 3, но файлы загружаются в tmp Папка, а затем удаляется.

Я использую многопартийность для загрузки (и потокового) файлов.

var form = new multiparty.Form();

До 1:

form.on('progress', function (bytesReceived) {
  if (262144000 < bytesReceived) {
   abortConnection('filesizeexeeded');
  }
});

реализовать собственную функцию прерывания соединения; например:

function abortConnection(reason) {
  res.writeHead(413, { 'Connection': 'close' });
  return res.end(reason);
}

предупреждение: браузер, скорее всего, повторит попытку загрузки (до 4 раз). Я использую подключение через веб-сокет, чтобы отменить загрузку на стороне клиента.

До 2: (использовать многопартийность)

На 3: я создал суть, которая показывает, как проверить MIME-тип на лету с помощью mmmagic.

Если вы используете паспорт в сочетании с многопартийностью, это может оказаться полезным:

https://github.com/jaredhanson/passport/pull/106

Другие вопросы по тегам