Closed Bug 530928 Opened 15 years ago Closed 15 years ago

"Security error" (NS_ERROR_DOM_SECURITY_ERR) when calling canvasCtx.getImageData() from local HTML file

Categories

(Core :: Security, defect)

defect
Not set
normal

Tracking

()

RESOLVED DUPLICATE of bug 444641

People

(Reporter: cjones, Unassigned)

Details

Attachments

(1 file)

I downloaded and tried running this demo http://people.mozilla.com/~vladimir/mdemos/imgmanip/image.html locally, but get a security error when calling getImageData(). A small testcase is <html> <body> <canvas id="dstcanvas" width=465 height=700></canvas> <script type="text/javascript"> var jpg = new Image(); jpg.src = 'trees.jpg'; jpg.onload = triggerBug; var dstcanvas = document.getElementById("dstcanvas"); function triggerBug() { var dstctx = dstcanvas.getContext("2d"); dstctx.clearRect(0, 0, 465, 700); dstctx.drawImage(jpg, 0, 0); // XXX this call fails XXX var dstpix = dstctx.getImageData(0, 0, 465, 700); } </script> </body> </html> where 'trees.jpg' is a file in the same directory as the testcase.
We're failing here NS_IMETHODIMP nsCanvasRenderingContext2D::GetImageData() { if (!mValid) return NS_ERROR_FAILURE; if (mCanvasElement && mCanvasElement->IsWriteOnly() && !nsContentUtils::IsCallerTrustedForRead()) { // XXX ERRMSG we need to report an error to developers here! (bug 329026) return NS_ERROR_DOM_SECURITY_ERR; } because mCanvasElement->IsWriteOnly() is true.
The canvas element is being set to write-only in CanvasUtils::DoDrawImageSecurityCheck() because nsCOMPtr<nsINode> elem = do_QueryInterface(aCanvasElement); if (elem) { // XXXbz How could this actually be null? PRBool subsumes; nsresult rv = elem->NodePrincipal()->Subsumes(aPrincipal, &subsumes); subsumes is false. It seems odd to me that the image and the canvas don't have the same security principal. But playing with principals is a bit out of my league right now ... any advice on where to start fixing this?
Looked into this a little more, and it comes down to inline PRBool NS_SecurityCompareURIs(nsIURI* aSourceURI, nsIURI* aTargetURI, PRBool aStrictFileOriginPolicy) { [snip] // special handling for file: URIs if (targetScheme.EqualsLiteral("file")) { [snip] // Otherwise they had better match PRBool filesAreEqual = PR_FALSE; nsresult rv = sourceFile->Equals(targetFile, &filesAreEqual); return NS_SUCCEEDED(rv) && filesAreEqual; The principal for the canvas is my HTML file, and the principal for the image is the image file, so this security check is failing. I don't understand what we're trying to prevent by being so anal about file: security. Any hints on a fix, or is this a WONTFIX candidate?
Thoughts on this general approach? It essentially makes "same-domain" mean "same parent directory" for file: URIs. I have no idea what the implications of this are, and I don't know whom I should be r?ing.
Assignee: nobody → jones.chris.g
Attachment #414412 - Flags: review?(bzbarsky)
Not really a canvas issue.
Assignee: jones.chris.g → nobody
Component: Canvas: 2D → Security
OS: Linux → All
QA Contact: canvas.2d → toolkit
Hardware: x86 → All
After skimming bug 230606 and https://developer.mozilla.org/en/Same-origin_policy_for_file%3a_URIs, I must admit to being rather confused about this bug. It appears that either can-load-URI is covered by a different policy than same-origin, or CheckSameOrigin() isn't applying quite the same same-origin check as CheckLoadURI(). I'm not sure what's the best way to fix this, but I'll stick with the r? for my original patch for the time being.
The fundamental design of file:// security stuff at the moment is the following: 1) Each file is a separate security domain; this is a symmetric check. 2) The CheckMayLoad check is asymmetric and allows loading other files from the same directory or files from subdirectories. 3) Certain cases stamp the loader's principal on the loadee based on item 2 so that we don't break existing use cases due to item 1. It sounds like you're proposing changing #1 to "all files in a given directory are considered to be a single security domain". Given item 2 above, maybe this is ok, but your testcase would then still break if the image were in subdirectory. That seems undesirable. The only way to fix the subdirectory case is to make image loads properly stamp the principal on the loadee (needed for data: and javascript: images too, in any case; longstanding imagelib issue).
Status: NEW → RESOLVED
Closed: 15 years ago
Resolution: --- → DUPLICATE
(In reply to comment #7) > The only way to fix the subdirectory case is to make image loads properly stamp > the principal on the loadee (needed for data: and javascript: images too, in > any case; longstanding imagelib issue). > Yeah, based on what you say this sounds like The Right Fix. Is there anything more to the "imagelib issue" than a good old-fashioned TODO?
Other than having to be careful about coalescing image loads across non-same-origin principals, no.
Or more precisely, imagelib coalesces loads across multiple documents based on URI; it would need to change to using URI + loader principal.
Attachment #414412 - Flags: review?(bzbarsky)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: