Firefox Lite Address Bar Spoofing with Secure Lock using Back Button or Forward Button
Categories
(Emerging Markets Graveyard :: Security: Firefox Lite, defect)
Tracking
(Not tracked)
People
(Reporter: sourc7, Assigned: st3fan)
Details
(Keywords: csectype-spoof, reporter-external, sec-moderate)
Attachments
(3 files, 1 obsolete file)
|
569.47 KB,
text/html
|
Details | |
|
513.81 KB,
video/mp4
|
Details | |
|
3.95 KB,
patch
|
Details | Diff | Splinter Review |
After pressing the back button, Firefox Lite was too early to set the address bar to the previous webBackForwardList. Therefore the address bar has been changed earlier than the the actual page (out of sync).
The vulnerable code is at app/src/main/java/org/mozilla/focus/fragment/BrowserFragment.kt:1005 with following code:
private fun goBack() {
val currentTab = sessionManager.focusSession
if (currentTab != null) {
val current = currentTab.engineSession?.tabView
// The Session.canGoBack property is mainly for UI display purpose and is only sampled
// at onNavigationStateChange which is called at onPageFinished, onPageStarted and
// onReceivedTitle. We do some sanity check here.
if (current == null || !current.canGoBack()) {
return
}
val webBackForwardList = (current as WebView).copyBackForwardList()
val item = webBackForwardList.getItemAtIndex(webBackForwardList.currentIndex - 1)
updateURL(item.url)
current.goBack()
}
The updateURL(item.url) was updated the address bar, before the browser successfully navigate to the destination address.
With the above vulnerability, I able to spoof the address bar with secure lock using back button functionality.
By using onbeforeunload event handler, after press back button Firefox Lite will prompts the user before unloading, if user choose "Stay on This Page" Firefox Lite will stay on the website, but the address bar has been updated to previous website at webBackForwardList.
Steps to reproduce:
- Visit attached backspoof. bundle.html
- Tap "Start Spoof" button
- Tap "Login with Google" link
- You'll navigated to real Google Login page
- After ~2 second, you'll redirected back to backspoof page
- Tap "Login with Google" link
- After alert message appears, tap "Ok"
- Press back button
- Tap "Stay On This Page"
- Address bar successfully spoofed
| Reporter | ||
Comment 1•5 years ago
|
||
Updated•5 years ago
|
| Assignee | ||
Comment 2•5 years ago
|
||
I haven't looked in detail but my first thought is: why do we call updateURL() there instead of waiting for one of the callbacks to happen.
Thank you Irvan - will explore more. Not entirely sure if this will roll into the release with the other fix. It may have to be a followup patch.
| Reporter | ||
Comment 3•5 years ago
|
||
(In reply to Stefan Arentz | :st3fan | ⏰ EST | he/him from comment #2)
I haven't looked in detail but my first thought is: why do we call
updateURL()there instead of waiting for one of the callbacks to happen.
After I removed the updateURL(item.url) then attach DevTools to emulate slow network to the tab, I notice after I press back there are no progress bar & the address bar stayed on current website.
Since there are no progress bar (feedback) after press back button, it confuse the user whether they already press the button. So I think the developer call updateURL() in order to give user feedback they already press the back button. But doing so is unsafe, it vulnerable to address bar spoofing.
I think we can follow Firefox for Android behavior, by replacing updateURL() with a progress bar call in order to give feedback to the user.
| Assignee | ||
Comment 4•5 years ago
|
||
Thank you Irvan. This bug is on our radar. I just want to let you know now that we will not ship this together with the fix for your previous report. That one will go out in the coming days and then we will address this one separately. Thank you for the submission!
| Assignee | ||
Comment 5•5 years ago
|
||
Verified this bug to valid.
I have a patch in a private branch that just removes the updateURL() calls from both goBack() and goForward(). This properly prevents the spoofing but it can result in a slower update of the location bar.
| Reporter | ||
Comment 6•5 years ago
|
||
(In reply to Stefan Arentz | :st3fan | ⏰ EST | he/him from comment #5)
Verified this bug to valid.
Thanks Stefan for the update.
I have a patch in a private branch that just removes the
updateURL()calls from bothgoBack()andgoForward(). This properly prevents the spoofing but it can result in a slower update of the location bar.
I've created a patch to replace updateURL() with progress bar update to mitigate the vulnerability:
if (isLoading && progress_bar.progress == 100) {
progress_bar.progress = 20
}
I hope the code follow Firefox's behavior, after pressing the back button a progress bar will appear to provide feedback to the user.
I'm currently still testing this, I hope the progress bar update patch is reliable as expected.
| Reporter | ||
Comment 7•5 years ago
|
||
(In reply to Stefan Arentz | :st3fan | ⏰ EST | he/him from comment #5)
Verified this bug to valid.
I have a patch in a private branch that just removes the
updateURL()calls from bothgoBack()andgoForward(). This properly prevents the spoofing but it can result in a slower update of the location bar.
Gotcha! It turns out we doesn't need to replace updateURL() with force progress bar update.
Below are the main reason the progress bar not immediately appear after press back button:
On the FocusWebChromeClient.javait already listen to WebChromeClient => onProgressChanged, after press back button it will notify a progress update to BrowserFragment.kt on function onProgress, but it's odd the progressIsForLoadedUrl condition check is cancelling the UI progress bar update.
After remove the progressIsForLoadedUrl condition check, the progress bar is appear after we press the back button (similar to Firefox behavior). 👍
| Assignee | ||
Comment 8•5 years ago
|
||
Thank you so much for exploring the root cause of this issue. We really appreciate the time you put in this to go beyond just the bug report.
I am going to play around a bit with your suggestion and see how we can ship that as an update.
| Reporter | ||
Comment 9•5 years ago
|
||
So far so good, I feel the progress bar is now synced with WebChromeClient onProgressChanged callback.
| Reporter | ||
Comment 10•5 years ago
|
||
When figuring out the reason behind progressIsForLoadedUrl condition check is exist, I found this commit description Don't update page progress if the page is already loaded added on Oct 23, 2017.
The code author said on the code comment "Some new url may give 100 directly and then start from 0 again. don't treat", but after removing the condition check I haven't encountered the mentioned issue.
I'm not sure this related or not, I found some people on StackOverflow said WebView sometimes run onPageFinished callback more than 1 times on older Android API, so after removing the condition check it worth to test the usability using older Android API.
Updated•5 years ago
|
| Reporter | ||
Comment 11•5 years ago
|
||
After further testing, the code author comment were right, without progressIsForLoadedUrl condition check the progress bar will be updated more frequently than expected (e.g. on url fragment), also cause progress bar to race (e.g. on Google Search).
Gladly I've improve the condition check to solve the issue, hereby the patch changelog:
- Allows back button and forward button to update the progress bar (it now sync with
WebChromeClient->onProgressChanged) - Prevent progress bar update on URL fragment (follow Chrome and Firefox for Android behavior)
- Also fixes the progress bar sometimes stuck at loading state (solve issue on current Firefox Lite)
| Reporter | ||
Updated•5 years ago
|
| Assignee | ||
Comment 12•4 years ago
|
||
Irvan, apologies for the silence. We plan to ship this fix very soon. I am working on getting the patches in shape to get it out asap.
| Reporter | ||
Comment 13•4 years ago
|
||
(In reply to Stefan Arentz | :st3fan | ⏰ EST | he/him from comment #12)
Irvan, apologies for the silence. We plan to ship this fix very soon. I am working on getting the patches in shape to get it out asap.
Thank you Stefan for the update, I'm glad to hear that! 👍
Comment 14•4 years ago
•
|
||
Verified as fixed on the FF Lite latest 2.6.1(20652) WebView 89.0.4389.90 (provided by Stefan) with Google Pixel 4 XL (Android 11) and Samsung Galaxy S7 (Android 7).
Note that following the steps from the description everything works as expected.
| Assignee | ||
Comment 15•4 years ago
|
||
This is shipping today to 25%. We'll keep an eye on it and then go to 100% later this week.
Updated•4 years ago
|
Updated•4 years ago
|
| Assignee | ||
Updated•4 years ago
|
| Assignee | ||
Comment 16•4 years ago
|
||
Since this shipped, I am marking this as ASSIGNED/RESOLVED. Will soon publish the CVE in the Github project.
Updated•4 years ago
|
| Reporter | ||
Comment 17•4 years ago
|
||
(In reply to Stefan Arentz | :st3fan | ⏰ EST | he/him from comment #16)
Since this shipped, I am marking this as ASSIGNED/RESOLVED. Will soon publish the CVE in the Github project.
Thanks Stefan, I also confirmed this has been fixed on Firefox Lite 2.6.1(20652) (installed from Google Play Store) with WebView version 89.0.4389.105.
Comment 18•4 years ago
|
||
Thanks for reporting this, Irvan. We've awarded a bounty for this one but we've also now end-of-lifed Firefox Lite. If your interest is in bug bounties I urge you to switch to looking at one of our other browsers. Firefox for Android (Fenix) might be most similar to this project, and of course Firefox for desktop is our flagship browser.
| Reporter | ||
Comment 19•4 years ago
|
||
(In reply to Daniel Veditz [:dveditz] from comment #18)
Thanks for reporting this, Irvan. We've awarded a bounty for this one but we've also now end-of-lifed Firefox Lite. If your interest is in bug bounties I urge you to switch to looking at one of our other browsers. Firefox for Android (Fenix) might be most similar to this project, and of course Firefox for desktop is our flagship browser.
Thanks a lot Dan for the bounty. Yes after reporting this bug, Tom also told me the same (that Firefox Lite is in process of end of life), so afterward I focused on finding bugs in Firefox for Desktop.
Updated•4 years ago
|
Updated•1 year ago
|
Description
•