diff options
| author | Tim Graham <timograham@gmail.com> | 2014-08-08 10:20:08 -0400 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2014-08-20 14:39:40 -0400 |
| commit | 0d8d30b7ddfe83ab03120f4560c7aa153f4d0ed1 (patch) | |
| tree | 36523aca0c14222c8b30241e2e0a8fe3a8af511c /docs | |
| parent | 28e765810df46a3f28ff4785491e9973593382fd (diff) | |
Fixed #23157 -- Removed O(n) algorithm when uploading duplicate file names.
This is a security fix. Disclosure following shortly.
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/howto/custom-file-storage.txt | 13 | ||||
| -rw-r--r-- | docs/ref/files/storage.txt | 12 | ||||
| -rw-r--r-- | docs/releases/1.4.14.txt | 20 | ||||
| -rw-r--r-- | docs/releases/1.5.9.txt | 20 | ||||
| -rw-r--r-- | docs/releases/1.6.6.txt | 20 | ||||
| -rw-r--r-- | docs/releases/1.7.txt | 7 |
6 files changed, 90 insertions, 2 deletions
diff --git a/docs/howto/custom-file-storage.txt b/docs/howto/custom-file-storage.txt index 5109986d45..afa1c9a908 100644 --- a/docs/howto/custom-file-storage.txt +++ b/docs/howto/custom-file-storage.txt @@ -90,5 +90,14 @@ the provided filename into account. The ``name`` argument passed to this method will have already cleaned to a filename valid for the storage system, according to the ``get_valid_name()`` method described above. -The code provided on ``Storage`` simply appends ``"_1"``, ``"_2"``, etc. to the -filename until it finds one that's available in the destination directory. +.. versionchanged:: 1.7 + + If a file with ``name`` already exists, an underscore plus a random 7 + character alphanumeric string is appended to the filename before the + extension. + + Previously, an underscore followed by a number (e.g. ``"_1"``, ``"_2"``, + etc.) was appended to the filename until an avaible name in the destination + directory was found. A malicious user could exploit this deterministic + algorithm to create a denial-of-service attack. This change was also made + in Django 1.6.6, 1.5.9, and 1.4.14. diff --git a/docs/ref/files/storage.txt b/docs/ref/files/storage.txt index 1d2c31972e..3200ec3914 100644 --- a/docs/ref/files/storage.txt +++ b/docs/ref/files/storage.txt @@ -112,6 +112,18 @@ The Storage Class available for new content to be written to on the target storage system. + .. versionchanged:: 1.7 + + If a file with ``name`` already exists, an underscore plus a random 7 + character alphanumeric string is appended to the filename before the + extension. + + Previously, an underscore followed by a number (e.g. ``"_1"``, ``"_2"``, + etc.) was appended to the filename until an avaible name in the + destination directory was found. A malicious user could exploit this + deterministic algorithm to create a denial-of-service attack. This + change was also made in Django 1.6.6, 1.5.9, and 1.4.14. + .. method:: get_valid_name(name) Returns a filename based on the ``name`` parameter that's suitable diff --git a/docs/releases/1.4.14.txt b/docs/releases/1.4.14.txt index 28390c96a4..6c140ee6dc 100644 --- a/docs/releases/1.4.14.txt +++ b/docs/releases/1.4.14.txt @@ -18,3 +18,23 @@ To remedy this, URL reversing now ensures that no URL starts with two slashes (//), replacing the second slash with its URL encoded counterpart (%2F). This approach ensures that semantics stay the same, while making the URL relative to the domain and not to the scheme. + +File upload denial-of-service +============================= + +Before this release, Django's file upload handing in its default configuration +may degrade to producing a huge number of ``os.stat()`` system calls when a +duplicate filename is uploaded. Since ``stat()`` may invoke IO, this may produce +a huge data-dependent slowdown that slowly worsens over time. The net result is +that given enough time, a user with the ability to upload files can cause poor +performance in the upload handler, eventually causing it to become very slow +simply by uploading 0-byte files. At this point, even a slow network connection +and few HTTP requests would be all that is necessary to make a site unavailable. + +We've remedied the issue by changing the algorithm for generating file names +if a file with the uploaded name already exists. +:meth:`Storage.get_available_name() +<django.core.files.storage.Storage.get_available_name>` now appends an +underscore plus a random 7 character alphanumeric string (e.g. ``"_x3a1gho"``), +rather than iterating through an underscore followed by a number (e.g. ``"_1"``, +``"_2"``, etc.). diff --git a/docs/releases/1.5.9.txt b/docs/releases/1.5.9.txt index 12b5b5f806..232cbb0767 100644 --- a/docs/releases/1.5.9.txt +++ b/docs/releases/1.5.9.txt @@ -18,3 +18,23 @@ To remedy this, URL reversing now ensures that no URL starts with two slashes (//), replacing the second slash with its URL encoded counterpart (%2F). This approach ensures that semantics stay the same, while making the URL relative to the domain and not to the scheme. + +File upload denial-of-service +============================= + +Before this release, Django's file upload handing in its default configuration +may degrade to producing a huge number of ``os.stat()`` system calls when a +duplicate filename is uploaded. Since ``stat()`` may invoke IO, this may produce +a huge data-dependent slowdown that slowly worsens over time. The net result is +that given enough time, a user with the ability to upload files can cause poor +performance in the upload handler, eventually causing it to become very slow +simply by uploading 0-byte files. At this point, even a slow network connection +and few HTTP requests would be all that is necessary to make a site unavailable. + +We've remedied the issue by changing the algorithm for generating file names +if a file with the uploaded name already exists. +:meth:`Storage.get_available_name() +<django.core.files.storage.Storage.get_available_name>` now appends an +underscore plus a random 7 character alphanumeric string (e.g. ``"_x3a1gho"``), +rather than iterating through an underscore followed by a number (e.g. ``"_1"``, +``"_2"``, etc.). diff --git a/docs/releases/1.6.6.txt b/docs/releases/1.6.6.txt index 43b3adf630..c2ebdb9efb 100644 --- a/docs/releases/1.6.6.txt +++ b/docs/releases/1.6.6.txt @@ -19,6 +19,26 @@ To remedy this, URL reversing now ensures that no URL starts with two slashes approach ensures that semantics stay the same, while making the URL relative to the domain and not to the scheme. +File upload denial-of-service +============================= + +Before this release, Django's file upload handing in its default configuration +may degrade to producing a huge number of ``os.stat()`` system calls when a +duplicate filename is uploaded. Since ``stat()`` may invoke IO, this may produce +a huge data-dependent slowdown that slowly worsens over time. The net result is +that given enough time, a user with the ability to upload files can cause poor +performance in the upload handler, eventually causing it to become very slow +simply by uploading 0-byte files. At this point, even a slow network connection +and few HTTP requests would be all that is necessary to make a site unavailable. + +We've remedied the issue by changing the algorithm for generating file names +if a file with the uploaded name already exists. +:meth:`Storage.get_available_name() +<django.core.files.storage.Storage.get_available_name>` now appends an +underscore plus a random 7 character alphanumeric string (e.g. ``"_x3a1gho"``), +rather than iterating through an underscore followed by a number (e.g. ``"_1"``, +``"_2"``, etc.). + Bugfixes ======== diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index 7a88cf3878..db4829a1c9 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -588,6 +588,13 @@ File Uploads the client. Partially uploaded files are also closed as long as they are named ``file`` in the upload handler. +* :meth:`Storage.get_available_name() + <django.core.files.storage.Storage.get_available_name>` now appends an + underscore plus a random 7 character alphanumeric string (e.g. + ``"_x3a1gho"``), rather than iterating through an underscore followed by a + number (e.g. ``"_1"``, ``"_2"``, etc.) to prevent a denial-of-service attack. + This change was also made in the 1.6.6, 1.5.9, and 1.4.14 security releases. + Forms ^^^^^ |
