Heads up! This blog post hasn't been updated in over 2 years. CodePen is an ever changing place, so if this post references features, you're probably better off checking the docs. Get in touch with support if you have further questions.

Just recently we were having a conversation with Keith Wyland on Twitter. Keith was trying to using <canvas> and images in a Pen he was working on. He kept getting a security error:

Uncaught SecurityError: An attempt was made to break through the security policy of the user agent.

So he asked us if CodePen PRO’s Asset Hosting feature would help with this, because he thought the issue might be related to cross-domain security. We weren’t sure, actually, but we forked his Pen and moved the image assets to our PRO Asset Hosting. It didn’t seem to clear up the issue. We do set proper cross-origin headers for all our served assets. So, for instance, you can Ajax them no problem. That was only part of the issue here though. The other part had to do with a “tainted canvas”. Keith actually wrote a blog post about this very journey. And he writes:

Apparently, when you pull in a resource from an external domain, or cross-domain, and use it on the canvas, the canvas becomes “tainted” and will no longer allow you to pull data out of it.

To fix the issue, not only do the proper headers need to be sent (see enable-cors.org for more info), you need to set the crossOrigin attribute on the image itself in the JavaScript.

var img = new Image;
// This src needs the correct headers
img.src = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/pie.png";
// This makes it work
img.crossOrigin = "Anonymous";

See the Pen Canvas toDataURL with CrossOrigin by Keith Wyland (@keithwyland) on CodePen

If you don’t see the black icon in the middle of the circle, it might have to do with (something weird related to) caching. Try opening DevTools and loading the page with those open. And any ideas on why that would be the case, let us know!