On 28 August 2010 22:46, Graham Dumpleton <graham.dumple...@gmail.com> wrote: > > > On Aug 28, 7:58 pm, "david b." <db.pub.m...@gmail.com> wrote: >> Ok so I was looking through the code and I saw this (in >> django/core/files/uploadhandler.py) : >> >> FileUploadHandler >> ... >> >> def new_file(self, field_name, file_name, content_type, >> content_length, charset=None): >> """ >> Signal that a new file has been started. >> >> Warning: As with any data from the client, you should not trust >> content_length (and sometimes won't even get it). >> """ >> >> So the content_length we control right? - Maybe I missed something but >> ... I can say I want to upload a small file then upload a file that >> triggers an oom condition / use a lot of memory no ? ... >> >> And then this. >> >> class MemoryFileUploadHandler(FileUploadHandler): >> """ >> File upload handler to stream uploads into memory (used for small >> files). >> """ >> >> def handle_raw_input(self, input_data, META, content_length, >> boundary, encoding=None): >> """ >> Use the content_length to signal whether or not this handler >> should be in use. >> """ >> # Check the content-length header to see if we should >> # If the post is too large, we cannot use the Memory handler. >> if content_length > settings.FILE_UPLOAD_MAX_MEMORY_SIZE: >> self.activated = False >> else: >> self.activated = True >> >> def new_file(self, *args, **kwargs): >> super(MemoryFileUploadHandler, self).new_file(*args, **kwargs) >> if self.activated: >> self.file = StringIO() >> raise StopFutureHandlers() >> >> def receive_data_chunk(self, raw_data, start): >> """ >> Add the data to the StringIO file. >> """ >> if self.activated: >> self.file.write(raw_data) >> else: >> return raw_data >> >> def file_complete(self, file_size): >> """ >> Return a file object if we're activated. >> """ >> if not self.activated: >> return >> >> self.file.seek(0) >> return InMemoryUploadedFile( >> file = self.file, >> field_name = self.field_name, >> name = self.file_name, >> content_type = self.content_type, >> size = file_size, >> >> There is a regression test for this BUT --> in the test suite there >> is # A small file (under the 5M quota) >> which is governed by >> (django/tests/regressiontests/file_uploads/uploadhandler.py) >> >> def receive_data_chunk(self, raw_data, start): >> self.total_upload += len(raw_data) >> if self.total_upload >= self.QUOTA: >> raise StopUpload(connection_reset=True) >> return raw_data >> >> So obviously my proposed attack is to simply say "content length is >> tiny" and "this file is actually HUGE". >> I hope I missed something :) I don't really want this to occur ... > > A decent web server such as Apache (under mod_wsgi) will stop reading > the original content at the content length specified in the request. > Thus not possible to force more than content length down to the > application level. > > Graham
The documentation and code in django suggests that this is not the case. So lets assume we are not using apache but another httpd of some sort - then this problem will be present. http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4 seems to say otherwise from my reading. Also as per the django code comment (in django/core/files/uploadhandler.py): def new_file(self, field_name, file_name, content_type, content_length, charset=None): """ Signal that a new file has been started. Warning: As with any data from the client, you should not trust content_length (and sometimes won't even get it). """ self.field_name = field_name self.file_name = file_name self.content_type = content_type self.content_length = content_length self.charset = charset -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.