💡 Ví dụ hoạt động đầy đủ có sẵn trên GitHub:
merge-untrusted-html-uploads-dotnet
Việc hợp nhất an toàn các tài liệu HTML không đáng tin cậy là một quy trình làm việc của GroupDocs.Merger cho .NET, từ chối các tài nguyên bên ngoài mà một tệp tải lên tham chiếu - URL từ xa, đường dẫn UNC và tệp cục bộ - trừ khi bạn cho phép chúng một cách rõ ràng.
Cách Cũ Đầy Khó Khăn
Hãy tưởng tượng cổng thanh toán của bạn hợp nhất tệp tải lên hoá đơn của khách hàng với phiếu giao hàng từ cùng một đơn hàng thành một tài liệu HTML duy nhất để lưu trữ. Hoá đơn là HTML thuần - một liên kết stylesheet, một hình logo, một vài đoạn văn - ngoại trừ bạn không viết nó, mà trình duyệt hoặc công cụ xuất của khách hàng đã tạo. Trước GroupDocs.Merger 26.10, quá trình hợp nhất tải các tài nguyên bên ngoài mà HTML tham chiếu - stylesheet từ xa, hình ảnh từ xa, đường dẫn tệp cục bộ tuyệt đối - và không có tùy chọn nào để ngăn chặn.
Đây là vấn đề ngay khi tệp tải lên không hoàn toàn đáng tin cậy. Một URL stylesheet cũng có thể là một pixel theo dõi. Một src của hình ảnh có thể trỏ tới http://169.254.169.254/latest/meta-data/iam/security-credentials/ - một địa chỉ metadata đám mây - và bước hợp nhất của bạn sẽ yêu cầu nó thay mặt người tải lên. Một đường dẫn file:/// tuyệt đối cũng được đọc, vì vậy một tham chiếu tới tệp tải lên của khách hàng khác có thể kéo tệp đó vào đầu ra hợp nhất.
Chi phí thực sự của việc hợp nhất mù quáng: một công việc hợp nhất lấy bất kỳ thứ gì mà tệp tải lên yêu cầu sẽ biến máy chủ của bạn thành proxy cho SSRF, và một tham chiếu
file:///thành cách để một khách hàng hợp nhất đọc tệp của khách hàng khác.
Có Cách Tốt Hơn
GroupDocs.Merger cho .NET khắc phục vấn đề này theo mặc định. Từ phiên bản 26.10, mọi constructor của LoadOptions đều đặt SkipExternalResources = true, và một Merger được tạo mà không có tùy chọn tải sẽ sử dụng cùng mặc định đó - không có tài nguyên bên ngoài nào được tải trừ khi bạn cho phép.
Yêu cầu trước:
- .NET (bất kỳ một trong bốn framework mục tiêu mà GroupDocs.Merger cho .NET hỗ trợ)
- GroupDocs.Merger cho .NET 26.10 trở lên (lấy giấy phép tạm thời)
- Hai tài liệu HTML để hợp nhất, ít nhất một từ nguồn bạn không hoàn toàn tin tưởng
Cài đặt bằng một lệnh:
dotnet add package GroupDocs.Merger --version 26.10.0
Cách Mới: Hợp Nhất HTML Mà Không Tin Cậy Nó
Đây là cách hợp nhất hai tệp HTML tải lên với các mặc định bảo mật, một trình xử lý ghi lại mọi quyết định, và - trong lần chạy thứ hai - một trình xử lý cung cấp một tài nguyên tin cậy.
Bước 1 - Tạo Load Options cho Định Dạng
LoadOptions không có constructor không tham số và đã được đóng kín kể từ 26.10; mẫu này đặt tên định dạng một cách rõ ràng.
// LoadOptions(FileType.HTML) already denies everything external by default
var audit = new ResourceAudit();
var loadOptions = new LoadOptions(FileType.HTML) { ExternalResourceHandler = audit };
Bước 2 - Hợp Nhất Các Tải Lên và Kiểm Tra Các Quyết Định
// Both uploads follow the options of the Merger they are joined to
using (var merger = new Merger(firstUpload, loadOptions))
{
merger.Join(secondUpload);
merger.Save(outputPath);
}
foreach (string decision in audit.Decisions)
{
Console.WriteLine(decision);
}
Các điểm chính:
SkipExternalResources: ngầm định làtrueở đây, vì vậy mọi URL từ xa, đường dẫn UNC và tham chiếu tệp cục bộ đều bị từ chối, kể cả tệp trong thư mục tải lên của chính nó.- Một
LoadOptionscho mỗi lần hợp nhất: tệp tải lên thứ hai không có tùy chọn riêng - nó kế thừa những gìMergermà nó được hợp nhất vào đã tạo.
Bước 3 - Cho Phép Chính Xác Một Tài Nguyên Được Tin Cậy
// Supply the logo's bytes directly instead of requesting it over the network
var trustedAssets = new Dictionary<string, byte[]>
{
[logoUrl] = File.ReadAllBytes(logoPath)
};
var audit = new ResourceAudit(trustedAssets);
var loadOptions = new LoadOptions(FileType.HTML) { ExternalResourceHandler = audit };
Phương thức OnLoading của trình xử lý đặt args.Skipped = false và args.Data thành các byte đó khi URI yêu cầu khớp, vì vậy tài liệu nhận được logo mà không có GroupDocs.Merger thực hiện bất kỳ yêu cầu nào.
Khi chúng tôi chạy hợp nhất mặc định với các tệp hoá đơn và phiếu giao hàng, tất cả bảy tham chiếu bên ngoài trong cả hai tệp đều bị chặn - stylesheet từ xa, logo từ xa, URL kiểu metadata, hình ảnh trong thư mục cùng cấp, một đường dẫn file:///, một đường dẫn UNC và một URL theo dõi có chuỗi truy vấn. joined.html giữ lại văn bản từ cả hai tải lên; một placeholder được đặt thay cho mỗi hình ảnh bị chặn. Khi trình xử lý logo tin cậy được gắn, logo được supplied và sáu tài nguyên còn lại vẫn blocked.
So Sánh: Trước và Sau
| Trước (không tùy chọn) | Sau (GroupDocs.Merger 26.10) | |
|---|---|---|
| Yêu cầu bên ngoài | Mỗi tham chiếu được tải tự động | Bị từ chối trừ khi được cho phép rõ ràng |
| Đường dẫn tệp cục bộ tuyệt đối | Được tải vào đầu ra | Bị từ chối giống như bất kỳ tham chiếu nào khác |
| Ngoại lệ tin cậy | Không cần - mọi thứ đều được tải | Một tài nguyên qua handler, hoặc một tiền tố trong danh sách trắng |
| Mục danh sách trắng không hợp lệ | Không có danh sách trắng | Bị từ chối với ArgumentException khi khởi tạo |
| Mã cần thiết | Không có cách nào để hạn chế tải | Vài dòng trên LoadOptions |
Sự khác biệt nằm ở những gì có thể làm được, không chỉ ở mức độ tiện lợi: trước 26.10 không có cài đặt nào ngăn việc tải; sau đó, việc từ chối là mặc định và mọi ngoại lệ đều phải được chỉ định rõ ràng.
Điều này có làm hỏng HTML đã phụ thuộc vào việc tải ảnh từ xa không?
Nếu HTML đó vẫn được hợp nhất với LoadOptions mặc định, câu trả lời là có - các hình ảnh sẽ không được tải, và một placeholder sẽ thay thế chúng trong đầu ra. Giải pháp là rõ ràng, không phải là một cách khắc phục tạm thời: liệt kê các nguồn tin cậy trong WhitelistedResources, hoặc gắn một IExternalResourceHandler cung cấp các tài sản cụ thể mà bạn vẫn muốn hiển thị. Dù chọn cách nào, quá trình hợp nhất vẫn tiếp tục; nó chỉ dừng việc lấy bất kỳ thứ gì bạn chưa chỉ định.
Ví Dụ Thực Tế: Hợp Nhất Hóa Đơn và Phiếu Giao Hàng
Một pipeline tài liệu hợp nhất HTML do khách hàng gửi vào bản sao lưu là đúng kịch bản mà dự án mẫu trên trang này mô phỏng: một tệp hoá đơn tải lên và một phiếu giao hàng từ cùng một đơn hàng, được hợp nhất thành một tệp. Không tệp nào trong hai tải lên này được đội ngũ pipeline tự viết, vì vậy không thể giả định chúng an toàn để đọc nguyên văn. Hoá đơn ghi rõ số tiền phải trả và khách hàng, Northwind Traders, và chứa tham chiếu logo, stylesheet theo dõi, URL kiểu metadata đám mây, tham chiếu hình ảnh cùng thư mục, và một đường dẫn file:/// - tổng cộng bảy tham chiếu bên ngoài giữa hai tải lên, không có tham chiếu nào mà pipeline lưu trữ nên lấy thay mặt khách hàng.
Trước khi công việc hợp nhất đi vào hoạt động, nên quyết định, từng loại tài liệu một, liệu có cần bất kỳ ngoại lệ nào không. Kịch bản hoá đơn trong mẫu này chỉ cần một ngoại lệ: logo của công ty, được phục vụ từ một tệp đã có trên đĩa thay vì được lấy từ URL từ xa mà HTML chỉ định. Mọi thứ khác - stylesheet theo dõi, địa chỉ kiểu metadata, tệp cùng thư mục, đường dẫn UNC và file:/// - không có lý do hợp pháp để được lấy, vì vậy mặc định đã là câu trả lời đúng cho chúng.
// Reject a whitelist entry that is not an absolute URI prefix
var loadOptions = new LoadOptions(FileType.HTML)
{
WhitelistedResources = new List<string> { "cdn.example.com" }
};
Việc truyền một tên máy chủ thuần thay vì một tiền tố tuyệt đối như https://cdn.example.com/brand/ sẽ gây lỗi, với thông báo Whitelisted resource 'cdn.example.com' must be an absolute URI without a query, fragment or encoded '/', '\' or '.'. (Parameter 'WhitelistedResources') - trước khi bất kỳ tệp tải lên nào được mở. Bắt lỗi danh sách trắng cấu hình sai ngay khi khởi động có giá trị hơn rất nhiều so với việc bắt lỗi sau khi một tài nguyên âm thầm không tải được trong môi trường sản xuất.
Bạn Có Thể Làm Gì Khác Với GroupDocs.Merger cho .NET?
- Xác thực các mục danh sách trắng sớm: một mục
WhitelistedResourcessai định dạng sẽ thất bại khi khởi tạoMerger, vì vậy các kiểm tra khởi động của triển khai sẽ bắt được trước khi bất kỳ tài liệu nào được xử lý. - Cung cấp tài sản tin cậy từ đĩa:
IExternalResourceHandlercó thể trả lời một yêu cầu bằng các byte bạn đã có, mà không cần truy cập mạng. - Áp dụng một chính sách cho mọi tài liệu được hợp nhất:
LoadOptionsđược đặt một lần trênMerger, và mọi tài liệu sau này được hợp nhất vào sẽ tuân theo cùng quy tắc. - Bao phủ nhiều hơn HTML: xử lý văn bản, HTML/MHTML, bản trình chiếu, bảng tính, SVG và tài liệu EPUB đều tôn trọng cùng các tùy chọn.
Kết Luận
Hợp nhất HTML mà bạn không viết không còn đồng nghĩa với việc tin tưởng mọi thứ bên trong nó. GroupDocs.Merger cho .NET từ chối tài nguyên bên ngoài theo mặc định kể từ phiên bản 26.10, và hai cách để cấp ngoại lệ - một trình xử lý tài sản tin cậy và WhitelistedResources - cho bạn chính xác mức độ truy cập mà pipeline cần, không hơn không kém.
Sẵn sàng thử ngay?
- Thử giấy phép tạm thời miễn phí
- Đọc cách bỏ qua việc tải tài nguyên bên ngoài
- Tìm hiểu khi nào GroupDocs.Merger truy cập mạng
- Duyệt hướng dẫn sử dụng từng bước
- Xem dự án mẫu trên GitHub (merge-untrusted-html-uploads-dotnet)