capsulesocial / capsule-vue

Blogchain's web application, decentralised discourse and publishing on web3.
https://blogchain.app
GNU Affero General Public License v3.0
11 stars 3 forks source link

Image compression of SVG file changes mimetype to `image/png` #828

Open ashutosh1206 opened 2 years ago

ashutosh1206 commented 2 years ago

Noticed that image compression changes the mimetype of an SVG to image/png. Combined with https://github.com/capsulesocial/capsule-orbit/issues/425, the image passes through to the backend successfully.

There's a check before compression step in the post editor (src/components/post/Editor.vue) throwing an error that needs to be disabled:

            if (!isValidFileType(file.type)) {
                this.$toastError(`image of type ${file.type} is invalid`)
                return
            }

To confirm that mimetype changes due to compression, I disabled it and verified the mimetype of the resultant data URL (it was image/svg+xml:

            const reader = new FileReader()
            reader.readAsDataURL(image)
            reader.onload = async (i) => {
                if (i.target !== null && i.target.result !== null) {
                    const cid = await addPhotoToIPFS(i.target.result)
                    resolve({ cid, url: i.target.result, image, imageName: image.name })
                }
            }

Now I am not sure exactly what happens to the image raw data, because that the image gets rendered correctly on the post reader. I am opening an issue since we should probably check if the image raw data is an SVG after compression, or a PNG. Might need to consider security implications if it's an SVG (how the image is loaded on the reader etc.).

chrispanag commented 2 years ago

With cure53, we established that the src field of an image on the browser doesn't allow the execution of any malicious tags. I'll try to read more though about what happens during compression.

chrispanag commented 2 years ago

So... it's actually really interesting why it works with the svg.

It uses the OffscreenCanvas feature of the browser. Basically it renders the image there, and then it performs the necessary operations (this is useful because it leverages GPU acceleration in some operation)

So because it is a canvas, you can render anything you want, even an svg. But the results (apparently - pending confirmation) are png/jpeg, because it is converted afterwards.