Closed Bug 1307857 Opened 8 years ago Closed 6 years ago

Element injection into about:feeds context could allow one to bypass sandboxing and possibly execute script.

Categories

(Firefox Graveyard :: RSS Discovery and Preview, defect)

49 Branch
defect
Not set
normal

Tracking

(Not tracked)

RESOLVED WONTFIX

People

(Reporter: jerri.rice.001, Unassigned)

Details

(Keywords: sec-other)

Attachments

(1 file)

User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0
Build ID: 20160919214112

Steps to reproduce:

I loaded a page with an onclick handler to open a data URI representing a rss feed.


Actual results:

When the page is clicked a page is opened with the about:feeds context, using < and > in the description tag of an item element I have injected html elements into this page.

Although not properly shown here even if the feed is loaded in a round about way(ie it has a null principal) the poster attribute of the video element loads while the image element injected raises a security error.


Expected results:

A security error should be issued for the load of the poster attribute on the video element.
I don't see a security error for either the image element or the poster, and both show up for me. This makes sense because both of them are in chrome://browser/skin/ which is web-accessible ( cf. bug 443400 ). Tested on both current nightly and 50 beta. What are you testing on and where are you seeing the error?

I'm not sure if HTML insertion this way is otherwise expected or no. It doesn't seem to be possible to insert script, or even links with JS URLs, so I'm assuming we're using the sanitizer and dumping stuff that doesn't make sense or shouldn't make it into the doc.
Component: Untriaged → RSS Discovery and Preview
Flags: needinfo?(jerri.rice.001)
I originally was loading the page either through forms or through a meta tag redirect, which gives it a null principal.  

I'll work on a modified testcase to show this in action here shortly.
Flags: needinfo?(jerri.rice.001)
I'm getting different results now, not trying with a form or meta tag redirect yet.

*looks at recent nightly changes*
Hmm I will get this back, I remember I was using nested elements at one point, and I still haven't went back to the meta tag redirection just because it's a headache to get to work right.

Anyway, I'm in the middle of a strange transition right now with all my luggage lost and a much more important bug to file relating to this imo.

Give me a little time :)

Hopefully important updates and that second bug by tomorrow afternoon.
Blocks: 1308090
(In reply to Jerri Rice from comment #3)
> I originally was loading the page either through forms or through a meta tag
> redirect, which gives it a null principal.

Odd. 

<iframe src="data:text/html,hi<img src='chrome://browser/skin/feeds/feedIcon.png'>" sandbox></iframe>


also gets the framed document a null principal, AIUI, and that also works without a security error in my setup. One could argue that we should stop content-accessible chrome from being loaded this way, though I'm not sure if fixing that would really do much good.
(In reply to :Gijs Kruitbosch from comment #6)
> (In reply to Jerri Rice from comment #3)
> > I originally was loading the page either through forms or through a meta tag
> > redirect, which gives it a null principal.
> 
> Odd. 
> 
> <iframe src="data:text/html,hi<img
> src='chrome://browser/skin/feeds/feedIcon.png'>" sandbox></iframe>
> 
> 
> also gets the framed document a null principal, AIUI, and that also works
> without a security error in my setup. One could argue that we should stop
> content-accessible chrome from being loaded this way, though I'm not sure if
> fixing that would really do much good.

With a null principal switch the image loaded to one remote like in bug 1308090.  There I use the favicon from google in a slight modification of the testcase here.  That should generate a security error.

If you were to then load that image as the poster attribute for a video it would load(this was the original issue here).

I was trying to combine that with capturing of the video image data and/or a canvas to see if data that should be blocked could in fact be accessed cross domain.
(In reply to Jerri Rice from comment #7)
> (In reply to :Gijs Kruitbosch from comment #6)
> > (In reply to Jerri Rice from comment #3)
> > > I originally was loading the page either through forms or through a meta tag
> > > redirect, which gives it a null principal.
> > 
> > Odd. 
> > 
> > <iframe src="data:text/html,hi<img
> > src='chrome://browser/skin/feeds/feedIcon.png'>" sandbox></iframe>
> > 
> > 
> > also gets the framed document a null principal, AIUI, and that also works
> > without a security error in my setup. One could argue that we should stop
> > content-accessible chrome from being loaded this way, though I'm not sure if
> > fixing that would really do much good.
> 
> With a null principal switch the image loaded to one remote like in bug
> 1308090.  There I use the favicon from google in a slight modification of
> the testcase here.  That should generate a security error.

Why? Loading http:// images from null principals is allowed. Ditto for content-accessible chrome:// ones.
Flags: sec-bounty?
(In reply to :Gijs Kruitbosch from comment #8)
> (In reply to Jerri Rice from comment #7)
> > (In reply to :Gijs Kruitbosch from comment #6)
> > > (In reply to Jerri Rice from comment #3)
> > > > I originally was loading the page either through forms or through a meta tag
> > > > redirect, which gives it a null principal.
> > > 
> > > Odd. 
> > > 
> > > <iframe src="data:text/html,hi<img
> > > src='chrome://browser/skin/feeds/feedIcon.png'>" sandbox></iframe>
> > > 
> > > 
> > > also gets the framed document a null principal, AIUI, and that also works
> > > without a security error in my setup. One could argue that we should stop
> > > content-accessible chrome from being loaded this way, though I'm not sure if
> > > fixing that would really do much good.
> > 
> > With a null principal switch the image loaded to one remote like in bug
> > 1308090.  There I use the favicon from google in a slight modification of
> > the testcase here.  That should generate a security error.
> 
> Why? Loading http:// images from null principals is allowed. Ditto for
> content-accessible chrome:// ones.

I took this to be because the about:feeds context is used as the principal that gets checked before the load happens, but I'm not sure how you tested it.  Either way I'll be focusing on the feed reader implementation in ff for now I guess, it seems fruitful so far.

I wish I could provide more useful info, but I'm down to a single chromebook and even getting the source to build on it is proving tricky.  Better debugging tools than gdb would also be nice, but that might just be me lacking skills with it.  Not for much longer though :)
Ok, I'm retouching on this issue after remembering that I was at the time nesting <source> elements for the video load, as well as using the <picture> container element for an image load trailing the video.  Hopefully one of these proves to be fruitful.

I'm going to be cross testing this in release and nightly builds too, because I can't quite remember if I was working only in the nightly build.

For now I still think this demonstrates behavior we don't want(null principal loading remote content).
Wait why is it that we do in fact allow this?  I was misunderstandwaing something obviously.  If a load has occured in such a way that it is in fact loading with a null principal why should we allow loading of remote content?  CSRF done as images is the first thing that pops into my mind here, but I havent tested that to see if cookies are in fact sent.

Do we handle the loading of content from a null principal in any special way in regards to cookies being included with requests?
(In reply to Jerri Rice from comment #11)
> Wait why is it that we do in fact allow this?  I was misunderstandwaing
> something obviously.  If a load has occured in such a way that it is in fact
> loading with a null principal why should we allow loading of remote content?
> CSRF done as images is the first thing that pops into my mind here, but I
> havent tested that to see if cookies are in fact sent.
> 
> Do we handle the loading of content from a null principal in any special way
> in regards to cookies being included with requests?

I expect that the answer is that we allow whatever we allow for 'normal' web pages in terms of <img> and <script> (though the latter presumably gets stripped from feeds) sourcing because any web page can request an image or script from anywhere, and so presumably so can a null-principal'd thing. Whether we send cookies - again, I would assume we do whatever we do for the rest of the web. Maybe Christoph knows more.
Flags: needinfo?(ckerschb)
Please keep in mind that in web terms "null principal" means "sandboxed iframe" or "data: URL loaded in toplevel tab".

So yes, they can load images.  Yes, cookies will get sent for subresource loads.  These things are not special.

You seem to be imbuing "null principal" with restrictions it just doesn't have.  It just means "untrusted (in the sense that any web page is untrusted) origin distinct from any URL-based origin".
No longer blocks: 1308090
So an add campaign that loads adds using a data URI could in fact be fairly sure that a person was logged into a certain site then use CSRF/XSRF for some request regarding GET data to achieve a compromise..  hmm interesting.  I know that it's the site's responsibility to guard against this, still though when we choose to to hold the end user's hands and when we don't rarely makes sense to me.

It doesn't seem the best way to go in terms of security, but there is a spec for a reason :)
(In reply to Boris Zbarsky [:bz] (still a bit busy) from comment #13)

> You seem to be imbuing "null principal" with restrictions it just doesn't
> have.  It just means "untrusted (in the sense that any web page is
> untrusted) origin distinct from any URL-based origin".

This could allow one to launch any number of XSS/XSRF based attacks without even an origin for the attack being able to be traced.  Seems a little off to me but we go with the flow in the end.
We definitely need a rework of the about:feeds setup because if one could even get one event handler to execute in the <description> section, priviledge escalation could be just one click, one load, even one scroll away.  The current setup filters input as the page loads, but after the load anything that executes can change things around.

I personally have been trying to get a handler to execute that sets a global window click handler which does in fact have the ability to load anything priviledged.

Just an FYI for anybody seeing this, there is just such a tiny layer of protection involved here.  I'm switching focus for now but will come back here before I'm done for sure.
(In reply to Jerri Rice from comment #16)
> We definitely need a rework of the about:feeds setup because if one could
> even get one event handler to execute in the <description> section,
> priviledge escalation could be just one click, one load, even one scroll
> away.  The current setup filters input as the page loads, but after the load
> anything that executes can change things around.
> 
> I personally have been trying to get a handler to execute that sets a global
> window click handler which does in fact have the ability to load anything
> priviledged.

Can you clarify what you mean here with "anything privileged"? The page is unprivileged as far as AboutRedirector.cpp, so it shouldn't be able to do anything a web page can't do. As I noted earlier, the chrome:// URI you initially used is content-accessible, so being able to load it in an <img> container is not surprising. I'm fairly sure it's all running in the right compartment, so it shouldn't be possible to privilege escalate to anything more than that...
window.onclick = (function(){ open('about:preferences', 'pWin'); return true;})

Put that in the web console for the about:feeds page loaded from this testcase.  Click, it loads it with no issues at all.  This was my original reason for this bug and the work here.

It seems soo close to exploitable especially with element injection into the feed and the continuing addition of new html elements without the code filtering this input changing to account for those changes.
For those interested the flow of how about:feeds works is as this:

An xml page with the mime type to indicate a feed is indicated as the next load ->
The code behind about:feeds parses this input into an xhtml+xml form ->
This code then sanitizes input and tries to ensure any elements act like <iframe sanbox=""> ->
Page loads the input in this fashion, while the page itself seems to retain elevated priviledges.

This is dangerous imo, and with the evolution of the html spec I can only see this not being exploitable for a short time.  The poster attribute used here was supposed to show this( I can't get the same errors, but the poster attribute is not filtered in any way.)
(In reply to Jerri Rice (rehash pending) from comment #19)
> For those interested the flow of how about:feeds works is as this:
> 
> An xml page with the mime type to indicate a feed is indicated as the next
> load ->
> The code behind about:feeds parses this input into an xhtml+xml form ->
> This code then sanitizes input and tries to ensure any elements act like
> <iframe sanbox=""> ->

We use the tree sanitizer. This is also used on about:reader (reader mode pages). It's supposed to be conservative about allowing stuff through. Of course, it's always possible we're still allowing something that could be malicious...

> Page loads the input in this fashion, while the page itself seems to retain
> elevated priviledges.

I don't think this is true. In non-e10s, in the browser console, when about:feeds is loaded, content.document.nodePrincipal is a codebase principal (ie like www.foo.com) rather than the system principal.

(In reply to Jerri Rice (rehash pending) from comment #18)
> window.onclick = (function(){ open('about:preferences', 'pWin'); return
> true;})

This works for about: pages but not chrome:// ones, right? I believe this is because you're already on an about: page and that's the scheme of the URI of the principal, so about: pages can link to other about: pages. You still shouldn't be able to touch anything in that window because of compartments, though.

This is another place that would benefit from a fix based on bug 1305012 to downgrade all the way to null principal. The other defense-in-depth thing we can/should do is make URI_SAFE_FOR_UNTRUSTED_CONTENT about: pages not be able to link to other about: pages that *aren't* URI_SAFE_FOR_UNTRUSTED_CONTENT (like about:preferences ). I'm a bit surprised that this works as-is. It looks like that's a regression from bug 1253673. I'll file a separate bug for that...
(In reply to :Gijs Kruitbosch from comment #20)
> The other defense-in-depth thing we
> can/should do is make URI_SAFE_FOR_UNTRUSTED_CONTENT about: pages not be
> able to link to other about: pages that *aren't*
> URI_SAFE_FOR_UNTRUSTED_CONTENT (like about:preferences ). I'm a bit
> surprised that this works as-is. It looks like that's a regression from bug
> 1253673. I'll file a separate bug for that...

bug 1309310
Ignore the ds, apparently I'm far too dependent on spellcheck. hmm

Will check back in on this later, then time for a rehash of everything.

I honestly didn't try this with chrome:// yet but I'll assume that is in fact locked down.  One thing I was playing with though that isn't even filtered is linking to about:home which isn't blocked while if you try to link to say about:preferences it filters that out.  

I wont post any details about what could be possibly be done with that, but I can see it leading to privilege escalation with a few simple tweaks/steps.  That's work for another time.

Opening a privileged page is usually one part one to a full exploit.  There's multiple vectors to get there through about:feeds.

Also you should note that if you use a meta redirect to data loaded into about:feeds then it has a null principal so the code base principal concept doesn't apply then.  Just referesh my memory but that's not anything to worry about though since one null principal can't even access another null principal right?

I think that does prove my point about the very thin layer of security here.  I did in fact at one point have the poster attribute loading something that the image that follows it wouldnt.  I'm going to test if I can link to about:preferences in the poster attribute but I predict that failing(it's part of an elements attributes which behaves as sandoxed.)

Hope all that makes sense and I should have pointed that out originally when posting this bug, the title implies that is what I was aiming for though.  My bad guys.
(In reply to Jerri Rice (rehash pending) from comment #22)
> Ignore the ds, apparently I'm far too dependent on spellcheck. hmm
> 
> Will check back in on this later, then time for a rehash of everything.
> 
> I honestly didn't try this with chrome:// yet but I'll assume that is in
> fact locked down.  One thing I was playing with though that isn't even
> filtered is linking to about:home which isn't blocked while if you try to
> link to say about:preferences it filters that out.  
> 
> I wont post any details about what could be possibly be done with that, but
> I can see it leading to privilege escalation with a few simple tweaks/steps.
> That's work for another time.
> 
> Opening a privileged page is usually one part one to a full exploit. 

You're using "privileged" in the broad sense here. Neither about:home nor about:feeds are privileged in the strict sense of the word. They have an "about:" URI, but neither has chrome privileges. about:preferences *is* privileged in the strict sense of the word (has chrome privileges). All the chrome-privileged stuff on about:home (opening options / bookmarks etc.) is done by code not part of the about:home window itself. Same stuff for e.g. network error pages which live on about:neterror/about:certerror.

While I would like to make all about: pages except about:blank unlinkable from the web, unfortunately there are various blockers to that.

All of this is just about even being able to open a(nother) window/frame with a page. Web content shouldn't have script access to windows that have any kind of about: page loaded (except of course about:blank, which is special/weird). So far that restriction hasn't been bypassed in any of these bugs, right?

> There's multiple vectors to get there through about:feeds.

Well... so far no working way to actually run script on about:feeds, right? Using the web console doesn't really count. :-)

Can you expand on what specifically you mean by "multiple vectors" ?

> Also you should note that if you use a meta redirect to data loaded into
> about:feeds then it has a null principal so the code base principal concept
> doesn't apply then.  Just referesh my memory but that's not anything to
> worry about though since one null principal can't even access another null
> principal right?

Correct. null principal is less privileged than codebase principal, so from that perspective there's not really a whole lot you could gain from that.

> I think that does prove my point about the very thin layer of security here.
> I did in fact at one point have the poster attribute loading something that
> the image that follows it wouldnt.  I'm going to test if I can link to
> about:preferences in the poster attribute but I predict that failing(it's
> part of an elements attributes which behaves as sandoxed.)

I would hope that the sanitizer strips that out, yes, or that otherwise the security checks forbid it, yes.
Just to be clear even though  I didn't want to give out details, clickjacking to a top level about:home window is one of the multiple vectors there.  I have work on file showing clickjacking as a valid tihing in firefox already.

See the associated bug for a 47 loading of about:feeds which I think very clearly shows that without the regression here things would still be one simple action away from escalation.  BTW yes I do consider loading any page chrome privileged to be privilege escalation.
(In reply to :Gijs Kruitbosch from comment #12)
> I expect that the answer is that we allow whatever we allow for 'normal' web
> pages in terms of <img> and <script> (though the latter presumably gets
> stripped from feeds) sourcing because any web page can request an image or
> script from anywhere, and so presumably so can a null-principal'd thing.
> Whether we send cookies - again, I would assume we do whatever we do for the
> rest of the web. Maybe Christoph knows more.

Since Boris answered that question in Comment 13, I think my ni? became superfluous.
Flags: needinfo?(ckerschb)
At this point this bug seems to be a catalog of things that you find surprising, but not any actual exploitable condition. I'm not sure what we're supposed to "fix" based on this bug. rating it 'sec-other' for now to get it off the triage list. If we get a vulnerability then please clear that (or ask someone to do so in #security) and we can re-evaluate.
Keywords: sec-other
I'll be going back over this again soon, I like to fully explore things before moving on so I'm more familiar with whats going on when I pick it back up.  I'll let you know anything exploitable, but also just keep listing interesting things so this can stay a list as sec-other if nothing major comes.

about:feeds is a good place to target from what I've seen, I just haven't took major time to pull it apart.
going to pass on a bug bounty on this one for now. If it does trigger an interesting find you'll most likely want to file a new bug to get a fresh start so the devs don't have to skip the first 28 comments on this one to figure out what's going on. In any case you can write us to request a bounty.
Flags: sec-bounty? → sec-bounty-
Per policy at https://wiki.mozilla.org/Bug_Triage/Projects/Bug_Handling/Bug_Husbandry#Inactive_Bugs. If this bug is not an enhancement request or a bug not present in a supported release of Firefox, then it may be reopened.
Status: UNCONFIRMED → RESOLVED
Closed: 6 years ago
Resolution: --- → INACTIVE
Product: Firefox → Firefox Graveyard
Resolution: INACTIVE → WONTFIX
Group: firefox-core-security
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: