Open mgax opened 5 days ago
Thank you @mgax, I can reproduce this with your instructions. Do you have thoughts on what we should do about this? I can think of a few options but I have no notion of how desirable they are:
blob:
URLs always?<canvas>
?For now I’ll add this to #7053.
Do you have thoughts on what we should do about this?
I think the issue stems from this if
: https://github.com/wagtail/wagtail/blob/abcb2da37259c16d1efd16d7233794f00bb29680/wagtail/images/static_src/wagtailimages/js/vendor/jquery.fileupload-image.js#L202-L203
When there is a thumbnail in the EXIF, the thumbnail
variable contains a value in the form data:image/jpeg,...
, which is then injected into the DOM. But that's vendorized code, from jQuery-File-Upload, which is not maintained any more. And data.exif
comes from load-image.min.js, which was likely copied from JavaScript-Load-Image, which hasn't had an update in 3 years (and our version is from 10 years ago when it was first added to the repository).
I think we should replace it with a modern, maintained alternative. And in the mean time, we could convert that thumbnail
value on the fly, from a data:
URL to a blob:
URL. ChatGPT helped me write this little monster:
--- a/wagtail/images/static_src/wagtailimages/js/vendor/jquery.fileupload-image.js
+++ b/wagtail/images/static_src/wagtailimages/js/vendor/jquery.fileupload-image.js
@@ -200,6 +200,8 @@
}
if (options.thumbnail) {
thumbnail = data.exif.get('Thumbnail');
+ const [type, encodedData] = thumbnail.split(":")[1].split(",");
+ thumbnail = URL.createObjectURL(new Blob([new Uint8Array((str => str.replace(/%([0-9A-F]{2})/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16))).split('').map(c => c.charCodeAt(0)))(encodedData))], { type }));
if (thumbnail) {
loadImage(thumbnail, resolve, options);
return dfd.promise();
@@ -312,4 +314,4 @@
});
Issue Summary
With a Content Security Policy that blocks
data:
URLs (because the MDN warns against allowing them), when an editor uploads an image with a thumbnail embedded in the EXIF, the image uploader JS code tries to load a thumbnail image with adata:
URL. On the other hand, if the image does not already contain a thumbnail, the JS code generates one, and loads it using ablob:
URL.Steps to Reproduce
local.py
:The following message appears in the web console (example from Firefox):
The upload itself still works, it's just the thumbnail that is broken.
This other image, with EXIF stripped (
exiftool -all= iguana-noexif.jpg
), does not trigger an error:Technical details
3.12.6
5.0.9
6.2.2
130.0.1
Working on this
Anyone can contribute to this. View our contributing guidelines, add a comment to the issue once you’re ready to start.