|
1 | 1 | import os |
2 | 2 |
|
| 3 | +from django.core.exceptions import SuspiciousFileOperation |
3 | 4 | from django.core.files.base import ContentFile |
4 | | -from django.core.files.storage import Storage |
| 5 | +from django.core.files.storage import FileSystemStorage, Storage |
5 | 6 | from django.db.models import FileField |
6 | 7 | from django.test import SimpleTestCase |
7 | 8 |
|
@@ -36,6 +37,44 @@ def generate_filename(self, filename): |
36 | 37 |
|
37 | 38 |
|
38 | 39 | class GenerateFilenameStorageTests(SimpleTestCase): |
| 40 | + def test_storage_dangerous_paths(self): |
| 41 | + candidates = [ |
| 42 | + ('/tmp/..', '..'), |
| 43 | + ('/tmp/.', '.'), |
| 44 | + ('', ''), |
| 45 | + ] |
| 46 | + s = FileSystemStorage() |
| 47 | + msg = "Could not derive file name from '%s'" |
| 48 | + for file_name, base_name in candidates: |
| 49 | + with self.subTest(file_name=file_name): |
| 50 | + with self.assertRaisesMessage(SuspiciousFileOperation, msg % base_name): |
| 51 | + s.get_available_name(file_name) |
| 52 | + with self.assertRaisesMessage(SuspiciousFileOperation, msg % base_name): |
| 53 | + s.generate_filename(file_name) |
| 54 | + |
| 55 | + def test_storage_dangerous_paths_dir_name(self): |
| 56 | + file_name = '/tmp/../path' |
| 57 | + s = FileSystemStorage() |
| 58 | + msg = "Detected path traversal attempt in '/tmp/..'" |
| 59 | + with self.assertRaisesMessage(SuspiciousFileOperation, msg): |
| 60 | + s.get_available_name(file_name) |
| 61 | + with self.assertRaisesMessage(SuspiciousFileOperation, msg): |
| 62 | + s.generate_filename(file_name) |
| 63 | + |
| 64 | + def test_filefield_dangerous_filename(self): |
| 65 | + candidates = ['..', '.', '', '???', '$.$.$'] |
| 66 | + f = FileField(upload_to='some/folder/') |
| 67 | + msg = "Could not derive file name from '%s'" |
| 68 | + for file_name in candidates: |
| 69 | + with self.subTest(file_name=file_name): |
| 70 | + with self.assertRaisesMessage(SuspiciousFileOperation, msg % file_name): |
| 71 | + f.generate_filename(None, file_name) |
| 72 | + |
| 73 | + def test_filefield_dangerous_filename_dir(self): |
| 74 | + f = FileField(upload_to='some/folder/') |
| 75 | + msg = "File name '/tmp/path' includes path elements" |
| 76 | + with self.assertRaisesMessage(SuspiciousFileOperation, msg): |
| 77 | + f.generate_filename(None, '/tmp/path') |
39 | 78 |
|
40 | 79 | def test_filefield_generate_filename(self): |
41 | 80 | f = FileField(upload_to='some/folder/') |
|
0 commit comments