Я пытался разработать 'лучшие практики' способ управлять загрузками файла с Turbogears 2 и к настоящему времени действительно не нашел примеров. Я выяснил способ на самом деле загрузить файл, но я не уверен как надежный он нас.
Кроме того, каков был бы хороший способ получить загруженное имя файлов?
file = request.POST['file']
permanent_file = open(os.path.join(asset_dirname,
file.filename.lstrip(os.sep)), 'w')
shutil.copyfileobj(file.file, permanent_file)
file.file.close()
this_file = self.request.params["file"].filename
permanent_file.close()
Так принятие, которое я понимаю правильно, что-то вроде этого избежало бы базовой проблемы 'именования'? идентификатор = UUID.
file = request.POST['file']
permanent_file = open(os.path.join(asset_dirname,
id.lstrip(os.sep)), 'w')
shutil.copyfileobj(file.file, permanent_file)
file.file.close()
this_file = file.filename
permanent_file.close()
@mhawke - вы правы, вы должны справиться с этим - зависит от того, что вы делаете с файлом, если столкновение имен не имеет значения, например, вам нужна только последняя версия некоторых данных, тогда, вероятно, нет проблем, или если имя файла не имеет значения, важно только его содержимое, но это все равно плохая практика.
Вы можете использовать именованный временный файл в каталоге tmp, а затем переместить файл после проверки в его окончательное местоположение. Или вы можете проверить, что имя файла еще не существует, например так:
file.name = slugify(myfile.filename)
name, ext = os.path.splitext(file.name)
while os.path.exists(os.path.join(permanent_store, file.name)):
name += '_'
file.name = name + ext
raw_file = os.path.join(permanent_store, file.name)
Для приведения имени файла в порядок используется метод slugify...
Я мало знаю о Turbogears и может ли он предоставить что-нибудь, чтобы избежать следующего, но мне кажется, что этот код чреват опасностью. Злоумышленник может перезаписать (или создать) любой файл, к которому процесс Python Turbogears имеет доступ для записи.
Что если имя_категории
равно / tmp
, то содержимое имя_файла
будет ../../../../ ../../../etc/passwd
и содержимое файла root :: 0: 0: root: / root: / bin / bash
? В среде UNIX этот код (ожидающие разрешения) откроет файл / tmp /../../../../../../../ etc / passwd
в режиме усечения. а затем скопируйте в него содержимое загруженного файла - эффективно перезаписав файл паролей вашей системы и указав пользователя root без пароля. Предположительно, есть неприятные вещи, которые можно сделать и с машиной Windows.
Хорошо, это крайний пример, который требует, чтобы python работал как root
(никто этого не делает, не так ли?). Даже если python работает как пользователь с низким уровнем привилегий, ранее загруженные файлы могут быть перезаписаны по желанию.
Подводя итог, не доверяйте вводу пользователя, в данном случае указанному пользователем имени файла, который доступен в file.filename
.
Разве турбоагрегаты не являются просто пилонами с дополнительными принадлежностями? Здесь вы можете найти справку:
http://wiki.pylonshq.com/display/pylonsdocs/Form+Handling#file-uploads
Тем не менее, он все еще содержит потенциальную уязвимость безопасности, о которой упоминал Махоук:
os.path.join(permanent_store, myfile.filename.lstrip(os.sep))
На самом деле то же самое, что и выше, если имя файла каким-то образом было ../../../../../ etc / passwd
, тогда вы могли бы заменить этот файл ...
Таким образом, вы могли бы просто получить фактическое имя файла выглядит так:
os.path.join(permanent_store, myfile.filename.split(os.sep).pop())
В Werkzeug есть очень хорошая вспомогательная функция для защиты имен файлов под названием secure_filename. Я думаю, вы можете взять ее на вооружение и использовать.