Why Does Canvas.Todataurl() Throw a Security Exception

Why does canvas.toDataURL() throw a security exception?

In the specs it says:

Whenever the toDataURL() method of a
canvas element whose origin-clean flag
is set to false is called, the method
must raise a SECURITY_ERR exception.

If the image is coming from another server I don't think you can use toDataURL()

canvas.toDataURL() throws security exception, despite image being local

This is the same problem as described here: Rasterizing an in-document SVG to Canvas

Basically, adding any SVG to a canvas taints the canvas and toDataURL() can no longer be called on it. Apparently, Firefox 12 fixes this, but Chrome has yet to fix it.

toDataURL throw Uncaught Security exception

This is a CORS issue - Gravatar sends the correct headers, you just need to put the correct attribute in:

<img id="preview1" crossorigin="anonymous" src="http://www.gravatar.com/avatar/0e39d18b89822d1d9871e0d1bc839d06?s=128&d=identicon&r=PG">

function getBase64() {
var img = document.getElementById("preview1");
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.width;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
alert(dataURL.replace(/^data:image\/(png|jpg);base64,/, ""));
}
getBase64();

Note that your first example also failed when I tested it, just as it should.

why is this toDataURL line a security error?

As per the spec, information leakage can occur if scripts from one origin can access information (e.g. read pixels) from images on another origin. The worry is that a malicious app could deduce information that it otherwise wouldn't have access to by loading in an image from another domain/origin (easily done with images) and reading the pixel content. XHR has protections built in place to prevent XD leakage. Images do not.

canvas.toDataURL() SecurityError

Unless google serves this image with the correct Access-Control-Allow-Origin header, then you wont be able to use their image in canvas. This is due to not having CORS approval. You can read more about this here, but it essentially means:

Although you can use images without CORS approval in your canvas,
doing so taints the canvas. Once a canvas has been tainted, you can no
longer pull data back out of the canvas. For example, you can no
longer use the canvas toBlob(), toDataURL(), or getImageData()
methods; doing so will throw a security error.

This protects users from having private data exposed by using images
to pull information from remote web sites without permission.

I suggest just passing the URL to your server-side language and using curl to download the image. Be careful to sanitise this though!

EDIT:

As this answer is still the accepted answer, you should check out @shadyshrif's answer, which is to use:

var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url;

This will only work if you have the correct permissions, but will at least allow you to do what you want.



Related Topics



Leave a reply



Submit