What is a tainted canvas and why

January 29, 2024

© 2024 borui. All rights reserved. This content may be freely reproduced, displayed, modified, or distributed with proper attribution to borui and a link to the article: borui(2024-01-29 11:43:26 +0000). What is a tainted canvas and why. https://borui/blog/2024-01-29-en-what-is-tainted-canvas.
@misc{
  borui2024,
  author = {borui},
  title = {What is a tainted canvas and why},
  year = {2024},
  publisher = {borui's blog},
  journal = {borui's blog},
  url={https://borui/blog/2024-01-29-en-what-is-tainted-canvas}
}

when canvas will be marked tainted

The explanation from MDN docs:

As soon as you draw into a canvas any data that was loaded from another origin without CORS approval, the canvas becomes tainted. A tainted canvas is one which is no longer considered secure, and any attempts to retrieve image data back from the canvas will cause an exception to be thrown. MDN doc (MDN docs, n.d.)

  1. Allowing cross-origin use of images and canvas. (n.d.). MDN docs. Retrieved January 29, 2024, from https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image#what_is_a_tainted_canvas

why crossorigin image is not allowed

The reason why canvas can't draw crossorigin images without the crossOrigin attribute is to prevent unauthorized access to image data from other domains. This is a security measure to protect users from having their private data exposed by malicious websites that use images to pull information from remote servers without permission.

what does crossorigin do

The crossOrigin attribute allows images to be loaded from foreign origins with the appropriate CORS header, which indicates that the server agrees to share the image data with the requesting origin. There are two possible values for the crossOrigin attribute: anonymous and use-credentials. The anonymous value means that the request is made without any credentials (such as cookies or HTTP authentication), and the use-credentials value means that the request is made with the user's credentials.

If the crossOrigin attribute is not set, or if the server does not respond with a valid CORS header, the canvas becomes tainted. A tainted canvas is one that is no longer considered secure, and any attempts to retrieve image data from the canvas will cause a SecurityError to be thrown. This prevents the website from accessing or manipulating the image data in any way, such as using getImageData(), toDataURL(), or toBlob() methods.

There are some drawbacks and limitations of using the crossOrigin attribute, such as:

  • It requires the server to support CORS and send the proper header for cross-origin requests.
  • It may cause a two-step request process, where the browser first sends a pre-flight request with the OPTIONS method to verify the CORS policy of the server, and then sends the real request with the crossOrigin attribute.

why do we have to add crossorigin attribute

The server sending Access-Control-Allow-Origin:* is not enough to prevent the canvas from being tainted. You also need to add the crossOrigin attribute on the img tag, or set it in the Image constructor, before loading the image. This tells the browser to request cross-origin access when trying to download the image data. If you don't set the crossOrigin attribute, the browser will not send the Origin header in the request, and the server will not know which origin is requesting the image. Therefore, the browser will block the access to the image data and taint the canvas. This is a security measure to protect users from having their private data exposed by malicious websites that use images to pull information from remote servers without permission.

why img element is not affected

The img element is not bound by the rule for tainted canvas probably because it does not expose any image data to the web page. The img element only displays the image on the screen, but it does not allow the web page to access or manipulate the image data in any way. Therefore, there is no security risk of leaking private data from cross-origin images.

More relevant articles

  1. manandeep1610. (02 Jun, 2020.). Why does canvas.toDataURL() throws a security exception? geeksforgeeks. Retrieved January 29, 2024, from https://www.geeksforgeeks.org/why-does-canvas-todataurl-throws-a-security-exception/