Tổng quan bảo mật
TCPDF-Next được xây trên triết lý thiết kế bảo mật ưu tiên. Mọi thành phần, từ nguyên thủy mật mã đến phân tích HTML, được thiết kế để loại bỏ toàn bộ loại lỗ hổng thay vì vá chúng sau khi phát hiện.
Triết lý thiết kế bảo mật ưu tiên
Bảo mật trong TCPDF-Next không phải tính năng gắn thêm lên codebase cũ. Nó là ràng buộc kiến trúc ảnh hưởng mọi quyết định thiết kế từ ngày đầu:
- Từ chối mặc định — Tải tài nguyên bên ngoài, yêu cầu mạng và truy cập file bị chặn trừ khi cho phép rõ ràng.
- Thất bại kín — Khi kiểm tra bảo mật không thể thực hiện (vd: OCSP responder không khả dụng), thao tác thất bại thay vì tiếp tục không an toàn.
- Phòng thủ nhiều lớp — Nhiều lớp bảo vệ độc lập đảm bảo một bypass đơn lẻ không xâm phạm hệ thống.
- Bề mặt tấn công tối thiểu — Không dependency runtime Composer. Mọi thao tác mật mã dùng extension OpenSSL và Sodium tích hợp PHP.
Mã hóa AES-256 (không thuật toán cũ)
TCPDF-Next chỉ implement mã hóa AES-256 như định nghĩa trong PDF 2.0 (ISO 32000-2, Revision 6). Mọi thuật toán cũ và không an toàn bị từ chối vĩnh viễn:
| Thuật toán | Trạng thái | Lý do |
|---|---|---|
| AES-256-CBC | Được hỗ trợ | Chuẩn PDF 2.0, không có tấn công thực tế đã biết |
| RC4 (40-bit / 128-bit) | Cấm | Stream cipher với bias đã biết và tấn công thực tế |
| AES-128 | Cấm | Không đủ margin cho bảo mật dài hạn |
| DES / 3DES | Không implement | Lỗ hổng kích thước block và độ dài key |
| MD5 (cho key derivation) | Cấm | Tấn công collision từ 2004 |
use YeeeFang\TcpdfNext\Encryption\EncryptionAlgorithm;
use YeeeFang\TcpdfNext\Encryption\Permissions;
$pdf->setEncryption()
->setAlgorithm(EncryptionAlgorithm::AES256)
->setUserPassword('reader-password')
->setOwnerPassword('admin-password')
->setPermissions(
Permissions::PRINT_HIGH_QUALITY
| Permissions::COPY
| Permissions::ACCESSIBILITY
)
->apply();Chữ ký số PAdES (B-B đến B-LTA)
TCPDF-Next implement đầy đủ PAdES Baseline Profile (ETSI EN 319 142-1) cho chữ ký số với mức long-term validity tăng dần:
| Cấp | Mô tả | Thời gian validation |
|---|---|---|
| PAdES B-B | Chữ ký CMS cơ bản với signing certificate | Hiệu lực certificate (~1-3 năm) |
| PAdES B-T | + Timestamp RFC 3161 từ TSA đáng tin cậy | Hiệu lực certificate TSA (~10-15 năm) |
| PAdES B-LT | + Document Security Store với dữ liệu OCSP/CRL | Thời gian bảo mật thuật toán (~15-30 năm) |
| PAdES B-LTA | + Archive timestamp cho re-validation vô thời hạn | Vô thời hạn (với re-timestamp định kỳ) |
Xem chi tiết implement tại Chữ ký PAdES B-LTA.
Bảo vệ SSRF với DNS Pinning
Mọi yêu cầu mạng bên ngoài (lấy ảnh, giao tiếp TSA, tra cứu OCSP) đi qua HTTP client được gia cố với bảo vệ SSRF tích hợp:
- DNS pinning — Địa chỉ IP đã resolve được xác thực trước khi kết nối. Dải mạng riêng (
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16), loopback (127.0.0.0/8), và link-local (169.254.0.0/16) bị chặn. - Giới hạn protocol — Mặc định chỉ cho phép
https://.http://thuần bị từ chối trừ khi cho phép rõ ràng. - Allowlist domain — Allowlist cấu hình được cho domain bên ngoài được phép.
- Theo redirect — Giới hạn tối đa cấu hình được (mặc định: 3) với re-validation ở mỗi bước.
Ngăn Path Traversal
Mọi thao tác đường dẫn file được làm sạch để ngăn tấn công directory traversal:
- Tên file nhúng bị loại bỏ dấu phân cách đường dẫn và chuỗi
... - Đường dẫn file font được resolve sang đường dẫn canonical tuyệt đối và xác thực theo thư mục được phép.
- Đường dẫn ảnh tham chiếu trong HTML bị giới hạn ở thư mục cấu hình rõ ràng qua
ResourcePolicy.
#[\SensitiveParameter] cho mật khẩu và key
Mọi tham số method nhận mật khẩu, passphrase, private key hoặc PIN được gán attribute #[\SensitiveParameter] PHP 8.2. Điều này đảm bảo giá trị nhạy cảm tự động được ẩn khỏi stack trace, log lỗi và exception message.
#[\NoDiscard] cho giá trị trả về quan trọng
Method trả về kết quả quan trọng bảo mật (kết quả validation, xác minh chữ ký) được gán #[\NoDiscard] để ngăn caller bỏ qua giá trị trả về. Bỏ qua tạo cảnh báo compiler.
PHPStan Level 10 (không lỗi, không baseline)
Toàn bộ codebase pass PHPStan phân tích tĩnh ở mức nghiêm ngặt nhất (Level 10) với không lỗi và không file baseline.
100% declare(strict_types=1)
Mọi file PHP trong TCPDF-Next bắt đầu bằng declare(strict_types=1). Không có ngoại lệ.
Cân nhắc tuân thủ OWASP
TCPDF-Next giải quyết các loại OWASP sau liên quan đến thư viện tạo PDF:
| Loại OWASP | Giải pháp |
|---|---|
| A01 -- Broken Access Control | Permission PDF chi tiết, mã hóa dựa trên certificate |
| A02 -- Cryptographic Failures | Chỉ AES-256, không thuật toán yếu, so sánh constant-time |
| A03 -- Injection | Làm sạch HTML, ngăn path traversal, không eval() |
| A05 -- Security Misconfiguration | Mặc định an toàn, policy tài nguyên từ chối mặc định |
| A06 -- Vulnerable Components | Không dependency runtime, crypto tích hợp qua OpenSSL/Sodium |
| A07 -- Authentication Failures | #[\SensitiveParameter], xóa bộ nhớ an toàn qua sodium_memzero() |
| A10 -- SSRF | DNS pinning, chặn mạng riêng, allowlist domain |
Tài liệu bảo mật
Khám phá tài liệu bảo mật đầy đủ:
- Thực hành bảo mật tốt nhất — Validation input, quản lý certificate, bảo mật triển khai