|
1 | 1 | import os |
| 2 | +import pathlib |
2 | 3 | from datetime import datetime |
3 | 4 | from urllib.parse import urljoin |
4 | 5 |
|
5 | 6 | from django.conf import settings |
6 | 7 | from django.core.exceptions import SuspiciousFileOperation |
7 | 8 | from django.core.files import File, locks |
8 | 9 | from django.core.files.move import file_move_safe |
| 10 | +from django.core.files.utils import validate_file_name |
9 | 11 | from django.core.signals import setting_changed |
10 | 12 | from django.utils import timezone |
11 | 13 | from django.utils._os import safe_join |
@@ -74,6 +76,9 @@ def get_available_name(self, name, max_length=None): |
74 | 76 | available for new content to be written to. |
75 | 77 | """ |
76 | 78 | dir_name, file_name = os.path.split(name) |
| 79 | + if '..' in pathlib.PurePath(dir_name).parts: |
| 80 | + raise SuspiciousFileOperation("Detected path traversal attempt in '%s'" % dir_name) |
| 81 | + validate_file_name(file_name) |
77 | 82 | file_root, file_ext = os.path.splitext(file_name) |
78 | 83 | # If the filename already exists, generate an alternative filename |
79 | 84 | # until it doesn't exist. |
@@ -105,6 +110,8 @@ def generate_filename(self, filename): |
105 | 110 | """ |
106 | 111 | # `filename` may include a path as returned by FileField.upload_to. |
107 | 112 | dirname, filename = os.path.split(filename) |
| 113 | + if '..' in pathlib.PurePath(dirname).parts: |
| 114 | + raise SuspiciousFileOperation("Detected path traversal attempt in '%s'" % dirname) |
108 | 115 | return os.path.normpath(os.path.join(dirname, self.get_valid_name(filename))) |
109 | 116 |
|
110 | 117 | def path(self, name): |
|
0 commit comments