MOTIVATION The risk of using Generic Sensor API calls for device fingerprinting is mentioned within the W3C Candidate Recommendation Draft, 29 July 2021 (https://www.w3.org/TR/2021/CRD-generic-sensor-20210729/#device-fingerprinting) Documented threats include manufacturing imperfections and differences that are unique to the concrete model of the device and can be used for fingerprinting.
We discovered another loophole in the Sensor.timestamp
attribute. The value
describes when the last Sensor.onreading
event occurred, in millisecond precision.
We observed the time origin is not the time of browsing context creation
but the last boot time of the device. Exposing such information is dangerous
as it allows to fingerprint the user easily. It is unlikely that two different
devices will boot at exactly the same time.
Tested with the Magnetometer sensor on the following devices: - Samsung Galaxy S21 Ultra; Android 11, kernel 5.4.6-215566388-abG99BXXU3AUE1, Build/RP1A.200720.012.G998BXXU3AUE1 Chrome 94.0.4606.71 and Kiwi (Chromium) 94.0.4606.56 - Xiaomi Redmi Note 5; Android 9, kernel 4.4.156-perf+, Build/9 PKQ1.180901.001 Chrome 94.0.4606.71
WRAPPING
The wrapper thus protects device by changing the time origin to the browsing context creation time, whereas the timestamp should still uniquely identify the reading. This is achieved in the following way: - At the first reading, we calculate the difference between the original value and performance.now(). This gives us the offset between 1) the device boot and 2) the page context initialization. - On every reading, the offset is subtracted from the original value. The resulting value then uniquely identifies the reading sample without exposing the boot time. - Like in the other time precision wrappers, the resulting timestamp is processed by the mitigation function before return. The mitigation may round and (optionally) add noise to the resulting timestamp.
POSSIBLE IMPROVEMENTS in protection level 2, the timestamp origin may be set to a random value based on the session hash. This can serve as a "fake boot time."