The feed protocol when combined with HTMLLinkElement elements creates ghost windows.

RESOLVED WORKSFORME

Status

()

Firefox
RSS Discovery and Preview
RESOLVED WORKSFORME
2 years ago
2 months ago

People

(Reporter: Jay Gilbert, Unassigned)

Tracking

({sec-other})

49 Branch
sec-other
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(1 attachment)

(Reporter)

Description

2 years ago
Created attachment 8760352 [details]
feedBasedGhostWindow-testcase-new.html

User Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
Build ID: 20160502172042

Steps to reproduce:

I loaded a normal content page with a HTMLLinkElement in the body of that content page.  This link element has a target attribute which is a named child of that content page and and the href attribute is as follows:

'feed:'+escape(document.location.href);

I then called the click method of the link element.


Actual results:

The link loads into a ghost window regardless of that state of that named child window and after the following error is shown in the global browser console:

NS_ERROR_MALFORMED_URI: Component returned failure code: 0x804b000a (NS_ERROR_MALFORMED_URI) [nsIIOService.newURI]

There is also an error that clearly shows that the feed handler tries to handle this load.


Expected results:

The load should have been stopped either when the NS_ERROR_MALFORMED_URI error was issued or depending on how we choose to handle the 'feed:' protocol at least loaded in the correct child window.

Comment 1

2 years ago
I played around with this for a bit, but I need to go take care of the rest of my life for today (just moved house).

I'm afraid I'm not creative enough to figure out how it breaks any security guarantees beyond just being really really weird. As far as I can tell, it allows you to do the following:

1) make a request through feed: to pages that are same-domain with the host of the parent of the iframe. So if you replace the escaped URI with something like "../foo.html", assuming that file exists in the parent of the dir, we will end up loading it into the iframe;
2) if the request doesn't return content, like a 404, we will not replace the currently loaded page. I tried loading a different page in the frame beforehand (ie assing to location from the js URL after setting the window name), in which case that other page just stays.

The same-origin qualifier is because if there is no full URI in the part following "feed:" we resolve relative to the base URI of the document, which boils down to:

Services.io.newURI(partialURI, null, baseURI);

which AIUI is always going to be same-host with baseURI.

If you do include a scheme in the URI the code from bug 1277583 will stop you. If you're already on a feed:http page (bug 1277697) then AFAICT we determine base URI stuff from the inner URI and so you don't actually expand the possibilities open to you, but I've not checked.

Based on that, this doesn't seem any better than loading arbitrary URLs into the iframe with 'normal' <a> links, except for the '404 detection' (which I haven't investigated in detail, but I presume is a function of the feed sniffer code that makes feed: URIs redirect so as to lose their "feed:" prefix).

Either way, the more I see of this, the more I'm tempted to just patch up bug 1277698 and kill off linking to feed: by non-chrome-privileged code entirely. :-\

Completely unrelated: I find it bizarre that HTML <link> elements are clickable. :-\
> except for the '404 detection'

For same-origin cases that can be done in lots of other ways too, yes?  Starting with XHR.

> Completely unrelated: I find it bizarre that HTML <link> elements are clickable. :-\

They're pretty similar to <a> in all sorts of ways, once you render them.
Oh, and in particular, I expect you can replace <link> with <a> in this bug's testcase with no change in behavior....  If not, that's odd.

Comment 4

2 years ago
(In reply to Boris Zbarsky [:bz] from comment #2)
> > except for the '404 detection'
> 
> For same-origin cases that can be done in lots of other ways too, yes? 
> Starting with XHR.

Yes, sorry, I was not explicit about this - I don't think that's a (security) problem per se, but it explains the fact that the link doesn't actually load in the testcase as-attached (and so the frame remains on 'about:blank'), which it would if you used 'normal' navigation directly - there are definitely other ways to avoid that if you were after that effect intentionally.
(Reporter)

Comment 5

2 years ago
I thought I should touch on this and state that I just filed this bug in case we hadn't caught something in bug 1277583.  I'll be focusing on things related to feed: and other self implemented pseudo protocols for the next work I do.

Let me understand this, because this is something that I actually *didn't* know about ff.  If a load is triggered in any way except directly for a child window, and this load has a response that means it's unavailable, we then don't show the content(of course you can't for a 404)?

I was getting a 403 Forbidden response, which does in fact serve up a response which is same origin.  That response still doesn't get shown in the child window.
(Reporter)

Comment 6

2 years ago
(In reply to :Gijs Kruitbosch from comment #1)
> The same-origin qualifier is because if there is no full URI in the part
> following "feed:" we resolve relative to the base URI of the document, which
> boils down to:
> 
> Services.io.newURI(partialURI, null, baseURI);
> 
> which AIUI is always going to be same-host with baseURI.
> 
> If you do include a scheme in the URI the code from bug 1277583 will stop
> you. If you're already on a feed:http page (bug 1277697) then AFAICT we
> determine base URI stuff from the inner URI and so you don't actually expand
> the possibilities open to you, but I've not checked.

I have already played quite a bit with manipulating this through the use of <base href=*/> and we seem solid so far.
 
> Either way, the more I see of this, the more I'm tempted to just patch up
> bug 1277698 and kill off linking to feed: by non-chrome-privileged code
> entirely. :-\

I think that would be the smart play.

Comment 7

2 years ago
(In reply to Jay Gilbert from comment #5)
> Let me understand this, because this is something that I actually *didn't*
> know about ff.  If a load is triggered in any way except directly for a
> child window, and this load has a response that means it's unavailable, we
> then don't show the content(of course you can't for a 404)?

FWIW, 404s would still quite often actually have 'error page, content not found' style content. 

> I was getting a 403 Forbidden response, which does in fact serve up a
> response which is same origin.  That response still doesn't get shown in the
> child window.

I haven't verified exactly how/when we do a redirect / show a response, and when we don't. I imagine this has to do with the feed and/or generic content type sniffer implementation. I looked for a bit just now, but I'm not at home in the relevant parts of the network stack and so I'm really not quite sure what triggers that behaviour, and what doesn't. Either way, so far it doesn't seem like you can actually make a request to a page that you couldn't make otherwise, which still limits the potential for abuse here.
(Reporter)

Comment 8

2 years ago
So far I agree but let's wait a little while longer before considering making this public.  I just feel that there's a lot of behavior here we don't fully understand.

Unexpected behavior is the first sign that something *may* be vulnerable.  It's better to be safe than sorry.

Making anything feed related only accessible by chrome needs to be done IMO.  I've been after a feed related vulnerability since reading over one found by moz_bug_r_a4.  It took me quite a while, but my point is unless something is changed with how feed related stuff is handled, this won't be the last vulnerability found.
Component: Untriaged → RSS Discovery and Preview
Keywords: sec-other

Updated

a year ago
Flags: needinfo?(gijskruitbosch+bugs)

Comment 9

a year ago
AFAICT this was addresed by bug 1277698.
Status: UNCONFIRMED → RESOLVED
Last Resolved: a year ago
Flags: needinfo?(gijskruitbosch+bugs)
Resolution: --- → WORKSFORME
Group: firefox-core-security
You need to log in before you can comment on or make changes to this bug.