Closed Bug 792479 Opened 12 years ago Closed 7 years ago

can't load iframe with content from addon

Categories

(Add-on SDK Graveyard :: General, defect, P2)

defect

Tracking

(Not tracked)

RESOLVED INCOMPLETE

People

(Reporter: thomas, Unassigned)

References

Details

(Keywords: access)

Attachments

(4 files)

While currently it is possible that a webpage can load resources like images from an addon the same does not applies to iframes: if an iframe with a src attribute of e.g. 'resource://<extension id>-at-jetpack/<extension name>/data/page.html' is added to a web page by a content script then a security error is raised.

In my scenario I scan web pages like webmail provider for encrypted messages. Once found, I place an overlay on top of the encrypted content and insert an iframe that will show a UI and finally the decrypted message. The motivation to use an iframe is:
- the style should be separated from the outer page
- security: as the iframe is from different origin the outer page cannot access its content

This currently works for chrome extensions where it is possible to define 'web accessible resources': http://developer.chrome.com/extensions/manifest.html#web_accessible_resources
The loaded iframe runs then in the context of the extension and has access to messaging.

Could this be a feature for the Add-on SDK?
Or is there a work around with XPCOM?
Gabor, do you know if this would be possible?
Whiteboard: [triage:followup]
There is coming a feature that can give content-script access to more than one origin. With that I think this problem can be addressed, Alex or I can look into that tomorrow.
Depends on: 786681
Priority: -- → P2
Whiteboard: [triage:followup]
Is this really related to bug 786681? The new feature described there would allow cross domain features for content scripts. But in the problem described above I'm adding an iframe to a webpage. Therefore I'm in the context of the webpage and the webpage then tries to load the content for the iframe from the resource:// URI.

This triggers a security violation. For me, it looks similar to what would happen if I would try to load the iframe from a file:// URI. Could it be that the resource protocol has the same constraints?

Currently my work around is that I load the iframe with an empty html page from a domain with http. A page_mod then injects a content script into the iframe. The addon loads my html template, sends it as a message to the content script, which finally inserts this content to the iframe. This works, but is of course not an optimal solution.
(In reply to toberndo from comment #3)
> Is this really related to bug 786681? The new feature described there would
> allow cross domain features for content scripts. But in the problem
> described above I'm adding an iframe to a webpage. Therefore I'm in the
> context of the webpage and the webpage then tries to load the content for
> the iframe from the resource:// URI.

You are right. I thought that it helps if you execute the navigation call from a more privileged context but it does not.

> This triggers a security violation. For me, it looks similar to what would
> happen if I would try to load the iframe from a file:// URI. Could it be
> that the resource protocol has the same constraints?

I'm not sure it is the same but something very similar. I think using a js file from a resource uri should be possible, but navigating to resource::// URI is not.

> Currently my work around is that I load the iframe with an empty html page
> from a domain with http. A page_mod then injects a content script into the
> iframe. The addon loads my html template, sends it as a message to the
> content script, which finally inserts this content to the iframe. This
> works, but is of course not an optimal solution.

I don't have anything better to offer right now. Message passing seems like the best solution for these kind of cross origin, or even cross protocol issues imo. In the meanwhile I will ask around about this 'web accessible resources', it would be nice if addon developers could easily implement the same addon on every browsers in general.
Any updates on this?

For me, the biggest issue with the work around is the dependency on an external resource. I would like the iframe to be loaded only with local resources.

I tried to experiment with dynamic iframes with src="about:blank", but couldn't make a page-mod to inject anything here.
(In reply to toberndo from comment #5)

> I tried to experiment with dynamic iframes with src="about:blank", but
> couldn't make a page-mod to inject anything here.

What's the include rule of your page-mod? However, you can use `data:` URL instead, and set directly the HTML you want to. Unfortunately, that it means it would be accessible from the host page too (the same for 'about:blank', I'm afraid); but you can play with iframe's sandbox attribute (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) and see if in your case it helps.

Gabor, any news from your side?
Flags: needinfo?(gkrizsanits)
(In reply to Matteo Ferretti [:matteo] [:zer0] from comment #6)
> Gabor, any news from your side?

I'm not working on this. We would need those web accessible resources. If I'm not mistaken Mossop was working on some protocol like that.
Flags: needinfo?(gkrizsanits) → needinfo?(dtownsend+bugmail)
Yes it's in progress but I keep hitting roadblocks.
Flags: needinfo?(dtownsend+bugmail)
Any updates about this bug?
Flags: needinfo?(dtownsend+bugmail)
(In reply to Matteo Ferretti [:matteo] [:zer0] from comment #6)
> I'm afraid); but you can play with iframe's sandbox attribute
> (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) and see
> if in your case it helps.

In my threat model the sandbox attribute probably won't help: the web site is the advisory and I want to hide the content of the iframe from it.
(In reply to Thomas Oberndörfer from comment #5)
> For me, the biggest issue with the work around is the dependency on an
> external resource. I would like the iframe to be loaded only with local
> resources.
> 
> I tried to experiment with dynamic iframes with src="about:blank", but
> couldn't make a page-mod to inject anything here.

i think "about:blank" is handled as a special case, but you can subvert that by adding a unique query string, like src="about:blank?myrandomstring123", and the same value for `PageMod.include` option.

also, i think the original page would not have access to the iframe content, but i'll leave testing that as an exercise to you.. :)
Thomas, not sure I get what you meant, if you use the `data:` URL to load content in the iframe, and then set the sandbox, you hide the content of the iframe from it, in the way that the website can't access to the iframe's content (but, also viceversa, so you need to communicate via `port` and `postMessage`).

If you want to explain your use case better, I would try to help! In the meanwhile, you can check my reply in SO and test the code: http://stackoverflow.com/questions/21082162/firefox-addon-sdk-loading-addon-file-into-iframe/21132801?noredirect=1#comment31812958_21132801

Hope it helps.
(In reply to Tomislav Jovanovic [:zombie] from comment #11)
> i think "about:blank" is handled as a special case, but you can subvert that
> by adding a unique query string, like src="about:blank?myrandomstring123",
> and the same value for `PageMod.include` option.
> 
> also, i think the original page would not have access to the iframe content,
> but i'll leave testing that as an exercise to you.. :)

Amazing, that works! I could inject the PageMod and get a permission denied when I try to access:

window.frames[0].document
window.frames[0].contentWindow
(In reply to Matteo Ferretti [:matteo] [:zer0] from comment #12)
> If you want to explain your use case better, I would try to help! In the
> meanwhile, you can check my reply in SO and test the code:
> http://stackoverflow.com/questions/21082162/firefox-addon-sdk-loading-addon-
> file-into-iframe/21132801?noredirect=1#comment31812958_21132801

Thanks for the help, but I think the problem with this solution is that you still reveal the content of the iframe to the outer page. It's correct that the outer page can't access the DOM of the iframe but it can access the src attribute of the iframe that contains the complete content (I did a quick check with your example in SO).
(In reply to Thomas Oberndörfer from comment #14)
> (In reply to Matteo Ferretti [:matteo] [:zer0] from comment #12)
> > If you want to explain your use case better, I would try to help! In the
> > meanwhile, you can check my reply in SO and test the code:
> > http://stackoverflow.com/questions/21082162/firefox-addon-sdk-loading-addon-
> > file-into-iframe/21132801?noredirect=1#comment31812958_21132801
> 
> Thanks for the help, but I think the problem with this solution is that you
> still reveal the content of the iframe to the outer page.

My bad, I thought set the `src` property instead of using `setAttribute` wouldn't reveal that. You can easily use instead `iframe.contentWindow.location.href` to solve the issue, I used `iframe.src` because was shorter.
Thanks to point it out, I also updated the reply on SO.
(In reply to Matteo Ferretti [:matteo] [:zer0] from comment #9)
> Any updates about this bug?

I haven't had time to work on this in a long time
Flags: needinfo?(dtownsend+bugmail)
Hi.

I am trying to understand how to fix this.

Is it correct that the reason why the load does not work is because of this definition for resource:// URLs?

nsResProtocolHandler::GetProtocolFlags(uint32_t *result)
{
    // XXXbz Is this really true for all resource: URIs?  Could we
    // somehow give different flags to some of them?
    *result = URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE;
    return NS_OK;
}

And would it work if the addon page was loaded from a URL with this definition?

URI_STD | URI_LOADABLE_BY_ANYONE | URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT

Would the solution then be to create a new URL scheme and use that for resources that should be accessible from the web? Or should resource:// somehow be modified to have these flags for certain paths? (I think something like this is done for about: URLs) Would it be OK to make everything in the "data" directory of an SDK addon available like this, or should it be restricted to specific URL patterns like Chrome does, or maybe use a new fixed directory name for web accessible resources?
Flags: needinfo?(gkrizsanits)
Flags: needinfo?(dtownsend+bugmail)
(In reply to Jesper Kristensen from comment #17)
> Hi.
> 
> I am trying to understand how to fix this.
> 
> Is it correct that the reason why the load does not work is because of this
> definition for resource:// URLs?
> 
> nsResProtocolHandler::GetProtocolFlags(uint32_t *result)
> {
>     // XXXbz Is this really true for all resource: URIs?  Could we
>     // somehow give different flags to some of them?
>     *result = URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE;
>     return NS_OK;
> }
> 
> And would it work if the addon page was loaded from a URL with this
> definition?
> 
> URI_STD | URI_LOADABLE_BY_ANYONE | URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT
> 
> Would the solution then be to create a new URL scheme and use that for
> resources that should be accessible from the web? Or should resource://
> somehow be modified to have these flags for certain paths? (I think
> something like this is done for about: URLs) Would it be OK to make
> everything in the "data" directory of an SDK addon available like this, or
> should it be restricted to specific URL patterns like Chrome does, or maybe
> use a new fixed directory name for web accessible resources?

That is basically the approach I took in a patch I started working on. It's difficult to get right though, gecko isn't really designed for this.
Flags: needinfo?(dtownsend+bugmail)
I definitely think that we should put all the web accessible pages into a separate place from the rest of add-on related pages, like panels and what not, because of security reasons.
Flags: needinfo?(gkrizsanits)
Attached file url-handler.js
I made this code, which I can place in my add-on to make all files within the data directory available for use in iframes.

Can anyone see any issues with the way I do this?

One thing I cannot do with this, but I can do with Chrome's web_accessible_resources is using XMLHttpRequest to access the content from a page. I don't know how to achieve that. Any suggestions?
This patch allows a resource:// url to be marked as web accessible, meaning that web content can load the url in iframes and read the content using XMLHttpRequest, while it is still treated as cross-origin.

The patch allows each resource domain to be marked as web accessible. The default is still semi-accessible. I chose the simplest solution of doing it per resource domain. Maybe we want to allow making individual URLs or patterns web accessible, like Chrome does.

I have tried to avoid breaking existing users of the nsIResProtocolHandler interface by using a separate methods to mark a domain as web accessible.

My patch uses the same structure as used by the existing code for chrome:// and file:// URLs. It would be great if this code could be refactored to split the policy enforcement from the policy definition, so that the policy could be defined in an extensible way, while still being enforced in a central place. But that is probably a different bug.
Attached patch web-sdk.patchSplinter Review
This patch allows an SDK based add-on to have web accessible resources by placing them into the "data/web/" directory.

The "data/web/" directory is hardcoded into the SDK, to follow the style of hardcoding the "data/", "lib/" and "test/" directories.

Add-on authors need to use self.data.web.url("example.txt") instead of self.data.url("web/example.txt") whenever they want to use a URL in web content, because that was easier to implement, given how I implemented my changes to nsIResProtocolHandler. This has the downside that a page like "data/web/example.html" loaded into an iframe in web content cannot use a relative url like <img src="../example.jpg"> to load the resource at "data/example.jpg", which is not web accessible.

I could only find JavaScript files within the SDK tests. I could not find tests that load HTML documents, so I don't know how to write a SDK unit test for this.
Attached file test-addon.zip
an add-on and a web page to test it
hey Dave, can you look, or find someone to look at this?
Flags: needinfo?(dtownsend+bugmail)
Comment on attachment 8404091 [details] [diff] [review]
web-resource-protocol.patch

Gabor, can you review this?
Attachment #8404091 - Flags: review?(gkrizsanits)
Flags: needinfo?(dtownsend+bugmail)
Comment on attachment 8404093 [details] [diff] [review]
web-sdk.patch

Irakli, does this seem sensible to you?
Attachment #8404093 - Flags: review?(rFobic)
Comment on attachment 8404091 [details] [diff] [review]
web-resource-protocol.patch

Review of attachment 8404091 [details] [diff] [review]:
-----------------------------------------------------------------

I'm going to have to pass this. I don't see the possible security implication of a change like this. And don't have enough knowledge about the resource protocol either. One question though: is it important to be web accessible or is it enough to be content-script accessible? Because for the later we could put all this magic in nsExpandedPrincipal instead and then it would be already a lot less scarier to me. Although I'm not sure that using nsEP for everything is the right thing to do.

::: caps/src/nsScriptSecurityManager.cpp
@@ +770,5 @@
> +              return NS_OK;
> +            }
> +          }
> +        }
> +

Nit: you might want to add a helper for this part to avoid code duplication
Attachment #8404091 - Flags: review?(gkrizsanits) → review?(bobbyholley)
Sorry, I wanted to select a bit bigger code chunk for the nit...

+  if (targetScheme.EqualsLiteral("resource")) {
+     nsCOMPtr<nsIResProtocolHandler> resHandler(do_GetService(
+                                                  NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "resource"));
+    if (resHandler) {
+      bool isPublic = false;
+      resHandler->IsPublicResource(targetBaseURI, &isPublic);
+      if (isPublic) {
+        return NS_OK;
+      }
+    }
+  }
(In reply to Gabor Krizsanits [:krizsa :gabor] from comment #27)
> One question though: is it important to be web
> accessible or is it enough to be content-script accessible?

One important consideration pertaining to this question, which I haven’t seen mentioned yet in this issue’s comments, is the role of a host page’s Content Security Policy. I would answer Gabor’s question this way: Yes, it’s important for the iframe `src` page to be web-accessible using a new scheme such as `resource:` so that web page authors can explicitly, unambiguously allow or disallow Firefox extension iframes in their Content Security Policy. Some sites with fairly restrictive CSPs explicitly allow Chrome extension iframes, but they can’t yet do the same for Firefox extensions.

For example, here’s the CSP header of https://blog.twitter.com/ (the Twitter blog):
> content-security-policy: default-src https: 'unsafe-eval' data:;
> report-uri https://twitter.com/scribes/csp_report; img-src https: data:;
> script-src https://*.twitter.com https://*.twimg.com https://*.vine.co https://ssl.google-analytics.com 'unsafe-eval';
> frame-src https://* chrome-extension: about: javascript:

Note the use of `chrome-extension:` in the `frame-src` clause. I suspect `about:` and perhaps `javascript:` are there (at least in part) specifically to permit Firefox extensions that are using workarounds for this very issue, but there’s no way to be certain unless we can get a Twitter employee to explain their policy, since those are general-purpose schemes that may also have other uses. Regardless, defining a new scheme for Firefox extensions to use for web-accessible content will allow web page authors to clarify their CSPs and perhaps reduce the attack surface their CSPs expose (by eliminating `about:` and/or `javascript:` from their `frame-src` clause).
(In reply to Gabor Krizsanits [:krizsa :gabor] from comment #27)
> One question though: is it important to be web
> accessible or is it enough to be content-script accessible?

I think it would be quite a job to keep track of who inserted or manipulated an image or iframe or anything else in order to base decisions on what to load on that, and I guess if we managed to do it, it would probably be very leaky anyway, so would not help much.

(In reply to jmjacobs from comment #29)
> One important consideration pertaining to this question, which I haven’t
> seen mentioned yet in this issue’s comments, is the role of a host page’s
> Content Security Policy.

I haven't thought of that. I tested my patch with this:

<?php header('Content-Security-Policy: default-src \'self\''); ?>
<iframe src="resource://jid1-jvrqfxgnl8wqla-at-jetpack-web/public.js"></iframe>
<iframe src="http://mozilladanmark.dk/mcs/img/logo/dino.png"></iframe>

Only the http url is blocked, while the resource url is loaded. That works for me.
Comment on attachment 8404093 [details] [diff] [review]
web-sdk.patch

Review of attachment 8404093 [details] [diff] [review]:
-----------------------------------------------------------------

I would prefer if there was no default folder like `data/web` instead we should add a entry to package.json that could point to a directory in package that would be web loadable. That way it is explicitly opt-in and avoids exposing things that add-ons didn't intended to expose.


Other than that everything looks fine to me.
Attachment #8404093 - Flags: review?(rFobic) → review-
Gabor I wonder if we could somehow use of extended principals stuff to mark specific urls loadable from web content, so that users can provide patterns similar to chrome:
https://developer.chrome.com/extensions/manifest/web_accessible_resources

Rather than having completely separate url for such resources.
Flags: needinfo?(gkrizsanits)
(In reply to Irakli Gozalishvili [:irakli] [:gozala] [@gozala] from comment #31)
...
> I would prefer if there was no default folder like `data/web` instead we
> should add a entry to package.json that could point to a directory in
> package that would be web loadable. That way it is explicitly opt-in and
> avoids exposing things that add-ons didn't intended to expose.

+1, I think it is reasonable to expect that the developer should make a specific location available explicitly.

One question, it will likely then be common that developers just share the entire data folder. If we see an inherent security issue with this we should document what we *recommend* developers do here and why. Is there any inherent issue with sharing ./data/* ?
Flags: needinfo?(rFobic)
This is on my list of things to look at - I just haven't had time. I'll get to it soon, hopefully.
(In reply to Jeff Griffiths (:canuckistani) from comment #33)
> (In reply to Irakli Gozalishvili [:irakli] [:gozala] [@gozala] from comment
> #31)
> ...
> > I would prefer if there was no default folder like `data/web` instead we
> > should add a entry to package.json that could point to a directory in
> > package that would be web loadable. That way it is explicitly opt-in and
> > avoids exposing things that add-ons didn't intended to expose.
> 
> +1, I think it is reasonable to expect that the developer should make a
> specific location available explicitly.
> 
> One question, it will likely then be common that developers just share the
> entire data folder. If we see an inherent security issue with this we should
> document what we *recommend* developers do here and why. Is there any
> inherent issue with sharing ./data/* ?

I think add-on reviewers usually are good at enforcing better patterns here. Also documenting this feature along with a best practices is a good idea for sure.
Flags: needinfo?(rFobic)
(In reply to Irakli Gozalishvili [:irakli] [:gozala] [@gozala] from comment #32)
> Gabor I wonder if we could somehow use of extended principals stuff to mark
> specific urls loadable from web content, so that users can provide patterns
> similar to chrome:
> https://developer.chrome.com/extensions/manifest/web_accessible_resources
> 
> Rather than having completely separate url for such resources.

What do you think of? Principals are not currently involved in all the checks that need changes.

I would like to try to make a patch that allows add-ons to provide patterns, but I don't think I know enough about URL path parsing and interpretation to make a safe pattern matching.
(In reply to Irakli Gozalishvili [:irakli] [:gozala] [@gozala] from comment #32)
> Gabor I wonder if we could somehow use of extended principals stuff to mark
> specific urls loadable from web content, so that users can provide patterns
> similar to chrome:
> https://developer.chrome.com/extensions/manifest/web_accessible_resources
> 
> Rather than having completely separate url for such resources.

We don't have any wildcard support on platform side. I was talking about wildcard support with Bobby a while ago in bug 723627. The conclusion was that we could implement it up to the effective-TLD... But I have no clue when will I have time for it. In general I would prefer better to flag directories to be web accessible.

Anyway, I really need someone with more expertise in this area than me. I will try to talk to Bobby about this soon, and also ask around on irc...
Flags: needinfo?(gkrizsanits)
Sorry it took me so long to get backed to this. I've been swamped with Tarako stuff (which code-freezes today).

Boris and I just discussed this on IRC, and have a few questions:

* What kind of principal do we want the iframe to have? It can't be same-origin with the content script, because content scripts run with nsExpandedPrincipal, and we don't let people make DOM Window with nsEP. So presumably it would have an nsNullPrincipal. But in that case it wouldn't be able to directly pass messages to the parent, which comment 0 indicates is desirable.

* Do we actually need content to be able to trigger the loads, or do we just want to be able to cause this stuff to be loaded in a content docshell? If it's the latter, you can accomplish this right now. Comment 0 describes setting the |src| attribute, which will cause the load to happen with the principal of the document. But if you just do contentWindow.location you should be able to trigger the load over Xrays. Or is the issue that nsEP isn't allowed to load these URIs either?

I'm not totally sure what principal we'll end up with in the load-over-Xray case, though. We've got a content script with an nsEP, which, after bug 996069, won't be inherited. So will we get a codebase principal for the resource:// URI? Are those all same-origin with each other? Boris, can you answer this?
(In reply to Bobby Holley (:bholley) from comment #38)
> Sorry it took me so long to get backed to this. I've been swamped with
> Tarako stuff (which code-freezes today).
> 
> Boris and I just discussed this on IRC, and have a few questions:
> 
> * What kind of principal do we want the iframe to have? It can't be
> same-origin with the content script, because content scripts run with
> nsExpandedPrincipal, and we don't let people make DOM Window with nsEP. So
> presumably it would have an nsNullPrincipal. But in that case it wouldn't be
> able to directly pass messages to the parent, which comment 0 indicates is
> desirable.

I'm just speaking from developer expectations here, so bear with me.

From a developer's perspective this would be easiest to swallow in one of two ways:

1. (ideally) content loaded from the add-ons data folder into the iframe should have the same features as a panel or a toolbar, so that means the addon global that could be used to communicate with main.js

2. (less ideal, but still easily understandabjle) the same as any other web page. This means communication would need to use postMessage to a content script to then get relayed back to main.js, introducing complexity to the implementation.

Does this make sense? Totally admit I don't have a deep enough understanding of various principals just to name the one I want.
(In reply to Jeff Griffiths (:canuckistani) from comment #39)
> 1. (ideally) content loaded from the add-ons data folder into the iframe
> should have the same features as a panel or a toolbar, so that means the
> addon global that could be used to communicate with main.js

What do panels and toolbars run with at present? We assert against using nsExpandedPrincipal for DOMWindows, so they're necessarily not same-origin with content scripts. Are they same-origin with the page?

> 2. (less ideal, but still easily understandabjle) the same as any other web
> page. This means communication would need to use postMessage to a content
> script to then get relayed back to main.js, introducing complexity to the
> implementation.

Comment 0 indicated that they wanted something cross-origin for the page. If we gave them a nonce principal (which is cross-origin with everything but itself), would that provide reasonable semantics?
> So will we get a codebase principal for the resource:// URI?

Yes.  

> Are those all same-origin with each other?

I don't actually know.  I'd have to experiment to see.
(In reply to Bobby Holley (:bholley) from comment #40)
> (In reply to Jeff Griffiths (:canuckistani) from comment #39)
> > 1. (ideally) content loaded from the add-ons data folder into the iframe
> > should have the same features as a panel or a toolbar, so that means the
> > addon global that could be used to communicate with main.js
> 
> What do panels and toolbars run with at present? We assert against using
> nsExpandedPrincipal for DOMWindows, so they're necessarily not same-origin
> with content scripts. Are they same-origin with the page?

Yes they are same origin with page. Since both content script and page script
are trusted code from the very same add-on there is no separation needed there.

I guess this behavior could be preserved only if the page has only cross origin
access to this iframe. But that's not a problem right?

> 
> > 2. (less ideal, but still easily understandabjle) the same as any other web
> > page. This means communication would need to use postMessage to a content
> > script to then get relayed back to main.js, introducing complexity to the
> > implementation.
> 
> Comment 0 indicated that they wanted something cross-origin for the page. If
> we gave them a nonce principal (which is cross-origin with everything but
> itself), would that provide reasonable semantics?

I don't think so. What if that page needs access to more content from the same
data folder? Would that work with nullprincipal? I think it should be a regular codebase
principal, only problem is that the resource protocol might be tricky... I'm not
sure it does not have any pitfalls when it comes to same origin determination against
other resource uris.
(In reply to Bobby Holley (:bholley) from comment #38)
> * Do we actually need content to be able to trigger the loads, or do we just
> want to be able to cause this stuff to be loaded in a content docshell? If
> it's the latter, you can accomplish this right now. Comment 0 describes
> setting the |src| attribute, which will cause the load to happen with the
> principal of the document. But if you just do contentWindow.location you
> should be able to trigger the load over Xrays. Or is the issue that nsEP
> isn't allowed to load these URIs either?

That does not seem to work. I still get a permission error when I try to load this in a content script:

var ifr = document.createElement('iframe');
document.body.appendChild(ifr);
ifr.contentWindow.location.href = "resource://***";
> > should be able to trigger the load over Xrays. Or is the issue that nsEP
> > isn't allowed to load these URIs either?
> 

Currently nsEP cannot load this URI either. The patch is adding some mechanism to let content load them
I was suggesting to put that mechanism on nsEP instead of regular principals... Not sure if it's good enough, it was just an idea. Other than chrome I think only other resources can load those URIs, and I _think_ that the resource URI protocol is like the file protocol when it comes to decide who can load what.
> and I _think_ that the resource URI protocol is like the file protocol when it comes to
> decide who can load what

I can find no evidence of this in the code.  Citation, please?
(In reply to Boris Zbarsky [:bz] (on PTO, reviews are slow) from comment #45)
> > and I _think_ that the resource URI protocol is like the file protocol when it comes to
> > decide who can load what
> 
> I can find no evidence of this in the code.  Citation, please?

That's more of a question than an actual statement from my side. I tried figuring out how resource protocol works in this respect by looking at bugs like 624764, and reading some code, but don't know really. And I didn't want to rely on experimentation since resource protocol might be tricky... So this is the 1 million dollar question as far as I'm concerned... Maybe Benjamin knows more about this.
Flags: needinfo?(benjamin)
The resource protocol definitely is not like file: in terms of directory restrictions. But I don't think I quite understand what question I was being asked.
Flags: needinfo?(benjamin)
(In reply to Benjamin Smedberg  [:bsmedberg] from comment #47)
> The resource protocol definitely is not like file: in terms of directory
> restrictions. But I don't think I quite understand what question I was being
> asked.

Sorry for the vague question. So we would like to introduce an API that can mark certain resource URI's as web-accessible, meaning they can be loaded with a regular content principal (or plan B with an nsExpandedPrincipal). Now I would like to know what kind of pitfalls the resource protocol might have that we have to keep in mind when designing such an API, and in general how does it work in terms of directory restrictions.
I don't know whether all resource URIs are considered same-origin to all other ones or not. I suspect that it's by domain, so:

* all resource:///* are same-origin with resource:///* but not resource://gre/*
* all resource://gre/* are same-origin with resource://gre/* but not resource:///*

So I suspect you could decide to make a new resource mapping and make it web-accessible (by altering nsResProtocolHandler::GetProtocolFlags).

However, in the past ISTR that there were some special-case permissions given to things from resource:// protocol URIs. I don't remember how that worked or whether it's still true.

Is there a particular reason it would be better to re-use resource: instead of creating a different protocol handler?
(In reply to Benjamin Smedberg  [:bsmedberg] from comment #49)
> Is there a particular reason it would be better to re-use resource: instead
> of creating a different protocol handler?

I agree - if we want to add new machinery here, we should create a different protocol handler, probably called firefox-extension://. resource:// just has too much baggage.
> Is there a particular reason it would be better to re-use resource: instead
> of creating a different protocol handler?

Thanks a lot for all the info. Indeed, a new protocol handler seems to be the way to go.
Comment on attachment 8404091 [details] [diff] [review]
web-resource-protocol.patch

Review of attachment 8404091 [details] [diff] [review]:
-----------------------------------------------------------------

I have to r- this patch for now... sorry... we need to implement a new protocol handler for this.
Attachment #8404091 - Flags: review?(bobbyholley) → review-
(In reply to Gabor Krizsanits [:krizsa :gabor] from comment #51)
> > Is there a particular reason it would be better to re-use resource: instead
> > of creating a different protocol handler?

> Thanks a lot for all the info. Indeed, a new protocol handler seems to be
> the way to go.

I missed all the discussion before, but I think having such protocol was one of the original idea (e.g. `addon:`), followed by the add-on's id. It was requested also because open a tab with the full `resource://` uri is not nice to see; especially now that we do not have in Australis the capability to hide the location bar as before (see about:addons).
Please let me know if you have any update on this problem. I am trying to load an Angular JS app in add-on/data directory into an iframe created by content script.
(In reply to Jared Jacobs from comment #29)
> (In reply to Gabor Krizsanits [:krizsa :gabor] from comment #27)
> > One question though: is it important to be web
> > accessible or is it enough to be content-script accessible?
> 
> One important consideration pertaining to this question, which I haven’t
> seen mentioned yet in this issue’s comments, is the role of a host page’s
> Content Security Policy. I would answer Gabor’s question this way: Yes, it’s
> important for the iframe `src` page to be web-accessible using a new scheme
> such as `resource:` so that web page authors can explicitly, unambiguously
> allow or disallow Firefox extension iframes in their Content Security
> Policy. Some sites with fairly restrictive CSPs explicitly allow Chrome
> extension iframes, but they can’t yet do the same for Firefox extensions.
> 
> For example, here’s the CSP header of https://blog.twitter.com/ (the Twitter
> blog):
> > content-security-policy: default-src https: 'unsafe-eval' data:;
> > report-uri https://twitter.com/scribes/csp_report; img-src https: data:;
> > script-src https://*.twitter.com https://*.twimg.com https://*.vine.co https://ssl.google-analytics.com 'unsafe-eval';
> > frame-src https://* chrome-extension: about: javascript:

Actually, chrome extension pages displayed through iframes are loaded even though the CSP doesn't explicitly allow the chrome-extension scheme. Take for instance github's CSP:

> default-src *; 
> script-src assets-cdn.github.com collector-cdn.github.com; 
> object-src assets-cdn.github.com; 
> style-src 'self' 'unsafe-inline' 'unsafe-eval' assets-cdn.github.com; 
> img-src 'self' data: assets-cdn.github.com identicons.github.com www.google-analytics.com collector.githubapp.com *.githubusercontent.com *.gravatar.com *.wp.com; 
> media-src 'none'; 
> frame-src 'self' render.githubusercontent.com gist.github.com www.youtube.com player.vimeo.com checkout.paypal.com; font-src assets-cdn.github.com; 
> connect-src 'self' ghconduit.com:25035 live.github.com uploads.github.com www.google-analytics.com s3.amazonaws.com

It does not say anything about chrome extensions, yet chrome loads web-accessible pages through iframes on github.

Quoting the CSP specs (more specifically this section: http://www.w3.org/TR/CSP/#processing-model)
> Enforcing a CSP policy should not interfere with the operation of user-supplied scripts such as third-party user-agent add-ons and JavaScript bookmarklets.

it looks like chrome implementation is the right one. As a side note, safari allows the display of extension pages through iframes, but such iframes are blocked when injected in pages like github.
This is something that would be very useful for our application. It doesn't make sense that I can't add 
"permissions": {
    "cross-domain-content": ["resource://blahblahblah"]
  },
  
to the package.json file to allow the iframe to load. All code is managed by the extension.
I was just pinged on this bug by Jared Smith of the webAIM project[1]. They are hitting this bug when they want to enhance the WAVE toolbar accessibility testing tool[2], effectively not allowing them to implement features they can easily implement in the Chrome equivalent of that extension. So, this is definitely a parity bug with Chrome, and we should address it soon'ish.

Therefore asking to get moving on this again if possible.

[1] http://webaim.org
[2] http://wave.webaim.org/toolbar/
Flags: needinfo?(gkrizsanits)
Flags: needinfo?(dtownsend)
I'm quite busy with e10s, so I don't think I will have time to work on this any time soon. This bug seems to need an owner preferably someone who knows a bit about protocol handlers or have the time to learn about them.
Flags: needinfo?(gkrizsanits)
Unfortunately we have no resources to work on this right now.
Flags: needinfo?(dtownsend)
(In reply to Marco Zehe (:MarcoZ) from comment #57)
> I was just pinged on this bug by Jared Smith of the webAIM project[1].

Marco, you should direct them to the forum: http://forums.mozilla.org/ or the #extdev IRC channel. There are probably ways to work around this limitation, though they are probably not as simple.
Hey guys, I work on TrueKey (Password Manager) and getting this fixed would solve our issue with the add-on we're writing to support Firefox. Without this resolved, we will not be able to provide robust support for Firefox.
(In reply to stanislav_venzerul from comment #61)
> Hey guys, I work on TrueKey (Password Manager) and getting this fixed would
> solve our issue with the add-on we're writing to support Firefox. Without
> this resolved, we will not be able to provide robust support for Firefox.

I think we have something at least something like this with moz-extension:// in WebExtensions. Bill, is this ready for people to use? Please let me know if there's someone else I should direct WebExtensions questions to.
Flags: needinfo?(wmccloskey)
(In reply to Bobby Holley (:bholley) from comment #62)
> (In reply to stanislav_venzerul from comment #61)
> > Hey guys, I work on TrueKey (Password Manager) and getting this fixed would
> > solve our issue with the add-on we're writing to support Firefox. Without
> > this resolved, we will not be able to provide robust support for Firefox.
> 
> I think we have something at least something like this with moz-extension://
> in WebExtensions. Bill, is this ready for people to use? Please let me know
> if there's someone else I should direct WebExtensions questions to.

We're already written a fairly complex and extensive portion of our extension using the add-on SDK, so waiting for and rewriting our code to use WebExtensions would be very costly and quite inefficient. We'd much prefer to have one of the patches in this thread applied to FF, or for lack of that, settle for a sensible work around.
> (In reply to Bobby Holley (:bholley) from comment #62)
> > (In reply to stanislav_venzerul from comment #61)
> > > Hey guys, I work on TrueKey (Password Manager) and getting this fixed would
> > > solve our issue with the add-on we're writing to support Firefox. Without
> > > this resolved, we will not be able to provide robust support for Firefox.
> > 
> > I think we have something at least something like this with moz-extension://
> > in WebExtensions. Bill, is this ready for people to use? Please let me know
> > if there's someone else I should direct WebExtensions questions to.
> 
> We're already written a fairly complex and extensive portion of our
> extension using the add-on SDK, so waiting for and rewriting our code to use
> WebExtensions would be very costly and quite inefficient. We'd much prefer
> to have one of the patches in this thread applied to FF, or for lack of
> that, settle for a sensible work around.

I ran into the same problem. My solution was to create a custom resource handler for the iframes. This solution has two parts:

1) Use a set base url for extension iFrames (e.g., "extension-id://url_here").
2) Code a resource protocol that converts the above URLs to "resource://extension-id/url_here".

This allows you to side step this problem. The code I used to accomplish this can be found at https://bitbucket.org/snippets/mathflair/7RbbE . You will need to change the extension id to match your extension id. Also, I limit acceptable urls to ones in the public folder, so you will probably want to remove that check.

If you have any questions, let me know.
(In reply to Scott Ruoti from comment #64)
> > (In reply to Bobby Holley (:bholley) from comment #62)
> > > (In reply to stanislav_venzerul from comment #61)
> > > > Hey guys, I work on TrueKey (Password Manager) and getting this fixed would
> > > > solve our issue with the add-on we're writing to support Firefox. Without
> > > > this resolved, we will not be able to provide robust support for Firefox.
> > > 
> > > I think we have something at least something like this with moz-extension://
> > > in WebExtensions. Bill, is this ready for people to use? Please let me know
> > > if there's someone else I should direct WebExtensions questions to.
> > 
> > We're already written a fairly complex and extensive portion of our
> > extension using the add-on SDK, so waiting for and rewriting our code to use
> > WebExtensions would be very costly and quite inefficient. We'd much prefer
> > to have one of the patches in this thread applied to FF, or for lack of
> > that, settle for a sensible work around.
> 
> I ran into the same problem. My solution was to create a custom resource
> handler for the iframes. This solution has two parts:
> 
> 1) Use a set base url for extension iFrames (e.g.,
> "extension-id://url_here").
> 2) Code a resource protocol that converts the above URLs to
> "resource://extension-id/url_here".
> 
> This allows you to side step this problem. The code I used to accomplish
> this can be found at https://bitbucket.org/snippets/mathflair/7RbbE . You
> will need to change the extension id to match your extension id. Also, I
> limit acceptable urls to ones in the public folder, so you will probably
> want to remove that check.
> 
> If you have any questions, let me know.

Yep, tried this approached several times. It fails on sites with somewhat restrictive CSP's like twitter.com or dropbox.com. The iframe itself is loaded, but the content is just a blank html document. 
If you wish, I can attach the code for the little test add-on I have to reproduce the problem.
Hmm, when I wrote this several months ago, I feel like it was working even on CSP protected pages.

Have you tried modifying the CSP headers and adding your iFrame's URI to the list of allowed sources?
Shameless bump. We could really use this in our app/extension. Right now our users have a degraded experience on Firefox because we aren't able to load an iframe from the extension bundle. :(
reply to stanislav_venzerul from comment #65)
> (In reply to Scott Ruoti from comment #64)
> > > (In reply to Bobby Holley (:bholley) from comment #62)
> > > > (In reply to stanislav_venzerul from comment #61)
> > > > > Hey guys, I work on TrueKey (Password Manager) and getting this fixed would
> > > > > solve our issue with the add-on we're writing to support Firefox. Without
> > > > > this resolved, we will not be able to provide robust support for Firefox.
> > > > 
> > > > I think we have something at least something like this with moz-extension://
> > > > in WebExtensions. Bill, is this ready for people to use? Please let me know
> > > > if there's someone else I should direct WebExtensions questions to.
> > > 
> > > We're already written a fairly complex and extensive portion of our
> > > extension using the add-on SDK, so waiting for and rewriting our code to use
> > > WebExtensions would be very costly and quite inefficient. We'd much prefer
> > > to have one of the patches in this thread applied to FF, or for lack of
> > > that, settle for a sensible work around.
> > 
> > I ran into the same problem. My solution was to create a custom resource
> > handler for the iframes. This solution has two parts:
> > 
> > 1) Use a set base url for extension iFrames (e.g.,
> > "extension-id://url_here").
> > 2) Code a resource protocol that converts the above URLs to
> > "resource://extension-id/url_here".
> > 
> > This allows you to side step this problem. The code I used to accomplish
> > this can be found at https://bitbucket.org/snippets/mathflair/7RbbE . You
> > will need to change the extension id to match your extension id. Also, I
> > limit acceptable urls to ones in the public folder, so you will probably
> > want to remove that check.
> > 
> > If you have any questions, let me know.
> 
> Yep, tried this approached several times. It fails on sites with somewhat
> restrictive CSP's like twitter.com or dropbox.com. The iframe itself is
> loaded, but the content is just a blank html document. 
> If you wish, I can attach the code for the little test add-on I have to
> reproduce the problem.

Stanislav, I took some time to modify the snippet I had written in order to handle the CSP problem (https://bitbucket.org/snippets/mathflair/7RbbE). I've tested and verified that it works and does what you want. Once note, if you are using relative URLS in your iframe, it will treat the top level folder (in my case /public) as the domain, and thus won't go to the root resource URL. So all files referenced will need to be in an outware facing location.

Scott
(In reply to Scott Ruoti from comment #68)
> reply to stanislav_venzerul from comment #65)
> > (In reply to Scott Ruoti from comment #64)
> > > > (In reply to Bobby Holley (:bholley) from comment #62)
> > > > > (In reply to stanislav_venzerul from comment #61)
> > > > > > Hey guys, I work on TrueKey (Password Manager) and getting this fixed would
> > > > > > solve our issue with the add-on we're writing to support Firefox. Without
> > > > > > this resolved, we will not be able to provide robust support for Firefox.
> > > > > 
> > > > > I think we have something at least something like this with moz-extension://
> > > > > in WebExtensions. Bill, is this ready for people to use? Please let me know
> > > > > if there's someone else I should direct WebExtensions questions to.
> > > > 
> > > > We're already written a fairly complex and extensive portion of our
> > > > extension using the add-on SDK, so waiting for and rewriting our code to use
> > > > WebExtensions would be very costly and quite inefficient. We'd much prefer
> > > > to have one of the patches in this thread applied to FF, or for lack of
> > > > that, settle for a sensible work around.
> > > 
> > > I ran into the same problem. My solution was to create a custom resource
> > > handler for the iframes. This solution has two parts:
> > > 
> > > 1) Use a set base url for extension iFrames (e.g.,
> > > "extension-id://url_here").
> > > 2) Code a resource protocol that converts the above URLs to
> > > "resource://extension-id/url_here".
> > > 
> > > This allows you to side step this problem. The code I used to accomplish
> > > this can be found at https://bitbucket.org/snippets/mathflair/7RbbE . You
> > > will need to change the extension id to match your extension id. Also, I
> > > limit acceptable urls to ones in the public folder, so you will probably
> > > want to remove that check.
> > > 
> > > If you have any questions, let me know.
> > 
> > Yep, tried this approached several times. It fails on sites with somewhat
> > restrictive CSP's like twitter.com or dropbox.com. The iframe itself is
> > loaded, but the content is just a blank html document. 
> > If you wish, I can attach the code for the little test add-on I have to
> > reproduce the problem.
> 
> Stanislav, I took some time to modify the snippet I had written in order to
> handle the CSP problem (https://bitbucket.org/snippets/mathflair/7RbbE).
> I've tested and verified that it works and does what you want. Once note, if
> you are using relative URLS in your iframe, it will treat the top level
> folder (in my case /public) as the domain, and thus won't go to the root
> resource URL. So all files referenced will need to be in an outware facing
> location.
> 
> Scott

Amazing! I'm gonna give it a go this week and come back with results. 

Thank you!
Flags: needinfo?(wmccloskey)
I hope the Firefox devs are paying attention to this thread... people are hacking their extensions with 350 lines of code in order to workaround something that can be done in one line in other browsers (Chrome, Safari).
After talking to Bill, it sounds like this is supported with WebExtensions, though there may be some CSP issues that need fixing (which Bill filed bug 1207394 for).

(In reply to lepolt from comment #70)
> I hope the Firefox devs are paying attention to this thread... people are
> hacking their extensions with 350 lines of code in order to workaround
> something that can be done in one line in other browsers (Chrome, Safari).

It can also be done in one line of code in Firefox, using WebExtensions, in exactly the same way. The poster in comment 63 indicated that he wasn't interested in using WebExtensions, which is why he needs a complex workaround.  Jetpack is still supported, but we're not adding complex new features to it.

If anyone here runs into issues doing this with WebExtensions (other than bug 1207394, which should get fixed soon), please file bugs.
Status: UNCONFIRMED → RESOLVED
Closed: 9 years ago
Resolution: --- → WORKSFORME
I'd rather not close this bug. We may eventually implement web_accessible_resources in Jetpack if enough people want it and if we can find someone to do the work.
Status: RESOLVED → REOPENED
Ever confirmed: true
Resolution: WORKSFORME → ---
Womp Womp. The recommended solution is to port to a brand new extension model :(. Perhaps we were a little late to the game, but we just spent a few months writing this one.
(In reply to Bobby Holley (busy) from comment #71)

> It can also be done in one line of code in Firefox, using WebExtensions, in
> exactly the same way.

except when you are trying to do anything on Android - or did the WebExtensions 
land in Android now?

Right now Android is rather frustrating dev experience, whatever I try to do
I end up studying bugzilla entries and workarounds.

Isn't it too early to ditch the Addon-SDK ?
(In reply to Thomas Oberndörfer from comment #0)
> While currently it is possible that a webpage can load resources like images
> from an addon the same does not applies to iframes: if an iframe with a src
> attribute of e.g. 'resource://<extension id>-at-jetpack/<extension
> name>/data/page.html' is added to a web page by a content script then a
> security error is raised.
> 
> In my scenario I scan web pages like webmail provider for encrypted
> messages. Once found, I place an overlay on top of the encrypted content and
> insert an iframe that will show a UI and finally the decrypted message. The
> motivation to use an iframe is:
> - the style should be separated from the outer page
> - security: as the iframe is from different origin the outer page cannot
> access its content

would sdk/panel work for that? Looks much easier and safer than injecting iframe
overlays on top of potentially hostile web pages. They can't directly read/modify 
your iframe but they can remove it or overlay with own content, maybe explore 
using canvass.
> except when you are trying to do anything on Android - or did the
> WebExtensions 
> land in Android now?

A limited amount of WebExtensions APIs are available on Android, specifically things that do not interact with the native Android UI. Feedback on how those APIs work is always appreciated.
Don't inject iframes into arbitrary webpages, it is broken and unsafe by design. For SDK addons "pannel" is easier to do and safer.

https://bugzilla.mozilla.org/show_bug.cgi?id=1287590
(In reply to Bobby Holley (:bholley) (busy with Stylo) from comment #71)
> After talking to Bill, it sounds like this is supported with WebExtensions,
> though there may be some CSP issues that need fixing (which Bill filed bug
> 1207394 for).
> 
> (In reply to lepolt from comment #70)
> > I hope the Firefox devs are paying attention to this thread... people are
> > hacking their extensions with 350 lines of code in order to workaround
> > something that can be done in one line in other browsers (Chrome, Safari).
> 
> It can also be done in one line of code in Firefox, using WebExtensions, in
> exactly the same way. The poster in comment 63 indicated that he wasn't
> interested in using WebExtensions, which is why he needs a complex
> workaround.  Jetpack is still supported, but we're not adding complex new
> features to it.
> 
> If anyone here runs into issues doing this with WebExtensions (other than
> bug 1207394, which should get fixed soon), please file bugs.

The use case of loading an iframe from a WebExtension is not working for me in Firefox.
After attaching an <iframe src="moz-extension://9bacc8fe-2bff-d84a-a124-747df2e48aa2/blank.html"> to the document and listing blank.html as web_accessible_resources I'm getting the following CSP violation:

Content Security Policy: The page’s settings blocked the loading of a resource at self (“script-src moz-extension://9bacc8fe-2bff-d84a-a124-747df2e48aa2”). Source: call to eval() or related function blocked by CSP.

Although the host page doesn't set any CSP header.
Thomas, do you mind filing a separate bug with your extension attached (and steps to reproduce if a particular site needs to be loaded) and ccing me on that bug?
Flags: needinfo?(thomas)
(In reply to Boris Zbarsky [:bz] (still a bit busy) (if a patch has no decent message, automatic r-) from comment #79)
> Thomas, do you mind filing a separate bug with your extension attached (and
> steps to reproduce if a particular site needs to be loaded) and ccing me on
> that bug?

Sorry, that was false alarm. The iframe loads just fine from a moz-extension URL. The CSP violation was triggered when attaching a Add-on SDK page-mod to this moz-extension iframe, but I think this use case is not relevant.
Flags: needinfo?(thomas)
https://bugzilla.mozilla.org/show_bug.cgi?id=1399562
Status: REOPENED → RESOLVED
Closed: 9 years ago7 years ago
Resolution: --- → INCOMPLETE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: