Django ImageField / FileField user upload_to function and security

I have a part of a model defined as follows:

logo_image = models.ImageField(upload_to=lambda i, fn: "logo_%s"%(fn), height_field="logo_image_height", width_field="logo_image_width")

and the question arose about the upload_to function.

According to the django documentation for FileField.upload_to , the second parameter filenameis "The name of the file that was originally provided to the file."

Now knowing about HTTP, file uploads, etc., the end-user client can easily fake the file name. In particular, can the end client not upload a file named "/ etc / passwd", for example, and then, if I use my naive code ( lambda i, fn: "logo_%s"%(fn)), will the downloaded file not be uploaded to /etc/passwd? Do I need to avoid the parameter filename?

#using django example of using full paths in settings module,
#MEDIA_ROOT="/tmp/media"
>>> os.path.join("/tmp/media/", "apple.jpg")
'/tmp/media/apple.jpg'
>>> os.path.join("/tmp/media/", "/etc/passwd")
'/etc/passwd'

Thanks for any suggestions / answers / clarifications.

Edit

files.py, 272:

272         def get_directory_name(self):
273             return os.path.normpath(force_unicode(datetime.datetime.now().strftime(smart_str(self.upload_to))))
274     
275         def get_filename(self, filename):
276             return os.path.normpath(self.storage.get_valid_name(os.path.basename(filename)))
277     
278         def generate_filename(self, instance, filename):
279             return os.path.join(self.get_directory_name(), self.get_filename(filename))

upload_to generate_filename(), :

226             if callable(upload_to):
227                 self.generate_filename = upload_to

save():

89      def save(self, name, content, save=True):
90          name = self.field.generate_filename(self.instance, name)
91          self.name = self.storage.save(name, content)

, django _os.py util safe_join.

, , :

24    def safe_join(base, *paths):
25      """
26      Joins one or more path components to the base path component intelligently.
27      Returns a normalized, absolute version of the final path.
28  
29      The final path must be located inside of the base path component (otherwise
30      a ValueError is raised).
31      """
+3
1

, . , os.path.join() , , ( Python, os.path). , , os.path.join(), , .

, : get_filename() os.path.basename(), . upload_to = .

, ImageField() upload_to, , os.path.basename(). -, . os.path.basename() upload_to. - ?

. http://hustoknow.blogspot.com/2010/08/try-me-out.html

+1

Source: https://habr.com/ru/post/1719319/


All Articles