#21231: Limiting the number of variables and files that a POST request can 
contain
-------------------------------+--------------------
     Reporter:  epandurski@…   |      Owner:  nobody
         Type:  New feature    |     Status:  new
    Component:  HTTP handling  |    Version:  master
     Severity:  Normal         |   Keywords:
 Triage Stage:  Unreviewed     |  Has patch:  0
Easy pickings:  0              |      UI/UX:  0
-------------------------------+--------------------
 == The Problem ==

 When deploying a django application one should be able to asses what
 will be *the absolute maximum* of memory consumed by each serving
 process/thread. Failing to make this assessment correctly may leave the
 application open to denial-of-service attacks. For example, when
 deploying with apache, an excessive number of threads should be
 available in order protect yourself from slowloris-type attacks. Also,
 in order to limit the maximum memory and CPU usage under attack
 "LimitRequestBody" should be set to a reasonably small value (1MB for
 example). So, here are the naive math: //"100 parallel requests"// X
 //"1MB
 per request"// = //"100MB maximum memory consumed"//

 The problem is that the naive math is wrong. A single 1MB POST request
 may require *much* more that 1MB to process. 1MB of
 "application/x-www-form-urlencoded" type may contain 200,000 short
 name-value pairs, which when fetched into the interpreter consume tens of
 megabytes (depending on the platform, probably 10-50MB). So the
 correct math would be: //"100 parallel requests"// X //"50MB per
 request"// =
 //"5000MB maximum memory consumed"//. Probably too much for many systems.

 As far as I know, django does not offer an easy way to protect against
 such edge cases (lots of simultaneous malicious POST request that consume
 unexpected amounts of memory).

 == The proposal ==

 Introduce two new settings, limiting the maximum number of entities in
 a POST request:

 **FORM_DATA_URLENCODED_MAX_VARS**: the maximum number of name-value
 pairs in the case of "application/x-www-form-urlencoded". (no limit by
 default)

 **FORM_DATA_MULTIPART_MAX_PARTS**: the maximum number of parts in the
 case of "multipart/form-data". (no limit by default)

 In case those limits are exceeded, the request must be discarded
 without being fetched/parsed into memory. (In our example, it would
 consume only 1MB instead of 50.)

-- 
Ticket URL: <https://code.djangoproject.com/ticket/21231>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/063.84f9fd6aa44c0d7023494c65ef3a571e%40djangoproject.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to