(In reply to Alex Gaynor [:Alex_Gaynor] from comment #0)
UXSS -> privesc via sync (install arbitrary extensions & set arbitrary preferences)
I'm sure there is other interesting settings which lead to a full sandbox escape.
Not a sandbox escape, but rather if a signin can be forced by an attacker, then the attacker can exfiltrate any data already saved on the device that would be synced, e.g., bookmarks and passwords.
(In reply to Ryan Kelly [:rfkelly] from comment #11)
I guess we'd need to simply block iframing accounts.firefox.com for the time being? Would that break anything?
We used to allow certain trusted origins to iframe accounts.firefox.com (via some awful code to generate X-Frame-Options and friends on-the-fly) but I believe all those integrations have been removed. I can't think of any legitimate reason for a site to be loading accounts.firefox.com in an iframe. Shane?
Firefox <= 60 still uses the iframe on the firstrun page. See https://github.com/mozilla/bedrock/issues/6837. We can ask :agibson and team to prioritize switching to the new page.
(In reply to Ryan Kelly [:rfkelly] from comment #3)
I wonder if we have enough information when dispatching the WebChannel message
here [...] to detect that it's coming from an iframe or other unexpected source
:pauljt talked through this with me a bit, and it doesn't sound like there's much we could do here; if the child process is sufficiently compromised then it can make itself indistinguishable from a "good" login page.
I think the right path forward on the FxA front is Bug 1538024, removing the ability for web content to sign the browser in to sync.
As the referred to bug title says, the key is not barring web content from being part of the signin process, but rather allowing FxA to modify the signed in state of Sync "silently". If FxA is in an isolated process and WebChannel messages are sent back to a trusted process, then it seems like the trusted process should be able to show the user some UX confirming the user wants to connect to Sync as user XXX@YYY.ZZZ.
(In reply to Paul Theriault [:pauljt] from comment #12)
(In reply to Ryan Kelly [:rfkelly] from comment #11)
Right, it's not iframing specific -- I just meant there's always two pieces: 1) loading the origin in it's own process, 2) not loading it in any other process :-)
Actually I think there might be THREE things here (cue spanish inquistion intro) :
- loading the origin in it's own process
- Not loading the the origin in another process
- Not loading ANY other web content in the Firefox accounts process
Do I understand correctly that this means only allowing connections to https://accounts.firefox.com from the privileged process? If so, we are going to have to undertake a re-architecture of FxA to move everything to a single domain. Currently https://accounts.firefox.com is only used to serve HTML and do a bit of metrics gathering. Static JS is served from a CDN at https://accounts-static.cdn.mozilla.net. Authentication related calls are made to https://api.accounts.firefox.com, OAuth related calls go to https://oauth.accounts.firefox.com, a user's profile is stored at https://profile.accounts.firefox.com, a user's profile photo is stored at https://firefoxusercontent.com so that invalid images cannot be used as an attack vector.
WebChannel architecture may provides this already though? I'm not sure if the approprate listeners are only created for a process that is loading accounts.firefox.com, or if this listener is setup for every process. IE can any content process just synthesize a login message, and not worry about loading accounts.firefox.com at all?.
IIRC, WebChannel listeners are created at startup and can be sent from any page, however every WebChannel has to specify an originOrPermission from which to accept messages . If a WebChannel message is sent from an unrecognized origin, it's ignored. WebChannels are created on startup to prevent race conditions in channel creation whenever a tab to https://accounts.firefox.com is loaded. I may have this wrong though and WebChannels are created on a per-tab basis. :markh should be able to chim in more here.
From a quick check, it looks like FxA stores a bunch of data in LocalStorage, but changing it doesn't seem to affect state
We do store a user's session state in localStorage, for Firefox Desktop's < 55  and any non-Firefox desktop browser. In Firefox Desktop >= 55, whenever FxA loads we send a WebChannel request to the browser to ask which user is signed in to Sync. If a user is signed in to Sync, then that info will be shared with FxA for subsequent signings. If no user is signed in, then we read the last signed in user from localStorage. For Firefox < 55 and any non Firefox Desktop browser, we always read a user's session state from localStorage.
We also store "verification state" in localStorage, this is used to customize the UX depending on whether a user verifies their email in the same browser in which they sign up in. For OAuth flows, the same verification info is used to help redirect the appropriate tab back to an OAuth relying party whenever a user verifies their email address.
 - https://searchfox.org/mozilla-central/rev/56705678f5fc363be5e0237e1686f619b0d23009/toolkit/modules/WebChannel.jsm#155
 - https://github.com/mozilla/fxa-content-server/blob/da94f530c8b5bb7477e207944ea0c6623af2f710/app/scripts/lib/channels/web.js#L18