Giải nén Request trong ASP.NET Core
Bởi David Acker
Middleware (phần mềm trung gian) giải nén request:
- Cho phép các API endpoint chấp nhận request có nội dung được nén.
- Sử dụng header HTTP
Content-Encodingđể tự động nhận diện và giải nén các request có nội dung được nén. - Loại bỏ nhu cầu viết code để xử lý các request được nén.
Khi giá trị header Content-Encoding trong một request khớp với một trong các decompression provider (nhà cung cấp giải nén) có sẵn, middleware:
- Sử dụng provider phù hợp để bọc
HttpRequest.Bodytrong một decompression stream phù hợp. - Xóa header
Content-Encoding, chỉ ra rằng request body không còn được nén.
Các request không bao gồm header Content-Encoding sẽ bị middleware giải nén request bỏ qua.
Quá trình giải nén:
- Xảy ra khi body của request được đọc. Nghĩa là, giải nén xảy ra tại endpoint khi model binding (ràng buộc model). Request body không được giải nén sớm.
- Khi cố gắng đọc request body đã giải nén với dữ liệu nén không hợp lệ cho
Content-Encodingđược chỉ định, một ngoại lệ được ném ra. Brotli có thể némSystem.InvalidOperationException: Decoder ran into invalid data. Deflate và GZip có thể némSystem.IO.InvalidDataException: The archive entry was compressed using an unsupported compression method.
Nếu middleware gặp request có nội dung được nén nhưng không thể giải nén, request được chuyển đến delegate tiếp theo trong pipeline. Ví dụ, một request có giá trị header Content-Encoding không được hỗ trợ hoặc nhiều giá trị header Content-Encoding được chuyển đến delegate tiếp theo trong pipeline.
Cấu hình
Code sau sử dụng AddRequestDecompression(IServiceCollection) và UseRequestDecompression để bật giải nén request cho các loại Content-Encoding mặc định:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRequestDecompression();
var app = builder.Build();
app.UseRequestDecompression();
app.MapPost("/", (HttpRequest request) => Results.Stream(request.Body));
app.Run();Các decompression provider mặc định
Các giá trị header Content-Encoding mà middleware giải nén request hỗ trợ theo mặc định được liệt kê trong bảng sau:
Giá trị header Content-Encoding | Mô tả |
|---|---|
br | Định dạng dữ liệu nén Brotli |
deflate | Định dạng dữ liệu nén DEFLATE |
gzip | Định dạng file Gzip |
Các decompression provider tùy chỉnh
Hỗ trợ cho các encoding tùy chỉnh có thể được thêm bằng cách tạo các class decompression provider tùy chỉnh cài đặt IDecompressionProvider:
public class CustomDecompressionProvider : IDecompressionProvider
{
public Stream GetDecompressionStream(Stream stream)
{
// Perform custom decompression logic here
return stream;
}
}Các decompression provider tùy chỉnh được đăng ký với RequestDecompressionOptions cùng với các giá trị header Content-Encoding tương ứng:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRequestDecompression(options =>
{
options.DecompressionProviders.Add("custom", new CustomDecompressionProvider());
});
var app = builder.Build();
app.UseRequestDecompression();
app.MapPost("/", (HttpRequest request) => Results.Stream(request.Body));
app.Run();Giới hạn kích thước request
Để bảo vệ chống lại zip bombs hoặc decompression bombs:
- Kích thước tối đa của request body đã giải nén bị giới hạn bởi giới hạn kích thước request body được áp dụng bởi endpoint hoặc server.
- Nếu số bytes được đọc từ stream request body đã giải nén vượt quá giới hạn, một
InvalidOperationExceptionđược ném ra để ngăn chặn đọc thêm bytes từ stream.
Theo thứ tự ưu tiên, kích thước request tối đa cho một endpoint được đặt bởi:
IRequestSizeLimitMetadata.MaxRequestBodySize, chẳng hạn nhưRequestSizeLimitAttributehoặcDisableRequestSizeLimitAttributecho các MVC endpoint.- Giới hạn kích thước server toàn cục
IHttpMaxRequestBodySizeFeature.MaxRequestBodySize.MaxRequestBodySizecó thể được ghi đè theo từng request vớiIHttpMaxRequestBodySizeFeature.MaxRequestBodySize, nhưng mặc định theo giới hạn được cấu hình cho cài đặt web server.
| Cài đặt web server | Cấu hình MaxRequestBodySize |
|---|---|
| HTTP.sys | HttpSysOptions.MaxRequestBodySize |
| IIS | IISServerOptions.MaxRequestBodySize |
| Kestrel | KestrelServerLimits.MaxRequestBodySize |
Vô hiệu hóa giới hạn kích thước request body đặt ra rủi ro bảo mật liên quan đến việc tiêu thụ tài nguyên không kiểm soát, đặc biệt nếu request body đang được buffer. Đảm bảo rằng các biện pháp bảo vệ được thiết lập để giảm thiểu rủi ro của các cuộc tấn công từ chối dịch vụ (DoS).