User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008052909 Firefox/3.0
Build Identifier: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008052909 Firefox/3.0
In the LibX extension, we embed icons in a web page by adding <img src="chrome://skin/libx/someicon.ico"> elements to a client's DOM.
FF 3.0 RC1 (though not FF 3.0b5) disallows this access unless we set contentaccessible=yes.
This is contrary to the documentation at http://developer.mozilla.org/en/docs/Chrome_Registration#contentaccessible which states that contentaccessible=yes allows untrusted content access to chrome:// URL.
In this case, the content attempting to access the chrome:// URL is trusted.
Steps to Reproduce:
1. Download http://libx.org/editions/vt.5/libx-vt.xpi
2. Go to: http://www.amazon.com/gp/product/006073132X
3. See the broken image next to "(Hardcover)"
Repeat the same in FF 3.0b5 or FF 18.104.22.168 and you see the correct link.
The image is broken unless I specify contentaccessible=yes
The image should be shown even if contentaccessible=yes is not given, because contentaccessible applies only to untrusted content. Here, the script performing the insert() action is trusted.
Please either fix this, or, better, explain to me how I can insert a <img src="chrome://...." /> element in a script from within a trusted extension without FF thinking that untrusted content is attempting to access chrome://
If I must set contentaccessible=yes, justify why I need to open *all* of my extension to untrusted content, rather than just the skin/ subdirectory.
marked this bug as occurring in the FF 3.0 branch.
marked this bug as applying to all OS, not just Linux.
this bug persists in FF 3.0 RC2.
As it is, the bug prevents meaningful manipulation of web content by extensions unless the extensions reveal themselves to all content, thereby defeating one of the main uses of Firefox extensions.
I'd say this bug is probably INVALID or WONTFIX, it's working as designed.
Extensions that want to allow content access to their content can use contentaccessible=yes. If you don't want to allow access to everything, just place that subset into a separate package with contentaccessible=yes. That would be equivalent to FF2. If you didn't want arbitrary content to access things, you could probably just inject your stuff with data: URIs to avoid the whole problem.
If they're just images, placing them in your skin directory should just work too.
See also: http://developer.mozilla.org/en/docs/Chrome_Registration#contentaccessible
I do not believe comment #3 is correct ("If they're just images, placing them
in your skin directory should just work too.")
Without contentaccessible=yes, images in the skin/ directory are not accessible
to trusted code (that's what breaks my extension.)
With contentaccessible=yes, they are accessible to my trusted extension and to
code coming from untrusted content using a chrome:// URL. However, unlike
suggested in comment #3, I do not want to allow untrusted content access to my
Thus, either setting of contentaccessible produces undesirable semantics.
I suspect that the fix to Bug 292789 is faulty. Likely, instead of computing
the privileges of the caller, it may be looking at the privileges associated
with the content DOM to which the element is being added. I know too little
about Mozilla's security model to say for certain.
ps: regarding the suggestion in comment #3 to use data: URIs, doing so would have the following disadvantages:
- unnecessary conversion and parsing overhead
- subject to length limits (though I have not verified this, online sources report that Firefox limits data: URI to 100k, restricting our ability to manipulate the page's content.)
Doesn't matter how you _insert_ the references to the chrome resources - inserted via chrome script or just plain-old hard coded references. As long as web content is trying to access chrome resources, you need contentaccessible=yes
I understand that. That's why I filed this bug.
I do not want to set contentaccessible=yes, because I don't want the (untrusted) client website to have access to my chrome:// resources.
If you mark this bug as invalid, please fix your documentation and do not longer claim that your fix has anything to do with untrusted content.
BTW, the irony here is that stack inspection, a technique that would allow you to perform security checks correctly, was actually invented at Netscape, 10 years ago.
For what it is worth, our Pearl Comments extension (http://pearlcrescent.com/pearlcomments/) does something very similar to what you described for LibX -- we insert DOM img elements to add "icons" to the page (to show where comments have been made). We just changed our code to use data: URIs, which works well (note that we are using very small images).
In LibX, we have an web-based interface for maintainers to build editions. These editions contain their own images. While most of the images are probably small, we have no control over what images our adopters use and include in their editions.
To tell you the truth, we can live with setting contentaccessible=yes (and that's what we've turned on), I filed this bug only because I think the Mozilla developer's reasoning is wrong. They may be thinking that it's key where a chrome:// URL is referenced, rather than who creates that reference. An argument in favor of that view is that untrusted client code could, for instance, read the src property of the <img> element after our extension has added it. However, untrusted code could do the same with a data: URI, and in any event, client code can *always* detect, directly, or indirectly, if an extension makes significant changes to its DOM. Short of keeping a shadow copy for the client, this information channel is unavoidable.
I'm not sure about js code residing in chrome://, but in the case of images, I can't follow the motivation for introducing this fix. It appears to be doing little or nothing to increase security, and it requires already trusted to jump through hoops if they want to benefit from the added security it provides while still performing their function.
So what you are asking is for *every* DOM node every created to keep track of what created it so it knows what created it? That seems a bit unreasonable, IMO.
Note, you can also add a new package with the contentaccessible=yes attribute, and have it point to nothing. Then, you use overrides from the contentaccessible package that resolve to something in your package. This gives you the security you want, and still exposes bits to content that you need exposed.
Regarding comment #7:
Exactly what is there to clarify in the docs?
You're inserting an IMG-node (not the image itself, but just a tag to load and display an image) into the untrusted content's DOM tree, and the image will only get loaded when page gets re-layouted afterwards.
And that means it is the untrusted content's newly added IMG-tag that's trying to load the image, which isn't in any way, shape or form different than the page already being served with the IMG tag in place...
> Exactly what is there to clarify in the docs?
The doc at http://developer.mozilla.org/en/docs/Chrome_Registration#contentaccessible says:
"Untrusted content is no longer allowed to reference resources in chrome packages."
Normally, "untrusted content" means content loaded from an untrusted source, such as a web page. Content that is created and inserted by a trusted program, such as an extension, is not normally considered "untrusted content."
Your argument is that inserting such content into the client's DOM makes it untrusted because Firefox does not keep track of the origin of individual DOM elements. That's a limitation (an entirely reasonable one in my view), but this limitation doesn't truly make the added content "untrusted."
It is also by no means implied, or always the case, that inserting something into the content DOM makes it untrusted. For instance, if you insert a <object> with a reference to an embedded plugin in a page, this doesn't mean the plugin will lose its privileged status.
Maybe the documentation could be changed to say:
"Chrome resources can no longer be referenced from within elements contained in, or added to, a DOM that was loaded from an untrusted source. This restriction applies to both elements defined by the DOM's untrusted origin and to elements that were added later, including those added by extensions."