New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 906636 link

Starred by 1 user

Issue metadata

Status: WontFix
Owner:
Closed: Jan 2
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 1
Type: Bug-Security
Team-Security-UX



Sign in to add a comment

Security: PWA security vulnerability report: PWA UI Design Flaw

Reported by user.pwa...@gmail.com, Nov 19

Issue description

VULNERABILITY DETAILS

Dear Chrome Team,
 
We're a security research group at Indiana University Bloomington. Recently we studied the Progressive Web App (PWA) implementation in Chrome and discovered one critical security flaw in its UI design affecting the latest version of Chrome (v70.0.3538.80 on Android 9). When exploiting the flaw, a malicious PWA can perform a phishing attack to steal victim users’ private or sensitive information (e.g., Google account credentials).

Background

In order to bring user an immersive experience, Chrome opens a PWA without any Chrome UI and the PWA takes up the entirety of the available display area (fullscreen) if the PWA is added to user’s homescreen and “standalone” or “fullscreen” are specified in the PWA’s manifest.json file [3]. 

Chrome displays a Prominent UI (a toolbar at the top of the screen showing the origin and secure connection status) to inform the PWA user when they are browsing out-of-scope URL (e.g., different origins) as shown in [5]. According to the PWA documentation[4], PWA users will rely on this Prominent UI of Chrome to know when he/she browses out-of-scope URL. This Prominent UI is an important security notice of Chrome.

The Security Flaw

Given the fact that a PWA is displayed in full screen, a malicious PWA could mimic the UI of any important security notice of Chrome, such as the Prominent UI mentioned above. A possible attack could take the following steps:

  1. A victim user launches a malicious PWA (of domain attack.com) and is to navigate off to out-of-scope domain Google/Facebook/Amazon for some reasonable business (e.g., single sign on, shopping).  
However, the malicious PWA indeed navigates the user to a phishing webpage (within the scope of the PWA) pretending to be Google/Facebook/Amazon.

  2. Upon navigation, the PWA could show a fake Prominent UI like the one in Figure 1, on behalf of Chrome, misleadingly informing the user that he/she is navigated to Google/Facebook/Amazon. It’s natural for the user to believe this Prominent UI is generated by Chrome. Consequently, the user incorrectly thinks he/she is navigated to Google/Facebook/Amazon, and leaks sensitive information (e.g., login credentials, personal or private information) to the phishing webpage.


There are two critical factors that make such an attack feasible:

  1.The genuine Prominent UI created by Chrome is hard for users to distinguish from the fake UI.

  2.PWA users cannot check the current domain in the fullscreen display due to the lack of address bar.  In contrast, in the “browser” display mode[3], which is not vulnerable to the attack, the current origin in the address bar is always available to users.

Reference:

[1] JavaScript Fullscreen API Security and Privacy Consideration,
https://fullscreen.spec.whatwg.org/#security-and-privacy-considerations

[2] PWA full screen Security,
https://www.w3.org/TR/appmanifest/#security-and-privacy-considerations


[3] Chrome display mode support,
https://developers.google.com/web/fundamentals/web-app-manifest/#display

[4] PWA Navigation out of scope,
https://www.w3.org/TR/appmanifest/#navigation-scope

[5] Promient UI of Chrome,
https://drive.google.com/file/d/1E1O9bY7OI_imHfr-w6LcbjJgObR_RkPl/view?usp=sharing


VERSION
Chrome Version: [70.0.3538.80] + [stable]
Operating System: [Android 9]

REPRODUCTION CASE

We attached a demo video to better demonstrate this problem.

Haoran Lu, Yifan Zhang, Luyi Xing, Xiaojing Liao
Indiana University Bloomington


 
PWA_UI_CONFUSION.mp4
8.9 MB View Download
Components: UI>Browser>Permissions>Prompts
Labels: Security_Severity-Medium Security_Impact-Stable OS-Android Pri-1
Owner: cthomp@chromium.org
Status: Assigned (was: Unconfirmed)
Assigning to cthomp@ for triage
Project Member

Comment 2 by sheriffbot@chromium.org, Nov 20

Labels: Target-71 M-71
Cc: cthomp@chromium.org
Owner: dominickn@chromium.org
Sorry for the delay -- passing this over to dominickn@ who is more familiar with PWA UX.
Components: UI>Browser>WebAppInstalls
Cc: benwells@chromium.org mgiuca@chromium.org
Thanks for the report.

This vulnerability boils down to: once installed, any PWA may phish the user because they are displayed without an omnibox.

We have a number of mitigations in place for this. Installing a PWA requires that the user explicitly consents to a prompt that contains the origin of the site, its title, and the icon. This consent stage must be triggered by a user gesture, and is regarded as the point of trust for the origin.

Once installed and running, standalone PWAs have a persistent notification in the system tray that shows their origin.

I agree that further improvements could be made to better disclose the origin of a running PWA. However, the existing UX has been deemed sufficient to protect the user - namely, there is an explicit trust step of installing the PWA, with the origin disclosure, that is required prior to any phishing attack being successful.
Thank you for the response. We think the system tray is still vulnerable to our attacks.

Based on our observation, through the persistent notification in the system tray, a PWA user has three ways to check the current browsing URL:

1. The “Open in Chrome” button. Tap the button to open the URL in Chrome browser and check the URL in the omnibox.
2. The “Share” button. Tap the button to share the URL through Android share Intent, and check the URL in the receiving Activity.
3. The “Tap to copy the URL of this app” notification area. Tap the area to copy the URL to the clipboard, then manually paste the URL somewhere (e.g., in a text editor) to check.

We find that the first way to check the current PWA URL is an unsound protection. Specifically, following the “Open in Chrome” button, once the current browsing URL of a PWA is opened in Chrome browser, the phishing PWA page can immediately redirect itself to the genuine domain (e.g., Google.com) as long as it detects through javascript API [1]  that it is opened in the browser. As a result, the omnibox in Chrome browser will display the genuine page’s URL and the user may still believe that the fake page opened in PWA is a genuine one. 

We argue that the second and third ways to check the current URL are hard to protect users from our phishing attacks. In both cases, the URL that the user sees could be the legitimate associated domain URL of the PWA (as long as the phishing is hosted on the index page of the domain). In the scenario of tapping “Share” button to share the PWA, the URL the user sees and shares is right the expected domain URL of the PWA (though the PWA is now displaying a fake Google page), and this sounds natural to normal users. Besides, the “Share” button is more naturally/likely used when users want to share the PWA to other users or apps, rather than when they want to inspect the current URL. Besides, in the third way when the user taps the “Tap to copy the URL for this app” notification area, he/she may not have the right expectation of what the copy-pasted URL should be (could either be the associated domain URL of the PWA or the current URL),  so the user will not be alerted when the URL is actually the associated domain URL of the PWA, in the situation of our phishing attacks.

The fundamental design pitfall 

We think that one fundamental design pitfall here is, given a PWA which takes the entirety of the display area, it’s practically misleading to users if Chrome is still designed to display important UI notice inside the display realm of the PWA in certain circumstances. Specifically, the users cannot tell whether the UI notice is from Chrome or the PWA. When this UI notice is for critical security notification (i.e., informing the current domain during off-scope navigation), such misleading will cause security consequences, e.g., our reported phishing attacks. 

Additionally, we also argue that, given the UI notice (the top bar, genuine or counterfeit) already showing the domain, normal users would not really go to the system tray to double check the domain being visited.

A suggested secure design principle 

It should be practically easy for users to judge whether any UI component inside the display area of PWA is owned by the PWA or Chrome. One possible implementation of this design principle could be, any UI component inside the display area of PWA should only be owned by the PWA. When Chrome wants to show users any critical UI notice, switch to Chrome’s own display area (e.g., Chrome’s UI activity or system notification created by chrome) and then display it. After the display, switch the users back to the PWA, so as to eliminate any breaking of the user experience.



Reference:

[1] Javascript API, https://www.w3.org/TR/appmanifest/#ex-8-example-8-const-standalone-matchmedia-display-mode-standalone-standalone-onchange-e-handle-changes-to-display-mode-if-standalone-matches-do-standalone-things

> A suggested secure design principle

I think this design principle is theoretically sound, but doesn't help much in practice. Any theoretically unspoofable UI helps us tell the user when they *aren't* being spoofed, but it doesn't notify users when they *are* being spoofed. The spoofing site can simply make something "close enough" to the legitimate UI and fool a large number of users.

> One possible implementation of this design principle could be, any UI component inside the display area of PWA should only be owned by the PWA. When Chrome wants to show users any critical UI notice, switch to Chrome’s own display area (e.g., Chrome’s UI activity or system notification created by chrome) and then display it.

What's to stop apps from spoofing this? If an app already has control of the entire screen, it can just emulate the browser UI. If Chrome delivers a notification when you switch to an out-of-scope site, a) the site could just use the notifications API to deliver its own fake notification, and b) even if they don't, they'll likely get away with it because only a very keen user will know to expect a notification and realise something's wrong when the notification isn't there.

The fundamental problem is that users don't notice when something is *missing*, only when something is *there*.

So while we acknowledge there is an issue (which we were already aware of), this is very difficult to properly mitigate without defeating the whole point of installable web apps. (And I'll note that this very issue is present for all types of native app as well.)
Thanks, mgiuca, for your response. We would like to make some clarification here.

Although a fullscreen app (native or standalone Web App) is known to be able to confuse users (simply make something "close enough" to the legitimate UI), the reasons and security implications were different from the problem we are reporting here. Specifically, Web App introduces a new layer of confusion, as elaborated below.

1. The OS has the responsibility to make users clear which is the app (or activity) running in the foreground. 
  a) Spoofing Type 1: users were confused which app they were running in the foreground (e.g., due to an Android flaw in [1]). When causes of such confusion were reported, the OS has the responsibility to fix them so that, users should always be clear which is the app running in the foreground. This type of spoofing is known.
  b) Spoofing Type 2: users clearly/correctly know the app they are running is app A, but A is displaying/spoofing UI of app B and can still fool a large number of users. This type of spoofing is trivial and known.


2. Now assume users reliably know which app (native or Web App) is running in the foreground (otherwise, the OS has the responsibility to fix the confusion). 
  a) Spoofing Type 3: users are confused about the ownership of UI components in (standalone) Web Apps, though they clearly know which Web App they are running. When Web App B shows a prominent UI notice or even spoofs browser UI, users assume/expect this prominent UI notice or browser UI may be owned/drawn by the real browser. This is the new layer of confusion introduced by Web App. Specifically, when users clearly know Web App B is running in the foreground, they still assume some UI components in B may still sometimes be owned by another native app (i.e., the browser). 
  b) Spoofing Type 3 does not apply in native apps. Any native app D (or D’s activity) exclusively owns and is responsible for all UI components (even if a chrome-like browser UI or a Facebook login UI) in it. There’s no confusion to the users all UI components displayed in D’s area are attributed to app D. 


Spoofing Type 3 is the type of spoofing we are reporting. We think Spoofing Type 3 is attributed to the improper implicit assumption in the design/implementation of (standalone) Web App that, the entire display area is not exclusively owned by Web App, since the browser still wants to reclaim some portion of the display area back in certain circumstances. This practice is different from native apps, where a native app is designed to have clear ownership of the entire display area.

Spoofing Type 1 requires the OS’s efforts to defeat, though sometimes hard to completely avoid. Spoofing Type 2 mainly affects less tech-savvy users and may call for the community’s further efforts. Spoofing Type 3 is introduced by Web Apps, and is also non-trivial to defeat. In this thread of report, we make our tentative suggestions for your review. In particular, the design practice could be, the (standalone) Web App should exclusively has the persistent full ownership of display area when the Web App is displayed. Besides, Web App users are aware of this practice and expect it (like users of native apps). When the browser needs to give users a critical notice, give it somewhere other than in Web App’s display area, and somewhere hard to counterfeit, such as in System Tray or in the browser’s own window. After the display of the critical notice, switch the user back to eliminate breaking of the user experience 

Please let us know if questions.

#8 Not true, Spoofing Type 3 can happen in native apps. Consider a native app for a service that uses Google Accounts for authentication. The native app shows a web view with https://accounts.google.com asking for the user's Google credentials. The user just has to take the native app's word for it that they are showing the real accounts.google.com and not a fake page.

Same thing happens when you click a news story from the Facebook native app, and it shows a Chrome Custom Tab UI containing the story on NY Times. You trust that Facebook is showing you the real NY Times website and not spoofing it, showing you a fake newspaper story.

Put another way, yes, the native app does own all the pixels and thus there is inherent trust when the user is shown an off-site login page within the native app. The same issue applies to web apps, but it's no better or worse than native apps in this regard. That's what I meant when I said "(And I'll note that this very issue is present for all types of native app as well.)"
Thanks, mgiuca. Please see our response below.

Your comment 1: “the native app does own all the pixels and thus there is inherent trust when the user is shown an off-site login page within the native app”  -- Agree. 

Your comment 2: “The same issue applies to web apps, but it's no better or worse than native apps in this regard.” -- This is not true.

When a UI component is displayed in a native app A, users naturally believe A exclusively owns the UI component. However, this is not the case for Web App users. Specifically, when a UI component (such as the off-scope navigation notice of Chrome) is displayed in a Web App B, normal users may be misled by the current practice of Web App that the User Agent owns (or always owns) such UI component. 

A security-sensitive and tech-savvy user may be aware that a Web App exclusively owns all its UI components, just like a native app. For such users, your comment 2 is true. However, we don’t believe the current practice and concept of Web App make normal users perceive Web App in the same way. For the concept of Web App, We still suggest the W3C Spec and the practice of User Agent together make sure users have a clearer understanding of ownership of UI components displayed inside Web App. 

#10:

> When a UI component is displayed in a native app A, users naturally believe A
> exclusively owns the UI component. However, this is not the case for Web App
> users. Specifically, when a UI component (such as the off-scope navigation
> notice of Chrome) is displayed in a Web App B, normal users may be misled by
> the current practice of Web App that the User Agent owns (or always owns) such
> UI component.

The assertion that users believe native apps exclusively own the UI while they think web apps share UI with the browser is false. Both native apps (at least on Android) and web apps have exactly the same controls in this regard:

- The application usually controls all the pixels.
- The application *can* ask the system to embed a third-party website in user-agent-controlled UI.
- The application could use its full control of all the pixels to spoof that user-agent-controlled UI.

There is literally no UI difference between a native app and an installed PWA in this regard (and that is rather the point).
Hi mgiuca,

Thanks for your response. 

We certainly agree that both a native app and an installed PWA can spoof users due to their control of all pixels. Following your example, both a native app and an installed PWA could use its full control of all the pixels to spoof that user-agent-controlled UI (e.g., User Agent’s activity). We do agree. 

However, the cause of different types of spoofing/confusion and who (the OS or the User Agent) is responsible to mitigate such spoofing/confusion deserve a clearer understanding here. When the spoofing happens because users are confused which app (or which app’s activity) is running in the foreground, we think the OS has at least the major responsibility to mitigate such confusion.  When the users clearly known which app (or which app’s activity) is running in the foreground, the spoofing happens because users are confused which app owns a portion of the foreground activity, e.g., in the case of our reported Web App spoofing, we think the User Agent at least shares the major responsibility to mitigate such type of confusion. 

We also acknowledge that even if both following two condition are met, spoofing could still affect many users especially those less tech-savvy users: (1) the OS makes sure identity of foreground app (or activity) is clear,  (2) some party (UA, OS, etc.) makes sure that any portion of foreground activity has clear ownership. Such a problem will itself call for solutions from the security community. Also, such a problem does not waive the OS and the UA’s respective responsibility to mitigate the discussed confusion.

Please let us know if questions.

Project Member

Comment 13 by sheriffbot@chromium.org, Dec 17

dominickn: Uh oh! This issue still open and hasn't been updated in the last 14 days. This is a serious vulnerability, and we want to ensure that there's progress. Could you please leave an update with the current status and any potential blockers?

If you're not the right owner for this issue, could you please remove yourself as soon as possible or help us find the right one?

If the issue is fixed or you can't reproduce it, please close the bug. If you've started working on a fix, please set the status to Started.

Thanks for your time! To disable nags, add the Disable-Nags label.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Project Member

Comment 14 by sheriffbot@chromium.org, Dec 31

dominickn: Uh oh! This issue still open and hasn't been updated in the last 28 days. This is a serious vulnerability, and we want to ensure that there's progress. Could you please leave an update with the current status and any potential blockers?

If you're not the right owner for this issue, could you please remove yourself as soon as possible or help us find the right one?

If the issue is fixed or you can't reproduce it, please close the bug. If you've started working on a fix, please set the status to Started.

Thanks for your time! To disable nags, add the Disable-Nags label.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Labels: -Restrict-View-SecurityTeam
Status: WontFix (was: Assigned)
As discussed above, this is a known problem with no complete solution, but several mitigations which are already in place. We're not planning to address it further in the short term. Marking as WontFix.

Sign in to add a comment