Bug 72654 - Canvas's toDataURL raises SECURITY_ERR after painting a local image by local file
Summary: Canvas's toDataURL raises SECURITY_ERR after painting a local image by local ...
Status: RESOLVED WONTFIX
Alias: None
Product: WebKit
Classification: Unclassified
Component: Canvas (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-11-17 14:14 PST by Rafael Brandao
Modified: 2011-11-18 18:16 PST (History)
5 users (show)

See Also:


Attachments
This is an example of how to reproduce this behavior. (3.44 KB, application/zip)
2011-11-17 14:14 PST, Rafael Brandao
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Rafael Brandao 2011-11-17 14:14:23 PST
Created attachment 115677 [details]
This is an example of how to reproduce this behavior.

After some experiments with canvas element in a local file, I've realized that once we paint an image (also a local file) on it, we cannot use toDataURL anymore because it would have tainted its origin. I've put this under canvas, but it is more like a security origin "issue", I'm not even sure if this is a real bug.

By default the client's settings doesn't allow file access from file urls, and then we check if both origins (the page and the image) match when we check for "isSameSchemeHostPort". As their file paths are different, this doesn't match. As there's nothing else saying that one security origin (page) can request the other url (image's) on function securityOrigin::taintsCanvas, then we just identify that the canvas's origin should be tainted. This check is done once we ask the image to be drawn inside the canvas element.

Now thinking on it, it looks weird that this check says I cannot request that url, but the page itself load the image if I put it on any img's src, like I did in the example I've attached. Does this make any sense?

Another thing that seems strange to me is that we cannot generate the data url for this canvas element after we've tainted its origin. We can still paint everything on it, including new images, but not to generate that url. I'd like to understand if this is somewhat expected or if this could be indeed a bug.
Comment 1 Adam Barth 2011-11-17 14:23:07 PST
This is the correct behavior.

The idea behind a tainted canvas is that you can continue to draw new things on the canvas and you can display it to the user, but you can't actually read back the pixels.  If you could convert it to a data URL, you would be able to read back its pixels.

The reason we block reading back the pixels in this case is because we don't want one file URL to be able to read the contents of another file URL.  That would let an email attachment you downloaded (say a resume from a job application) snoop on photos of you children in your home directory.
Comment 2 Sam Weinig 2011-11-18 15:01:05 PST
(In reply to comment #1)
> This is the correct behavior.
> 
> The idea behind a tainted canvas is that you can continue to draw new things on the canvas and you can display it to the user, but you can't actually read back the pixels.  If you could convert it to a data URL, you would be able to read back its pixels.
> 
> The reason we block reading back the pixels in this case is because we don't want one file URL to be able to read the contents of another file URL.  That would let an email attachment you downloaded (say a resume from a job application) snoop on photos of you children in your home directory.

It seems like it might be incorrect if allowUniversalAccessFromFileURLs() is true.  Rafael, what browser are you running?
Comment 3 Rafael Brandao 2011-11-18 18:16:55 PST
(In reply to comment #2)
> (In reply to comment #1)
> > This is the correct behavior.
> > 
> > The idea behind a tainted canvas is that you can continue to draw new things on the canvas and you can display it to the user, but you can't actually read back the pixels.  If you could convert it to a data URL, you would be able to read back its pixels.
> > 
> > The reason we block reading back the pixels in this case is because we don't want one file URL to be able to read the contents of another file URL.  That would let an email attachment you downloaded (say a resume from a job application) snoop on photos of you children in your home directory.
> 
> It seems like it might be incorrect if allowUniversalAccessFromFileURLs() is true.  Rafael, what browser are you running?

Hello Sam, I've managed to print the value for that option and it was false, at least for Qt port. I could also reproduce it on Google Chrome, not sure right now about the version (I could check on Monday at work). I should have tried on Firefox and Safari as well to compare behaviors, but I've forgot.

Adam Barth explained a bit more on IRC why this is correct. The function name "canRequest" should be changed to "canRead" because the problem about toDataURL is that you shouldn't provide a way to the script to read back what was painted (correct me if I'm wrong), otherwise one could expose this data illegally.

But checking this "bug" I've went into another one: https://bugs.webkit.org/show_bug.cgi?id=63506 - I'm a bit curious how Chrome does show the line number and file url when an error happens (on console log). I've tested it with webkit trunk and it wasn't working at all.