- vừa được xem lúc

Blog#212: 🔐Securing File Uploads in Node.js Express: A Comprehensive Guide

0 0 23

Người đăng: NGUYỄN ANH TUẤN

Theo Viblo Asia

212

Hi, I'm Tuan, a Full-stack Web Developer from Tokyo 😊. Follow my blog to not miss out on useful and interesting articles in the future.

File uploads are a common feature in modern web applications. Users can submit images, videos, documents, and other types of files to interact with the service. However, file uploads also bring potential security risks. This article will provide you with an in-depth, visual guide to securing file uploads in a Node.js Express application. Follow along to ensure your app remains safe and efficient.

1. Understanding the Risks of File Uploads

Before diving into the security measures, it's essential to understand the potential risks associated with file uploads. Some of these risks include:

  1. Malicious file uploads: Attackers may upload files containing harmful scripts that could compromise your application or server.
  2. Denial of Service (DoS) attacks: A large number of file uploads can exhaust server resources, causing the app to become unresponsive.
  3. Sensitive data exposure: Unauthorized users may gain access to files containing sensitive information.

2. Setting Up a Basic Node.js Express Application

To demonstrate how to secure file uploads, let's set up a basic Node.js Express application. Begin by installing the required packages:

npm init -y
npm install express multer

Next, create an app.js file and import the necessary modules:

const express = require('express');
const multer = require('multer'); const app = express();
const port = process.env.PORT || 3000; app.listen(port, () => { console.log(`Server running at http://localhost:${port}`);
});

3. Implementing File Uploads with Multer

Multer is a popular middleware for handling file uploads in Express. Begin by configuring Multer and setting up the storage engine:

const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, './uploads'); }, filename: (req, file, cb) => { const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); cb(null, file.fieldname + '-' + uniqueSuffix); },
}); const upload = multer({ storage });

Now, create a route for file uploads:

app.post('/upload', upload.single('file'), (req, res) => { res.status(200).send({ message: 'File uploaded successfully.' });
});

4. Securing File Uploads

4.1 Limit File Size

The first security measure is to limit the file size. This can help prevent DoS attacks and reduce the risk of running out of server resources. Set a file size limit when configuring Multer:

const upload = multer({ storage, limits: { fileSize: 2 * 1024 * 1024 }, // 2MB
});

4.2 Validate File Types

Ensure that only specific file types are allowed. This reduces the risk of malicious file uploads. Add a file filter function to the Multer configuration:

const allowedFileTypes = ['image/jpeg', 'image/png', 'image/gif']; const fileFilter = (req, file, cb) => { if (allowedFileTypes.includes(file.mimetype)) { cb(null, true); } else { cb(null, false); }
}; const upload = multer({ storage, limits: { fileSize: 2 * 1024 * 1024 }, fileFilter,
});

4.3 Handle Rejected Files

When a file is rejected, it's essential to provide the user with an appropriate error message. Update the /upload route to handle rejected files:

app.post('/upload', upload.single('file'), (req, res) => { if (!req.file) { return res.status(400).send({ message: 'Invalid file type or file too large.' }); } res.status(200).send({ message: 'File uploaded successfully.' });
});

4.4 Scan Files for Malware

To further protect your application, scan uploaded files for malware. One option is to use the ClamAV antivirus engine. Install the clamscan package:

npm install clamscan

Then, import and configure the ClamScan module:

const { NodeClam } = require('clamscan');
const clamscan = new NodeClam(); clamscan.init({ clamdscan: { path: '/usr/bin/clamdscan', // Path to clamdscan binary on your server config_file: '/etc/clamd.d/scan.conf', // Path to ClamAV config file on your server }, preference: 'clamdscan',
});

Scan the uploaded file for malware in the/upload route:

app.post('/upload', upload.single('file'), async (req, res) => { if (!req.file) { return res.status(400).send({ message: 'Invalid file type or file too large.' }); } try { const scanResult = await clamscan.scan_file(req.file.path); if (scanResult.is_infected) { fs.unlinkSync(req.file.path); // Delete infected file return res.status(400).send({ message: 'File is infected with malware.' }); } res.status(200).send({ message: 'File uploaded successfully.' }); } catch (error) { res.status(500).send({ message: 'Error scanning file for malware.' }); }
});

Don't forget to import the fs module:

const fs = require('fs');

4.5 Store Files Outside the Web Root

Storing uploaded files outside the web root helps prevent direct access to those files. In this example, we'll use the uploads folder, which should be outside your web root directory.

const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, '../uploads'); }, // ...
});

4.6 Serve Files Securely

To serve files securely, create a new route that verifies the user's authorization and serves the file using the res.sendFile() method:

app.get('/files/:filename', (req, res) => { // Verify user authorization here const filename = req.params.filename; const filePath = path.join('../uploads', filename); res.sendFile(filePath);
});

Don't forget to import the path module:

const path = require('path');

Conclusion

By following this comprehensive guide, you can create a secure file upload system in a Node.js Express application. Implementing proper security measures, like limiting file size, validating file types, scanning files for malware, and serving files securely, will help protect your app from various risks associated with file uploads.

And Finally

As always, I hope you enjoyed this article and got something new. Thank you and see you in the next articles!

If you liked this article, please give me a like and subscribe to support me. Thank you. 😊

Ref

Bình luận

Bài viết tương tự

- vừa được xem lúc

Cách mình "hack" được vào hẹ thống của SMAS để xem điểm.

Cách mà mình "hack" được vào hệ thống của SMAS. Thật ra dùng từ hack cũng không đúng lắm, chỉ là một vài trick để lừa hệ thống mà thôi.

0 0 145

- vừa được xem lúc

[NodeJs] Tạo QR Code trong nodeJs với qrcode

Tạo mã QR Code trong nodejs với qrcode. QR Code là gì. Tạo QR code với qrcode. Cài đặt thư viện qrcode.

0 0 34

- vừa được xem lúc

Áp dụng kiến trúc 3 Layer Architecture vào project NodeJS

The problem encountered. Các framework nodejs phổ biết như Express cho phép chúng ta dễ dàng tạo ra Resful API xử lí các request từ phía client một cách nhanh chóng và linh hoạt.

0 0 80

- vừa được xem lúc

Router, Controller trong Express

Mở đầu. Xin chào các bạn mình đã quay trở lại rồi đây, tiếp tục với series Nodejs cơ bản thì hôm nay mình sẽ giới thiệu đến các bạn Express Router và Controller.

0 0 40

- vừa được xem lúc

Xây dựng CRUD RESTful API sử dụng Node, Express, MongoDB.

Introduction. Trong phạm vi bài viết này chúng ta sẽ cùng tìm hiểu về cách tạo restful api với Node, Express và MongoDB. . Xử lý các hoạt động crud.

0 0 225

- vừa được xem lúc

Rate time limit trong NodeJS

Chào các bạn, lại là mình đây. Hôm nay mình xin giới thiệu tới các bạn một kỹ thuật rất hay ho và hữu ích đó là Rate Limiting. 1. Rate Limiting là gì.

0 0 62