Closed
Bug 1043110
Opened 10 years ago
Closed 9 years ago
an appropriate way to prevent forbidden pages to be embedded in a widget iframe
Categories
(Core Graveyard :: DOM: Apps, defect)
Tracking
(firefox42 fixed)
RESOLVED
FIXED
mozilla42
Tracking | Status | |
---|---|---|
firefox42 | --- | fixed |
People
(Reporter: CuveeHsu, Assigned: CuveeHsu)
References
Details
(Whiteboard: [ft:conndevices])
Attachments
(3 files, 11 obsolete files)
2.64 KB,
patch
|
CuveeHsu
:
review+
|
Details | Diff | Splinter Review |
2.57 KB,
patch
|
CuveeHsu
:
review+
|
Details | Diff | Splinter Review |
10.64 KB,
patch
|
CuveeHsu
:
review+
|
Details | Diff | Splinter Review |
If a widget iframe navigates to pages which are not listed in widgetPages, we should prevent forbidden pages to be embedded in a widget. We want an appropriate way to react the forbidden navitgation.
Updated•10 years ago
|
Whiteboard: [FT:Stream3]
Assignee | ||
Updated•10 years ago
|
Assignee: nobody → juhsu
Assignee | ||
Updated•9 years ago
|
Component: General → DOM: Apps
Product: Firefox OS → Core
Updated•9 years ago
|
Whiteboard: [FT:Stream3] → [ft:conndevices]
Assignee | ||
Updated•9 years ago
|
Blocks: conn_priority
Assignee | ||
Comment 1•9 years ago
|
||
WIP: test case Simply set source to a invalid page Besides, I do some refactor
Assignee | ||
Comment 2•9 years ago
|
||
WIP this patch doesn't match the test WIP patch and need some polish And causes false positive when the src is not in |widgetPages| Need to investigate.
Assignee | ||
Comment 3•9 years ago
|
||
For mozWidget, display a load error if we navigate to a page which is not claimed in |widgetPages|. Hello bz, May I have your review? Thanks.
Attachment #8624134 -
Attachment is obsolete: true
Attachment #8633364 -
Flags: review?(bzbarsky)
Assignee | ||
Comment 4•9 years ago
|
||
This test doesn't work since displayLoadError doesn't dispatch a |mozbrowsererror|. Will implement in another patch. (In reply to Junior [:junior] from comment #1) > Created attachment 8589513 [details] [diff] [review] > WIP: test > > WIP: test case > Simply set source to a invalid page > > Besides, I do some refactor
Assignee | ||
Comment 5•9 years ago
|
||
Dispatch a mozbrowsererror event when one navigates to an invalid src
Attachment #8634000 -
Flags: review?(kchen)
Assignee | ||
Comment 6•9 years ago
|
||
Test for navigation issue on mozWidget Wait for the review for previous parts
Attachment #8589513 -
Attachment is obsolete: true
Comment 7•9 years ago
|
||
Comment on attachment 8633364 [details] [diff] [review] Part1: display_error_if_navigate_to_invalid_src - v1 Sorry for the lag here.... >+ rv = aURI->SchemeIs("about", &isAbout); >+ if (!isAbout) { You need to check NS_SUCCEEDED/NS_FAILED(rv) before touching isAbout. I don't have a strong opinion as to whether failure should be treated as "about" or "not about". >+ nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(frameElement); This is just a complicated way of checking for an HTML <iframe>, right? frameElement->IsHTMLElement(nsGkAtoms::iframe") is clearer as a test. But... We don't really want to run this code in random iframes on the web that have a "mozwidget" attribute. I guess it would end up kinda working out because GetAppByLocalId will return null for the "no app id" case, but it's a little annoying to depend on that. Furthermore, don't we have to pay attention to the "dom.enable_widgets" preference somewhere here? Is there a reason that GetReallyIsWidget() does the wrong thing here? Or can we use it? I have to admit to not being very up on what the whole widget/browserframe setup is... >+ aURI->GetSpec(spec); Having to serialize the URI like that is a bit annoying, but ok. That said, won't this likely prevent data: URI loads? Do we want to do that, or should those succeed like about: loads succeed? I'd like to get the actual behavior we're after nailed down here, but in general this looks pretty good.
Attachment #8633364 -
Flags: review?(bzbarsky) → feedback+
Assignee | ||
Comment 8•9 years ago
|
||
(In reply to Boris Zbarsky [:bz] from comment #7) > Comment on attachment 8633364 [details] [diff] [review] > Part1: display_error_if_navigate_to_invalid_src - v1 > > Sorry for the lag here.... > > >+ rv = aURI->SchemeIs("about", &isAbout); > >+ if (!isAbout) { > > You need to check NS_SUCCEEDED/NS_FAILED(rv) before touching isAbout. I > don't have a strong opinion as to whether failure should be treated as > "about" or "not about". > The reason I didn't check if |SchemeIs| success or not is we've checked in http://lxr.mozilla.org/mozilla-central/source/docshell/base/nsDocShell.cpp#10531 I bailed out here since non-mozWidget case will trigger |DisplayLoadError| -> |InternalLoad| -> |DoURILoad(about:neterror...|, and |about:neterror| is always not a valid src. I need a condition to avoid recursive condition to infinitely call |DoURILoad| Or you still want to have a check here? > >+ nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(frameElement); > > This is just a complicated way of checking for an HTML <iframe>, right? > frameElement->IsHTMLElement(nsGkAtoms::iframe") is clearer as a test. But... > My idea here is to identify if it's a mozBrowser iframe (i.e. <iframe mozbrowser>) > We don't really want to run this code in random iframes on the web that have > a "mozwidget" attribute. I guess it would end up kinda working out because > GetAppByLocalId will return null for the "no app id" case, but it's a little > annoying to depend on that. Furthermore, don't we have to pay attention to > the "dom.enable_widgets" preference somewhere here? My bad, I need to check permission and preference again. That would also check if the embedder is an app or not I guess. Will check in next version. > > Is there a reason that GetReallyIsWidget() does the wrong thing here? Or > can we use it? I have to admit to not being very up on what the whole > widget/browserframe setup is... |GetReallyIsWidget| doesn't work because |DisplayLoadError| will not change src in |HTMLGeneralFrameElement|. Maybe I should cook out a refactor or some helper to make things easy to use and more intuitive. I'll file a follow-up bug. > > >+ aURI->GetSpec(spec); > > Having to serialize the URI like that is a bit annoying, but ok. > > That said, won't this likely prevent data: URI loads? Do we want to do > that, or should those succeed like about: loads succeed? We like to prevent navigating to src not in |widgetPages| claimed in manifest to avoid information leak. Briefly, |mozWidget| is proposed to be embedded in privileged app, thus causing us to have some restriction, such as limited navigation, limited browser API. SchemeIs('about') is only a sugar to prevent recursion. > > I'd like to get the actual behavior we're after nailed down here, but in > general this looks pretty good. Thanks for your review!
Flags: needinfo?(bzbarsky)
Updated•9 years ago
|
Attachment #8634000 -
Flags: review?(kchen) → review+
Comment 9•9 years ago
|
||
> is we've checked in > http://lxr.mozilla.org/mozilla-central/source/docshell/base/nsDocShell.cpp#10531 Nothing requires a URI implementation to consistently throw or not throw from SchemeIs. And if it throws you're reading a random boolean. So please do check. > My idea here is to identify if it's a mozBrowser iframe (i.e. <iframe mozbrowser>) Then the QI is not the right way to do it. All <iframe> elements QI to nsIMozBrowserFrame. You presumably need to check GetReallyIsBrowserOrApp() too, right? > Maybe I should cook out a refactor or some helper to > make things easy to use and more intuitive. That would be lovely. > We like to prevent navigating to src not in |widgetPages| claimed in manifest OK. I'm fine with them; just figured I should point out that it prevents things some people might expect to work ;)
Flags: needinfo?(bzbarsky)
Assignee | ||
Comment 10•9 years ago
|
||
https://treeherder.mozilla.org/#/jobs?repo=try&revision=562f26bcdc59
Assignee | ||
Comment 11•9 years ago
|
||
Here I use |nsIDocShell::GetIsApp()| to check if this docshell is an app or not, and find a way to use |GetReallyIsApp| instead of copying a dup logic. I know |GetReallyIsApp| is a little ambiguous. Maybe we should rename to |GetReallyIsAppOrWidget|.
Attachment #8633364 -
Attachment is obsolete: true
Attachment #8637113 -
Flags: review?(bzbarsky)
Assignee | ||
Comment 12•9 years ago
|
||
Rebase and carry r+
Attachment #8634000 -
Attachment is obsolete: true
Attachment #8637114 -
Flags: review+
Assignee | ||
Comment 13•9 years ago
|
||
Rebase. Wait for previous patches r+'ed
Attachment #8634007 -
Attachment is obsolete: true
Comment 14•9 years ago
|
||
Comment on attachment 8637113 [details] [diff] [review] Part1: display_error_if_navigate_to_invalid_src - v2 >+ // Once navigate to an invalid mozWidget page, trigger |displayLoadError| and >+ // load an about:neterror, which is also an invalid mozWidget page. To avoid >+ // recursion, we skip to check if aURI is of |about:| scheme. How about: When we go to display a load error for an invalid mozWidget page, we will try to load an about:neterror page, which is also an invalid mozWidget page. To avoid recursion, we skip this check if aURI's scheme is "about". That said, I assume we also want this for about:blank, right, not just about:neterror... and do we really want to allow other about: pages here? Maybe it would be best to just explicitly check for about:neterror and about:blank? >+ // widget. We want to check if the widget comes to an invalid page. (This "We want to check whether the widget is trying to navigate to an invalid page."? >+ if (browserFrame && !browserFrame->GetReallyIsApp()) { So the point here is that GetReallyIsApp will return false for widgets but true for apps while nsIDocShell::GetIsApp will return true for both? Or is the logic something else? The comments aren't actually making it clear why this check is the right one. r=me with those bits addressed
Attachment #8637113 -
Flags: review?(bzbarsky) → review+
Assignee | ||
Comment 15•9 years ago
|
||
(In reply to Boris Zbarsky [:bz] from comment #14) > Comment on attachment 8637113 [details] [diff] [review] > Part1: display_error_if_navigate_to_invalid_src - v2 > > >+ // Once navigate to an invalid mozWidget page, trigger |displayLoadError| and > >+ // load an about:neterror, which is also an invalid mozWidget page. To avoid > >+ // recursion, we skip to check if aURI is of |about:| scheme. > > How about: > > When we go to display a load error for an invalid mozWidget page, we will > try > to load an about:neterror page, which is also an invalid mozWidget page. To > avoid recursion, we skip this check if aURI's scheme is "about". > > That said, I assume we also want this for about:blank, right, not just > about:neterror... and do we really want to allow other about: pages here? > Maybe it would be best to just explicitly check for about:neterror and > about:blank? > What we are afraid of is leaking information in the "mozWidget". Therefore, it doesn't matter if we allow about:blank or not. But is there any elegant way to check aURI is about:neterror? If we serialize the |aURI| to check if |aURI->spec| has prefix "neterror", it's a little annoying and highly depends to the implementation of |displayLoadError|. > >+ // widget. We want to check if the widget comes to an invalid page. (This > > "We want to check whether the widget is trying to navigate to an invalid > page."? > > >+ if (browserFrame && !browserFrame->GetReallyIsApp()) { > > So the point here is that GetReallyIsApp will return false for widgets but > true for apps while nsIDocShell::GetIsApp will return true for both? Or is > the logic something else? The comments aren't actually making it clear why > this check is the right one. It's a bit ambiguous as I mentioned :( |nsIDocShell::GetIsApp| is decided as the frameLoader start to load this docshell, returning true for both mozApp and mozWidget. And this value doesn't change during the lifecycle of the frame. |GetReallyIsApp| delegates the check to |nsGenericHTMLFrameElement|, which will dynamically check the manifest/permission/preference/validity of src, returning true iff a frame is a mozApp or mozWidget at that time. But generally manifest/permission/preference do not change during the life time of the frame, hence an app frame is always valid; an widget frame becomes invalid when navigate to invalid page. Moreover, privileged app is able to embed widget. What we really concern is leaking the information of an "widget app" to a third-party app. To conclude: |nsIDocShell:GetIsApp| returning true means the docshell acts as an app/widget. We should care about the information leakage. Therefore, we check |GetReallyIsApp| to see if the app is still valid, and the only case |GetReallyIsApp| returning false is that it's a widget app and navigates to a invalid page. Maybe I should put the bug number to the code comment. Will update a WIP for reference. > > r=me with those bits addressed
Flags: needinfo?(bzbarsky)
Assignee | ||
Comment 16•9 years ago
|
||
Update per review command, carry r+
Attachment #8637113 -
Attachment is obsolete: true
Attachment #8638444 -
Flags: review+
Assignee | ||
Comment 17•9 years ago
|
||
Rebase, carry r+
Attachment #8637114 -
Attachment is obsolete: true
Attachment #8638445 -
Flags: review+
Assignee | ||
Comment 18•9 years ago
|
||
Comment on attachment 8637116 [details] [diff] [review] Part3: test-v2 Previous patches are r+'ed, I guess it's time for a review. Fabrice, could I have your review? Thanks.
Attachment #8637116 -
Flags: review?(fabrice)
Comment 19•9 years ago
|
||
> Therefore, it doesn't matter if we allow about:blank or not. I was thinking in terms of it possibly breaking widgets if loading about:blank is not allowed. But if the goal is to prevent information leakage, then that should be clearly documented in this code. In that situation, loading about:anything is probably fine. I wish we consistently used the URI_IS_LOCAL_RESOURCE protocol flag, since that would have the right meaning here, but about: URIs don't have it set. :( Maybe file a followup bug about that? In any case, with the clear documentation about what the goal is, just checking for about: is OK. But I still think allowing loading about:blank should be part of that goal and explicitly mentioned in the comment. > Maybe I should put the bug number to the code comment The bug number can be found via the blame. I would much rather the code comment summarized the intent of the code. So is the goal to prevent both widgets _and_ apps from navigating to URIs that are not valid, not just to prevent widgets from navigating? If so, then the code in the patch makes a lot more sense. If the goal is to only affect widgets but not apps, then I'm not clear on what's going on here.
Flags: needinfo?(bzbarsky) → needinfo?(juhsu)
Assignee | ||
Comment 20•9 years ago
|
||
(In reply to Boris Zbarsky [:bz] from comment #19) > > Therefore, it doesn't matter if we allow about:blank or not. > > I was thinking in terms of it possibly breaking widgets if loading > about:blank is not allowed. > > But if the goal is to prevent information leakage, then that should be > clearly documented in this code. In that situation, loading about:anything > is probably fine. I wish we consistently used the URI_IS_LOCAL_RESOURCE > protocol flag, since that would have the right meaning here, but about: URIs > don't have it set. :( Maybe file a followup bug about that? I'm not familiar with with protocol handler, bug I guess URI_DANGEROUS_TO_LOAD is an appropriate flag. So the question is: should "about:" protocol never hits the network to let it be with URI_IS_LOCAL_RESOURCE? But on the other hands, it's hard to have a flag to check if the page is valid for a mozWidget since the forbidden list depends on manifest and and the manifestURL, which is beyond the scope of "protocol handler" I guess. > > In any case, with the clear documentation about what the goal is, just > checking for about: is OK. But I still think allowing loading about:blank > should be part of that goal and explicitly mentioned in the comment. Sure, will try to have a clear comment for what we did now and what the intention was. > > > Maybe I should put the bug number to the code comment > > The bug number can be found via the blame. I would much rather the code > comment summarized the intent of the code. > > So is the goal to prevent both widgets _and_ apps from navigating to URIs > that are not valid, not just to prevent widgets from navigating? If so, > then the code in the patch makes a lot more sense. If the goal is to only > affect widgets but not apps, then I'm not clear on what's going on here. Let me rephrase. The goal of this bug is to affect widgets only. However, I think it works to generalize to apps and widgets, although this patch does not have impact on apps _now_. If an app possibly loses its validity of app in the future, this patch is able to prevent the navigation.
Flags: needinfo?(juhsu) → needinfo?(bzbarsky)
Assignee | ||
Comment 21•9 years ago
|
||
Modify comments, carry r+
Attachment #8638444 -
Attachment is obsolete: true
Attachment #8639217 -
Flags: review+
Comment 22•9 years ago
|
||
> bug I guess URI_DANGEROUS_TO_LOAD is an appropriate flag URI_DANGEROUS_TO_LOAD is a security flag. It can be set whether LOCAL_RESOURCE is set or not. > it's hard to have a flag to check if the page is valid for a mozWidget We shouldn't be trying to do that. For the actual checking for URIs we want to check for, the approach in the patch is fine; I'm just talking about the "about:" whitelisting in the patch. > although this patch does not have > impact on apps _now_. If an app possibly loses its validity of app in the future, > this patch is able to prevent the navigation. OK. Please just make sure this is clearly documented.
Flags: needinfo?(bzbarsky)
Comment 23•9 years ago
|
||
Comment on attachment 8637116 [details] [diff] [review] Part3: test-v2 Review of attachment 8637116 [details] [diff] [review]: ----------------------------------------------------------------- r=me with nit addressed ::: dom/apps/tests/file_test_widget.js @@ +42,5 @@ > domParent.appendChild(ifr); > > + ifr.addEventListener("mozbrowserloadend", function _onloadend() { > + ok(true, "receive mozbrowserloadend"); > + // ifr.removeEventListener("mozbrowserloadend", _onloadend); remove commented out code.
Attachment #8637116 -
Flags: review?(fabrice) → review+
Assignee | ||
Comment 24•9 years ago
|
||
Rebase, carry r+
Attachment #8639217 -
Attachment is obsolete: true
Attachment #8640412 -
Flags: review+
Assignee | ||
Comment 25•9 years ago
|
||
Rebase, carry r+
Attachment #8638445 -
Attachment is obsolete: true
Attachment #8640413 -
Flags: review+
Assignee | ||
Comment 26•9 years ago
|
||
Rebase and modify by review comment, carry r+
Attachment #8637116 -
Attachment is obsolete: true
Attachment #8640414 -
Flags: review+
Assignee | ||
Updated•9 years ago
|
Keywords: checkin-needed
Comment 27•9 years ago
|
||
can we get a try run here ? thanks!
Flags: needinfo?(juhsu)
Keywords: checkin-needed
Assignee | ||
Comment 28•9 years ago
|
||
https://treeherder.mozilla.org/#/jobs?repo=try&revision=26e924f96385
Assignee | ||
Updated•9 years ago
|
Keywords: checkin-needed
Comment 30•9 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/031cc887765e https://hg.mozilla.org/integration/mozilla-inbound/rev/623942e8b052 https://hg.mozilla.org/integration/mozilla-inbound/rev/fb2a33f119cd
Keywords: checkin-needed
Comment 31•9 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/031cc887765e https://hg.mozilla.org/mozilla-central/rev/623942e8b052 https://hg.mozilla.org/mozilla-central/rev/fb2a33f119cd
Status: NEW → RESOLVED
Closed: 9 years ago
status-firefox42:
--- → fixed
Flags: in-testsuite+
Resolution: --- → FIXED
Target Milestone: --- → mozilla42
Updated•7 years ago
|
Product: Core → Core Graveyard
You need to log in
before you can comment on or make changes to this bug.
Description
•