diff options
Diffstat (limited to 'django/core/files/utils.py')
-rw-r--r-- | django/core/files/utils.py | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/django/core/files/utils.py b/django/core/files/utils.py index f83cb1a3cf..f28cea1077 100644 --- a/django/core/files/utils.py +++ b/django/core/files/utils.py @@ -1,16 +1,26 @@ import os +import pathlib from django.core.exceptions import SuspiciousFileOperation -def validate_file_name(name): - if name != os.path.basename(name): - raise SuspiciousFileOperation("File name '%s' includes path elements" % name) - +def validate_file_name(name, allow_relative_path=False): # Remove potentially dangerous names - if name in {'', '.', '..'}: + if os.path.basename(name) in {'', '.', '..'}: raise SuspiciousFileOperation("Could not derive file name from '%s'" % name) + if allow_relative_path: + # Use PurePosixPath() because this branch is checked only in + # FileField.generate_filename() where all file paths are expected to be + # Unix style (with forward slashes). + path = pathlib.PurePosixPath(name) + if path.is_absolute() or '..' in path.parts: + raise SuspiciousFileOperation( + "Detected path traversal attempt in '%s'" % name + ) + elif name != os.path.basename(name): + raise SuspiciousFileOperation("File name '%s' includes path elements" % name) + return name |