In django version 3.2.12, I try to download an image for which I have an URL and store it inside an ImageField. It looks like this:
def load_image_from_url(self):
image_file = NamedTemporaryFile(delete=True, dir='project/media')
with urlopen(self.extra_large_url) as uo:
assert uo.status == 200
image_file.write(uo.read())
image_file.flush()
image = File(image_file)
self.image.save(image.name, image)
When I create the NamedTemporaryFile, the path generated is an absolute path.
In django.core.files.utils, it get blocked in this condition:
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
)
With a dir argument set for the NamedTemporaryFile, the issue remains even if the folder is a subdirectory of the project.
Is there a better solution than doing this:
self.image.save(os.path.basename(image.name), image)