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

Issue 724967 link

Starred by 1 user

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 3
Type: Bug



Sign in to add a comment

Navigating to another page does not reset silent lock state

Reported by xis...@gmail.com, May 22 2017

Issue description

VULNERABILITY DETAILS
When the users click the button using requestPointerLock() API, the browser pops up the message prompt "press esc to show your cursor". But the PointerLock prompt message can be hidden.

VERSION
Chrome Version: 58.0.3029.110+[Stable], 60.0.3100.0+[Canary]
Operating System: [Windows/MAC]

REPRODUCTION CASE

lock.html works on http(s):// or file:// 
(1)Click button "pointerlock"
(2)Click button "pointerlock1"
 
lock.html
452 bytes View Download

Comment 1 by wfh@chromium.org, May 22 2017

Components: UI>Browser>Permissions Blink>Input>PointerLock
Labels: Security_Severity-Medium Security_Impact-Stable OS-All Pri-2
Owner: mgiuca@chromium.org
Status: Assigned (was: Unconfirmed)
cool demo! I can repro this. matt can you take a look?

Comment 2 by xis...@gmail.com, May 23 2017

I think the pop-up prompt message should have the orgin from the lock.html URL shown. Such as "evil.com - press esc to show your cursor"

http://example.com/1.html

===1.html===
<iframe src="http://www.evil.com/lock.html"></iframe>
===1.html===

Comment 3 by mgiuca@chromium.org, May 23 2017

#2: Not sure how that's relevant (since the bug is the popup doesn't show at all). We decided to remove the origin from the prompt in 2015 since it doesn't help you make an informed decision about whether to stay in pointer lock (since there is no privacy issue, just the annoyance of not having access to your cursor, so it doesn't make a difference whether an iframe took the lock or the outer frame).

Confirmed the original issue. I was also able to dig down and realise that it's the location.replace (or location.assign) that causes this. It doesn't actually have to be empty quotes -- you can do any navigation and the pointer lock message will not show after the navigation. I've modified the example to do the attack across two pages. To repro using my files:

1. Load lock.html (file:// works).
2. Click "pointerlock". It navigates to lock1.html.
3. Click "pointerlock1".
lock.html
262 bytes View Download
lock1.html
233 bytes View Download

Comment 4 by mgiuca@chromium.org, May 23 2017

Cc: scheib@chromium.org
Investigation of the code flow for the second button click (on the second page):
- ExclusiveAccessManager::GetExclusiveAccessExitBubbleType is returning NONE on that second page.
- This is because MouseLockController::IsMouseLockedSilently() is returning true.
- This is because MouseLockController::RequestToLockMouse() is being called with last_unlocked_by_target=true.
- This can be traced all the way back to the renderer: MouseLockDispatcher keeps an instance variable |unlocked_by_target_| that tracks whether the lock has been voluntarily released, and sends it to the browser in an IPC message which ends up being passed as |last_unlocked_by_target| to MouseLockController::RequestToLockMouse ( Issue 725365 ).
- MouseLockDispatcher has global lifetime (per renderer), and its state persists across navigations if they are on the same renderer.
- MouseLockDispatcher is owned by RenderWidget, which has the same lifetime.

The fix is we need to have the RenderWidget delete and recreate the MouseLockDispatcher on navigation.

Comment 5 by mgiuca@chromium.org, May 23 2017

Summary: Security: Navigating to another page does not reset silent lock state (was: Security: Hide PointerLock prompt message)

Comment 6 by mgiuca@chromium.org, May 23 2017

It turns out this is really hard (maybe impossible without refactoring) because RenderWidget knows nothing about navigation. The Mojo team is trying to get rid of it apparently. :(
Project Member

Comment 7 by sheriffbot@chromium.org, May 23 2017

Labels: M-59
Project Member

Comment 8 by sheriffbot@chromium.org, May 23 2017

Labels: -Pri-2 Pri-1

Comment 9 by scheib@chromium.org, May 23 2017

Cc: chongz@chromium.org dtapu...@chromium.org

Comment 10 by kenrb@chromium.org, May 23 2017

re #6: It's not strictly true that RenderWidget knows *nothing* about navigation. When a non-same-page navigation commits, RenderFrameImpl calls RenderWidget::IncrementContentSourceId() which effectively tells the RenderWidget that a navigation has occurred (ContentSourceId is used in the browser process to link compositor frames to page loads).

Would it work to generalize that method a bit, so that in addition to incrementing the ContentSourceId, it also re-created the MouseLockDispatcher?

I haven't looked that closely at mouse lock, but sometimes the catch on things like that is if there is browser side state that can get out of sync.
Pointer lock is not a security or privacy threat. Pointer lock is a UX issue. Data can not be revealed, distributed, etc. This was established in 2011 and occasionally needs to be recirculated. I've brought this up on relevant email thread, will give that time to be addressed, and then clear the security flags from these issues.

Comment 12 by xis...@gmail.com, May 24 2017

https://www.w3.org/TR/pointerlock/#security

==========

Security Concerns:

1. User actions may be misdirected to elements the user did not intend to interact with.
2. Pointer Lock will remove the ability of a user to interact with user agent and operating system controls
3. Pointer Lock can be called repeated by script after user exits pointer lock, blocking user from meaningful progress.
4. Full screen exit instructions are displayed in some user agents when the pointer is moved to the top of the screen. During pointer lock that gesture is not possible.

Responses:

1. User agents may limit what security origins may lock the pointer.
2. User agents may prompt for confirmation before locking, this preference may be saved as a content setting.
3. Escape will always be provided by a default unlock gesture, e.g. Esc key.
4. Persistent display of escape instructions can be provided.
5. Repeated escapes of pointer lock can signal user agent to not re-lock the pointer without more specific engagement gesture, e.g. similar to how Chrome 6. suppresses repeated alert() calls.
7. Changing to new tabs, windows, or any other action that causes a page to lose focus will exit pointer lock.
Pointer lock can only be engaged when the window is in focus in the user agent and operating system.

Recommendations:

1. Esc key should exit pointer lock.
2. Preferences per sub-domain can be used to allow or block pointer lock, similar to pop-up, geolocation, and fullscreen.

Pointer lock is a required user interaction mode for certain application types, but carries a usability concern if maliciously used. An attacker could remove the ability for a user to control their mouse cursor on their system. User agents will prevent this by always providing a mechanism to exit pointer lock, by informing the user of how, and by limiting how pointer lock can be entered.

User agents will determine their own appropriate policies, which may be specialized per device or differ based on user options.
#10: Ah great, I looked for a method that might've been called on navigation but didn't find that. In that case, I think we can have it recreate the MouseLockDispatcher.

(It would also be valid to simply add a method on MouseLockDispatcher that's called on navigation which resets its state.)

Comment 14 by xis...@gmail.com, May 24 2017

#13: I found another Bug  Issue 526378 --‘Pointerlock browser UI hijack’. I think this bug can be reproduced.

lock2.html works on http(s):// or file://. Open and click.

lock2.html
367 bytes View Download
#14 that bug was marked fixed a long time ago. If you think it's still broken, it's a separate issue to that, so please open a new bug.

Comment 16 by xis...@gmail.com, May 24 2017

#15: OK, I'm going to submit a new bug now. 
Cc: mgiuca@chromium.org
Owner: chongz@chromium.org
According to #10 RenderWidget has information about navigation. The plan is to move the silent flag to RenderWidgetHost, and reset the flag on navigation.

Comment 19 by kenrb@chromium.org, May 26 2017

Labels: -Type-Bug-Security -Pri-1 -Restrict-View-SecurityTeam -Security_Impact-Stable -Security_Severity-Medium -M-59 Pri-2 Type-Bug
Clearing security flags. Unexpected mouse lock can be a user annoyance, and this can be considered a denial of service bug, but since that is the extent of exposure we don't consider it a security vulnerability.
https://dev.chromium.org/Home/chromium-security/security-faq#TOC-Are-denial-of-service-issues-considered-security-bugs-
Labels: -Pri-2 Hotlist-Input-Dev Pri-3
Owner: ----
Status: Available (was: Assigned)
Summary: Navigating to another page does not reset silent lock state (was: Security: Navigating to another page does not reset silent lock state)
The fix for  issue 725370  ensures that the exit instruction bubble will be displayed for a certain amount of time before granting silent mouse lock permission to current WebContent.

Demos in #0, #3, #14 won't cause issues anymore as the exit instruction bubble will be displayed to user properly.

Removing 'Security: ' from title to avoid confusion according to #19.

Lowering priority as the impact has been reduced, and keep bug open since we still want to clear the permission bit on navigation.

(Un-assigning myself so others can pick up)
Cc: -scheib@chromium.org
Project Member

Comment 22 by sheriffbot@chromium.org, Jan 10

Labels: Hotlist-Recharge-Cold
Status: Untriaged (was: Available)
This issue has been Available for over a year. If it's no longer important or seems unlikely to be fixed, please consider closing it out. If it is important, please re-triage the issue.

Sorry for the inconvenience if the bug really should have been left as Available.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Labels: -Hotlist-Recharge-Cold
Owner: mustaq@chromium.org
Status: Assigned (was: Untriaged)
Can still repro, specially the demo in #c3.

As per #c4, looks like resetting RenderWidgetMouseLockDispatcher on navigation should fix the remaining problem:
https://cs.chromium.org/chromium/src/content/renderer/render_widget.h?rcl=f335422d89988a17a8b2d4ecd1781ca206c1fe87&l=952

Sign in to add a comment