我有這樣定義的模型的一部分:的Django的ImageField /自定義的FileField功能upload_to和安全
logo_image = models.ImageField(upload_to=lambda i, fn: "logo_%s"%(fn), height_field="logo_image_height", width_field="logo_image_width")
,有一個關於upload_to功能問題。
根據django's documentation for FileField.upload_to,第二參數filename
是「最初給予該文件的文件名」。
現在,瞭解HTTP,文件上傳等,最終用戶的客戶端可以很容易僞造文件名。特別是,最終客戶端不能上傳一個名爲「/ etc/passwd」的文件,例如,如果我使用我的天真代碼(lambda i, fn: "logo_%s"%(fn)
),是不是將結果文件上傳到/etc/passwd
?我需要跳過filename
參數嗎?
#using django's 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'
感謝您的任何建議/答案/澄清。
編輯
的重要的是尋找方法在有in files.py, near line 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
()所看到here:
226 if callable(upload_to):
227 self.generate_filename = upload_to
然後,在save() method:
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)
將返回的文件名傳遞給存儲類,最終在_os.py util模塊safe_join中調用django替換函數。
這個功能似乎減輕了我的恐懼:
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 """
所以...你真的不需要那麼這個問題的回答? – Powerlord 2009-10-05 19:29:02
對不起:)不出現。只是在這一點上尋找驗證(有人做另一個看看)。 – 2009-10-05 20:17:04
如果您「回答自己的問題」,可能會更清楚,然後將其標記爲已回答,以便它不會留在未答覆的列表中。 – 2009-10-20 15:06:30