DOTNET Contents

Request Size Limits (Abuse Prevention)

Request size limits prevent memory exhaustion and slow-body attacks. Learn how to enforce limits at Kestrel, reverse proxy, and endpoint level without breaking legitimate uploads.

On this page

Large Requests Are a DoS Vector

If you do not enforce request size limits: - attackers can send huge bodies - memory usage spikes - request threads block - connection pools exhaust - application becomes unavailable Production rule: Every service must define explicit maximum request sizes.

Real Production Incident

Symptoms: - API memory usage grows rapidly. - GC pressure spikes. - CPU increases. - No obvious spike in request count. Root cause: - Client (malicious or buggy) sent very large JSON payloads. - No request size limit enforced. - Model binding attempted to buffer entire body. - Server resources exhausted. This was not high RPS. It was large body size abuse.

Symptom → Cause → Diagnosis → Fix

Symptom: - high memory usage - slow requests - OOM crashes - low request rate but heavy resource consumption Cause: - no MaxRequestBodySize - large file uploads without constraints - buffering entire body into memory - missing reverse proxy limits Diagnosis: - inspect request sizes in logs (if captured safely). - monitor memory allocation spikes. - review Kestrel and proxy config. - reproduce with large payload test. Fix: - set explicit request body size limits. - enforce per-endpoint limits (especially file uploads). - configure reverse proxy limits. - stream large uploads instead of buffering fully.

Anti-Pattern: Unlimited Body Size

If you rely on defaults: - body size may be too large. - reverse proxy may allow large payloads. - app may buffer entire request. This becomes trivial DoS. Production rule: Never leave body size unlimited in public endpoints.

Correct Pattern: Layered Size Limits

Enforce at multiple layers: 1) Reverse proxy (e.g., Nginx, ingress controller) 2) Kestrel server configuration 3) Endpoint-specific overrides Conceptual Kestrel configuration:
builder.WebHost.ConfigureKestrel(options =>
{
    options.Limits.MaxRequestBodySize = 10 * 1024 * 1024; // 10 MB
});
For specific endpoint:
[RequestSizeLimit(5 * 1024 * 1024)]
Production rule: File upload endpoints need explicit, intentional limits.

Streaming vs Buffering

Buffering: - entire request loaded into memory - simpler programming model - dangerous for large uploads Streaming: - process in chunks - lower memory footprint - more complex code For large files: - stream to disk or storage - validate size progressively - avoid loading entire file into memory Production rule: Large payloads must be streamed, not buffered.

Content-Type Enforcement

Attackers may: - send large body with unexpected content type - attempt to bypass parsing logic Enforce: - expected Content-Type - reject unknown or unexpected types early Production rule: Fail fast before expensive parsing.

Slow Body (Slowloris Variant)

Attackers can: - send body very slowly - keep connections open - exhaust connection pool Mitigations: - request body timeout - minimum data rate settings - connection limits Production rule: Timeouts matter as much as size limits.

Security Notes

- Do not log full request bodies (especially large ones). - Be careful with file uploads: scan and validate. - Combine size limits with rate limiting. Defense in depth: - proxy limits - app-level limits - streaming - timeouts

Operational Notes

Monitoring: - track average and max request size. - alert on sudden spikes in request body size. - monitor memory and GC pressure. Rollout: - tightening limits may break legitimate clients. - communicate size constraints in API docs. - canary new limits. Rollback: - if new limit blocks critical flows, adjust quickly. - do not remove limits entirely; tune them. Governance: - define standard limits per service type. - review large upload endpoints separately.

Checklist

- Reverse proxy enforces request size limit. - Kestrel MaxRequestBodySize configured. - File upload endpoints have explicit size limits. - Large payloads streamed instead of buffered. - Content-Type validated early. - Request timeouts configured to prevent slow-body attacks. - Request size metrics monitored. - Size limit changes are canaried and rollbackable.