Triển khai nodejs và express nên nhớ có một bài học đừng quên

Nội dung bài viết

Request entity too large nodejs, vâng chính là lỗi đó Anh. Chúng ta bị chơi rồi, nhưng Bạn A cũng đã khắc phục xong nhanh chóng, sao nó đơn giản mà chúng ta lại bị bỏ qua nhỉ?

Tình huống thực tế

Chả là anh em chúng tôi đang làm API cho bên thứ 3 để lấy những sản phẩm bán chạy trong tháng vừa qua, nó cũng liên quan đến phần thiết kế ở những bài trước về hệ thống thương mại điện tử, nhưng ở đây đang giai đoạn demo thôi. Chính vì thiết kế cho bạn IT bên đó lấy data về cho nên cũng chủ quan, không trust ip, không sercu lắm và cũng từ đây có một lỗ hổng được phát hiện, nhanh chóng đã được vá bởi anh em. Cụ thể như sau.

Anh em biết đó khi không trust ip thì thằng nào nó nhìn lén thấy api thì nó test ngay hệ thống mình đơn giản bẳng cách push data body quá mức cho phép. Cụ thể là Buffering and parsing mỗi lần lên, tốn tài nguyên chết mịa đi được. Chính vì vậy nếu không có giới hạn về kích thước của các yêu cầu, những kẻ tấn công có thể gửi một lượng data lớn lên các request và có thể làm cạn kiệt bộ nhớ server và ổ đĩa full luôn. Tạm vậy thôi, không chi tiết. Và một bạn trong team đã nhanh chóng xử lý thông qua bài viết được tìm và kết hợp với thư viện raw-body.

Request entity too large nodejs


Đặt giới hạn kích thước yêu cầu

Bạn có thể giới hạn kích thước nội dung yêu cầu cho tất cả các yêu cầu sử dụng raw-body

const contentType = require('content-type')
const express = require('express')
const getRawBody = require('raw-body')

const app = express()

app.use(function (req, res, next) {
  if (!['POST', 'PUT', 'DELETE'].includes(req.method)) {
    next()
    return
  }

  getRawBody(req, {
    length: req.headers['content-length'],
    limit: '1kb',
    encoding: contentType.parse(req).parameters.charset
  }, function (err, string) {
    if (err) return next(err)
    req.text = string
    next()
  })
})

Tuy nhiên nếu bạn để ý sẽ thấy, ở đây có gì sai sai, vì có nhiều request phải nhận khối lượng kb lớn hơn như upload file chẳng hạn. Ngoài ra, đầu vào có kiểu JSON nguy hiểm hơn, vì parsing JSON là một hoạt động chặn. Do đó, bạn nên đặt giới hạn kích thước yêu cầu cho các loại nội dung khác nhau. Bạn có thể thực hiện điều này rất dễ dàng với phần mềm trung gian nhanh như sau:

app.use(express.urlencoded({ extended: true, limit: "1kb" }));
app.use(express.json({ limit: "1kb" }));

Cần lưu ý rằng những kẻ không tốt có thể thay đổi tiêu đề Content-Type của yêu cầu và bỏ qua giới hạn kích thước yêu cầu. Do đó, trước khi xử lý yêu cầu, dữ liệu có trong yêu cầu phải được xác thực dựa trên loại nội dung được nêu trong tiêu đề yêu cầu. Nhớ nhé xác thực lại lần nữa, giống như nó khai báo là file png nhưngg không phải vậy đâu =]]

Có thể bạn đã bị missing