Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enumerateDevices can be used to track user devices in background pages #561

Closed
youennf opened this issue Jan 24, 2019 · 5 comments
Closed
Assignees

Comments

@youennf
Copy link
Contributor

youennf commented Jan 24, 2019

enumerateDevices currently use [storedDeviceList] to return the same list of devices as long as there is no devicechange event. devicechange events only fire when page has focus.
enumerateDevices can still be used on an iframe being reloaded every 1 second to gather the exact number of devices since [storedDeviceList] is initially null.

As per the spec, if the origin was granted once device access (say for a funny hat cool game), any page of that origin will be able to monitor in near realtime the exact list of devices including labels.

@jan-ivar
Copy link
Member

This circumvents the intent behind the [[storedDeviceList]], so I think we need to fix this.

@jan-ivar
Copy link
Member

I ran a couple ideas in my head:

If, on pageload, the document is not fully active and in focus, then instead of null:

  1. Initialize [[storedDeviceList]] to an empty list.
  2. Initialize [[storedDeviceList]] to a previous in-memory cached storedDeviceList for this origin, or null if not found.
  3. Initialize [[storedDeviceList]] to an empty list if origin is found in in-memory cached list, or null.
  4. Initialize [[storedDeviceList]] from a global in-memory storedDeviceList cache that holds back updates until tabs receive focus.
  5. Defer resolving enumerateDevices() promise until document becomes fully active and in focus.

(1) might break legitimate WebRTC sites, e.g. restoring Firefox with pinned tabs after a restart.
(2) would mitigate (1), but requires some work, and is vulnerable to 1.evil.com, 2.evil.com.
(3) is a cheaper (2) that's meaner to background tabs that fall in the net.
(4) probably is the full airtight solution, but again probably requires some work, and hard to spec.
(5) would be a simple solution that side-steps the problem, but might depend on #560.

@youennf
Copy link
Contributor Author

youennf commented Jan 25, 2019

There is the case of a page being loaded (so it has focus) that can instantiate a 1000 frames which will have focus at that time (hence with a [[storedDeviceList]] set as null). Each frame can then be used to call enumerateDevices at different times.

Options 1 to 4 can probably be specced so that at the first enumerateDevices call, in case [[storedDeviceList]] is null and page has not focus, do a specific handling like setting [[storedDeviceList]] to the empty list.

With that change, option 1 (which should also include triggering the devicechange event when getting focus) might be ok, and would be the occasion to have enumerateDevices return an empty array :)

5 seems simpler to spec, simpler to implement and web compatible.
Is there any downsides compared to the above options?

@jan-ivar
Copy link
Member

(has focus) ... 1000 frames ... Each frame can then be used to call enumerateDevices at different times [long after it has lost focus]

Good one. The spec mitigation is flawed. [[storedDeviceList]] cannot live in the browsing context. Instead, it would have to be cached per origin probably.

5 seems simpler to spec, simpler to implement and web compatible. ... any downsides ... ?

It would solve all these issues, including the 1000 frames. It might also help reign in the rampant misuse, steering it toward its intended use-case.

The only downside I see would be if #560 isn't resolved favorably.

It would be weird if enumerateDevices() blocked in background tabs and getUserMedia() didn't.

@youennf
Copy link
Contributor Author

youennf commented Apr 11, 2019

Fixed by #574

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants