Closed Bug 1774163 Opened 2 years ago Closed 2 years ago

Investigate preventing clickjacking/keyboard-jacking for the new async clipboard API

Categories

(Core :: DOM: Copy & Paste and Drag & Drop, task)

task

Tracking

()

RESOLVED FIXED
107 Branch
Tracking Status
firefox107 --- fixed

People

(Reporter: mbrodesser-Igalia, Assigned: edgar)

References

(Blocks 1 open bug, )

Details

(Keywords: sec-want, Whiteboard: [adv-main107-])

Attachments

(3 files)

From https://phabricator.services.mozilla.com/D135333#4873268:

Orthogonally, I recall that we talked about this project quite a while ago. I don't remember with 100% certainty if I raised it at the time (I hope/think I did?): what are we doing to prevent clickjacking/keyboard-jacking of the menu item?

That is, if I wrote a malicious website that said something like: "Press P lots of times to win a prize", and call this API on the first keypress, and expect the second keypress to activate the access key of the context menu item (on linux/windows) - does that work? Are we trying to avoid that working? (the typical workaround would be to disable the menuitem initially and enable it on a timeout)

It can't hurt to check what Safari does to prevent this.

Steps to play around with this:

  1. Use current Nightly.
  2. Flip the pref "dom.events.asyncClipboard.readText" to true.
  3. Open https://jsfiddle.net/68hng59s/.
  4. Click the "X" button. A "Paste" button should occur. Be aware of bug 1766803.
  5. Press the shortcut key for pasting, "p" (assumes the browser's language is English).

It's clear clickjacking/keyboard-jacking is a potential issue. However, it should be balanced with usability.

@Freddy: are you or your team experienced with related issues from which we can learn? Any context is appreciated.

Flags: needinfo?(fbraun)

I'm afraid I have not been working on clickjacking and such. Maybe Dan or Paul have? CCing.

Flags: needinfo?(fbraun)

Adding ni?-requests. CCs are overlooked so easily.

Flags: needinfo?(pbz)
Flags: needinfo?(dveditz)
Attached file keyboard-jacking-example.html (deleted) —

We definitely need to change something to prevent that example from working.

As Gijs mentioned in the comment, some of our clickjacking protections use a timeout to disable UI elements for a while when they're first shown. You can see an example of this in our permission dialog for external protocols. Another clickjacking protection I've worked on is Bug 1338637 where we now show a confirmation dialog before doing a folder upload. The default button of that confirmation dialog is cancel.

Flags: needinfo?(pbz)

(In reply to Paul Zühlcke [:pbz] from comment #5)

As Gijs mentioned in the comment, some of our clickjacking protections use a timeout to disable UI elements for a while when they're first shown. You can see an example of this in our permission dialog for external protocols. Another clickjacking protection I've worked on is Bug 1338637 where we now show a confirmation dialog before doing a folder upload. The default button of that confirmation dialog is cancel.

Thanks for the feedback.

To learn from Safari:

  • there, two arbitrary key strokes followed by "Enter", e.g. p-p-Enter, are required.
  • there, the menu item doesn't have a timeout. The mouse cursor is at the top left corner of the menu so that it needs to be moved slightly to accept the button (the same as in Firefox).

It's noteworthy that Firefox might be more vulnerable than Safari, because calling clipboard.readText() may happen up to five seconds (the pref "dom.user_activation.transient.timeout") after the user gesture. So currently, a possible clickjacking scenario could be to request the user to click, hold the mouse button down, move the cursor to the right and release and the mouseup event might then be dispatched to the "Paste" button without the user intending so. It needs to be checked whether that's indeed possible.

A simple security mechanism would indeed be a timeout, with, let's say, three seconds. If there are no better ideas, let's start with that.

If we think something is dangerous enough that we need to get an explicit assent from the user (in other words, a permission prompt of some kind) then we have to worry about attempts to get around that prompt. We've had a long history of problems with this, with bug 162020 being an early notable example. If the prompt shows up anywhere in the content area, at a time of the web site's choosing, at a predictable location, then we usually have a problem.

The standard solution is to make the dangerous action inactive for security.dialog_enable_delay ms, so that if it was a surprise the user will have time to stop themselves from clicking/typing if it was a lured click. This delay can be annoying if the user notices it on a legit prompt, but often the prompts are such that by the time the user recognizes there's a request, reads it, and moves their mouse over to activate it, the delay is over and they never notice there was one. Keyboard activation is similar, with attackers eliciting either repeated keystrokes or simply holding the activation key down.

I recommend using security.dialog_enable_delay rather than a custom timeout because it's an agreed compromise between long enough to be effective and not so long that users get annoyed. If we reach a slightly different conclusion on that time in the future we can adjust all the spots at once, and users (and automated tests!) can customize it to meet their needs.

I found the little "Paste" button in Safari and Firefox to be pretty mysterious. They don't look like browser prompts, and if they're mistaken for something the web page has created the user may not realize this is capable of grabbing the real clipboard contents. There's also no requirement that an input field be present, or that the page has to display the contents it read from the clipboard. "paste" may not be the right metaphor.

Safari's keyboard handling is safer than ours: their access key focuses the button but the enter key activates it. A prompt like this should not start with the dangerous/grant button selected (and we don't here), but usually it's in a bigger prompt context so it's clear that there is a button that can be focused by pressing tab or an access key.

Why is dom.user_activation.transient.timeout so long? That allows "user activation consequences" to happen long after the user has forgotten they've done something! Does reading the clipboard "consume" the user activation?

Note that secretly writing to the clipboard can also be abused. Sites might want to repeatedly stomp on the clipboard to prevent someone from copying any of its content, for example. It's a popular trick for malware to replace clipboard content that looks like a crypto wallet address with it's own address, hoping to slurp up misdirected transfers. We wouldn't want to enable web pages to try that same trick.

Flags: needinfo?(dveditz)
Keywords: sec-want

(In reply to Daniel Veditz [:dveditz] from comment #7)

Why is dom.user_activation.transient.timeout so long? That allows "user activation consequences" to happen long after the user has forgotten they've done something!

In some cases, the async operation might need more time to finish, e.g. fetch, and we would like to cover those cases as much as possible. Chrome also use the same value, so align with them could also help to minimize the potential compatibility problem.

Does reading the clipboard "consume" the user activation?

Currently no, which is defined in the spec.

(In reply to Mirko Brodesser (:mbrodesser) -- away for an unknown duration from comment #6)

So currently, a possible clickjacking scenario could be to request the user to click, hold the mouse button down, move the cursor to the right and release and the mouseup event might then be dispatched to the "Paste" button without the user intending so. It needs to be checked whether that's indeed possible.

Yes, it is possible. And Safari has the same behavior. I think having a timeout (enable delay) could help to avoid that.

(In reply to Daniel Veditz [:dveditz] from comment #7)

Safari's keyboard handling is safer than ours: their access key focuses the button but the enter key activates it.

access key activates the button is a generic behavior in Gecko on each platform.
Let me think if we could do something to help this without changing how we handle access key in Gecko.

Depends on D154455

Attachment #9289555 - Attachment description: Bug 1774163 - Part 1: Simplify event handling in ClipboardReadTextPasteParent; → Bug 1774163 - Part 1: Simplify event handling in ClipboardReadPasteParent;
Assignee: nobody → echen
Attachment #9289555 - Attachment description: Bug 1774163 - Part 1: Simplify event handling in ClipboardReadPasteParent; → Bug 1774163 - Part 1: Simplify event handling in ClipboardReadPasteParent; r?Gijs
Status: NEW → ASSIGNED
Attachment #9289556 - Attachment description: Bug 1774163 - Part 2: Delay enable clipboard contextmenu; → Bug 1774163 - Part 2: Delay enable clipboard contextmenu; r?Gijs

Even with the delay enabling, if user keeps press "p", user might still miss the popup.
One more thing that we could improve is that when we detect the access key is kept pressing, we postpone the enabling of the button, like what we do for download panel.

Pushed by echen@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/511ccd45bcd4 Part 1: Simplify event handling in ClipboardReadPasteParent; r=Gijs https://hg.mozilla.org/integration/autoland/rev/5434ea8567a6 Part 2: Delay enable clipboard contextmenu; r=Gijs

Backed out 2 changesets (Bug 1774163) for causing linting failure on browser_navigator_clipboard_clickjacking.js.
Backout link
Push with failures
Failure Log
Also bc5 Failure Log TEST-UNEXPECTED-FAIL | dom/events/test/clipboard/browser_navigator_clipboard_clickjacking.js | Paste popup should still be opened - Got "hiding", expected "open"

Flags: needinfo?(echen)
Summary: Investigate preventing clickjacking/keyboard-jacking → Investigate preventing clickjacking/keyboard-jacking for the new async clipboard API
Pushed by echen@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/e9938a1c54fb Part 1: Simplify event handling in ClipboardReadPasteParent; r=Gijs https://hg.mozilla.org/integration/autoland/rev/2b995b2e5c55 Part 2: Delay enable clipboard contextmenu; r=Gijs
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 107 Branch
Whiteboard: [adv-main107-]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: