FileDummy Logo
FileDummy
Bảo Mật & Toàn Vẹn Tệp Tin

Xác Thực Định Dạng Tệp Bằng Magic Bytes (Không Phụ Thuộc Vào Đuôi Mở Rộng)

Phát hiện định dạng tệp thực tế bằng magic bytes trong Node.js với thư viện file-type. Chặn đứng các tệp tin giả mạo đổi tên.

26 tháng 9, 20269 phút đọc1,420 lượt xem
nodejssecuritymagic-bytesmime-typevalidation

Chỉ dựa vào phần mở rộng (đuôi tệp như .pdf hay .jpg) hoặc header Content-Type do trình duyệt của người dùng gửi lên là một lỗ hổng bảo mật nghiêm trọng. Kẻ tấn công có thể dễ dàng đổi tên file thực thi độc hại malware.exe thành invoice.pdf để vượt qua các bộ lọc thông thường. Để xác thực tệp tin thực sự an toàn và chuẩn xác, chúng ta bắt buộc phải kiểm tra Magic Bytes (chữ ký số tệp tin).

Magic Bytes Là Gì?

Magic Bytes (file signatures) là một chuỗi các byte nhị phân đặc thù nằm chính xác ở những byte đầu tiên (header) của một tệp tin. Các hệ điều hành và phần mềm giải mã chuyên sâu luôn dựa vào chuỗi byte này thay vì phần mở rộng của file.

Dưới đây là bảng tra cứu Magic Bytes của các định dạng phổ biến:

Định dạng tệpPhần mở rộngMagic Bytes (Hex)Ký tự biểu diễn ASCII
PDF.pdf25 50 44 46%PDF
PNG.png89 50 4E 47.PNG
JPEG.jpgFF D8 FFÿØÿ
ZIP / DOCX.zip/.docx50 4B 03 04PK..
GIF.gif47 49 46 38GIF8
Thử Nghiệm Thực Tế.docx

Tải file mẫu DOCX 1MB chuẩn để phân tích các magic bytes PK của container ZIP trong mã nguồn của bạn.

Tải File Mẫu 1MB DOCX →

Kiểm Tra Magic Bytes Trong Node.js Với Thư Viện file-type

Cài đặt thư viện chuẩn công nghiệp:

Terminal
npm install file-type

Triển khai hàm xác thực định dạng nhị phân phía máy chủ:

TypeScript
import { fileTypeFromBuffer } from 'file-type';

export async function validateActualFileType(
  buffer: Buffer, 
  expectedMime: string
): Promise<boolean> {
  // Đọc và phân tích các byte mở đầu của buffer
  const detected = await fileTypeFromBuffer(buffer);

  if (!detected) {
    console.error('Không nhận diện được cấu trúc nhị phân của tệp.');
    return false;
  }

  console.log(`Định dạng thực tế: ${detected.ext} (${detected.mime})`);
  return detected.mime === expectedMime;
}

Đọc Magic Bytes Trực Tiếp Trên Trình Duyệt (Client-Side)

Bạn có thể đọc 4 đến 16 byte đầu tiên của bất kỳ đối tượng File hoặc Blob nào mà không cần nạp toàn bộ file vào bộ nhớ RAM của trình duyệt:

TypeScript
export async function checkPdfHeaderInBrowser(file: File): Promise<boolean> {
  // Chỉ cắt lấy 4 byte đầu tiên
  const headerBlob = file.slice(0, 4);
  const arrayBuffer = await headerBlob.arrayBuffer();
  const bytes = new Uint8Array(arrayBuffer);

  // Chuỗi %PDF trong bảng mã ASCII tương ứng [0x25, 0x50, 0x44, 0x46]
  return (
    bytes[0] === 0x25 && 
    bytes[1] === 0x50 && 
    bytes[2] === 0x44 && 
    bytes[3] === 0x46
  );
}

Lưu Ý Quan Trọng Về Bảo Mật Hệ Thống

  • Tệp Polyglot (Đa hình thức): Những tệp được cố ý tạo ra để vừa là file ảnh hợp lệ vừa chứa mã script thực thi. Do đó, hãy luôn kết hợp kiểm tra magic bytes với việc chuyển mã (re-encoding) hoặc xử lý trong môi trường sandbox cô lập.
  • Tệp DOCX / XLSX bản chất là ZIP: Các tài liệu Office hiện đại là kho nén OpenXML. Magic bytes của chúng sẽ báo về là application/zip. Bạn nên kiểm tra thêm sự tồn tại của tệp word/document.xml bên trong container để xác định chắc chắn là tài liệu Word.
NDL

Nguyễn Đại Long

Tác Giả

Backend Lead • Chuyên gia Kiến trúc Hệ thống Phân tán & Lưu trữ Đám mây

Hơn 4 năm kinh nghiệm thiết kế các hệ thống xử lý tệp tải lên thông lượng lớn, tối ưu hóa cơ sở dữ liệu và hạ tầng phân tán Cloudflare R2 / AWS S3. Người sáng lập FileDummy và Mạng lưới Hệ sinh thái NDL.

Bài viết này có hữu ích không?

Bấm Thích để ủng hộ tác giả và giúp bài viết lan tỏa tới cộng đồng lập trình viên.

Thảo Luận Kỹ Thuật & Đóng Góp Ý Kiến (0)

Chia sẻ kết quả benchmark, phản hồi các trường hợp biên hoặc đặt câu hỏi chuyên môn.

0/3000

Chưa có bình luận nào. Hãy là lập trình viên đầu tiên bắt đầu cuộc thảo luận!

Câu Hỏi Thường Gặp (FAQ)

Tại sao chỉ kiểm tra phần mở rộng (extension) là không đủ an toàn?▾

Kẻ tấn công có thể dễ dàng đổi tên file mã độc từ script_nguy_hiem.php thành tai_lieu.pdf. Máy chủ sẽ chấp nhận tải lên nếu chỉ kiểm tra đuôi file. Khi được phân phát hoặc thực thi với MIME type sai, nó sẽ dẫn đến lỗ hổng thực thi mã từ xa (RCE) đặc biệt nguy hiểm.

Magic bytes (chữ ký số tệp tin) là gì?▾

Magic bytes là chuỗi byte đặc thù nằm tại vị trí đầu tiên của tệp tin dùng để định danh định dạng thực tế. Ví dụ: mọi file PDF luôn bắt đầu bằng %PDF (mã hex 25 50 44 46), và ảnh PNG luôn bắt đầu bằng chuỗi hex 89 50 4E 47 0D 0A 1A 0A dù bạn có đổi tên file thành bất kỳ đuôi nào.

Thư viện nào tốt nhất để kiểm tra magic bytes trong Node.js?▾

Gói thư viện 'file-type' trên npm hiện là tiêu chuẩn công nghiệp. Thư viện này phân tích bộ đệm nhị phân Buffer và trả về MIME type cùng extension chuẩn xác. Phía trình duyệt, bạn có thể đọc 8–16 byte đầu tiên qua FileReader và kiểm tra mảng Uint8Array trực tiếp.

Bài Viết Liên Quan