зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1363508 - Part 1: Spoofing pen/touch pointer events into mouse pointer events when fingerprinting resistance is on r=arthuredelstein,masayuki,smaug
The pointerType field in the pointer event will reveal the details of users' hardware; this is a fingerprinting vector. So, we would spoof all types of pointer events into mouse type pointer events for protecting users from browser fingerprinting when fingerprinting resistance is on. In this patch, we would spoof the pointerType as well as other fields that mouse pointer events don't support, like pressure, tiltX/Y and so on when fingerprinting resistance is on. Differential Revision: https://phabricator.services.mozilla.com/D6003 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
2139aad55e
Коммит
0a30f56cd5
|
@ -235,6 +235,28 @@ Event::GetTarget() const
|
|||
return mEvent->GetDOMEventTarget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDocument>
|
||||
Event::GetDocument() const
|
||||
{
|
||||
nsCOMPtr<EventTarget> eventTarget = GetTarget();
|
||||
|
||||
if (!eventTarget) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> win =
|
||||
do_QueryInterface(eventTarget->GetOwnerGlobal());
|
||||
|
||||
if (!win) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
doc = win->GetExtantDoc();
|
||||
|
||||
return doc.forget();
|
||||
}
|
||||
|
||||
EventTarget*
|
||||
Event::GetCurrentTarget() const
|
||||
{
|
||||
|
|
|
@ -214,6 +214,10 @@ public:
|
|||
EventTarget* GetTarget() const;
|
||||
EventTarget* GetCurrentTarget() const;
|
||||
|
||||
// This method returns the nsIDocument which is associated with the event
|
||||
// target.
|
||||
already_AddRefed<nsIDocument> GetDocument() const;
|
||||
|
||||
void ComposedPath(nsTArray<RefPtr<EventTarget>>& aPath);
|
||||
|
||||
uint16_t EventPhase() const;
|
||||
|
|
|
@ -391,24 +391,6 @@ KeyboardEvent::InitKeyboardEventJS(const nsAString& aType,
|
|||
keyEvent->mKeyValue = aKey;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDocument>
|
||||
KeyboardEvent::GetDocument()
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
nsCOMPtr<EventTarget> eventTarget = GetTarget();
|
||||
|
||||
if (eventTarget) {
|
||||
nsCOMPtr<nsPIDOMWindowInner> win =
|
||||
do_QueryInterface(eventTarget->GetOwnerGlobal());
|
||||
|
||||
if (win) {
|
||||
doc = win->GetExtantDoc();
|
||||
}
|
||||
}
|
||||
|
||||
return doc.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
KeyboardEvent::ShouldResistFingerprinting(CallerType aCallerType)
|
||||
{
|
||||
|
|
|
@ -107,10 +107,6 @@ private:
|
|||
// Otherwise, it will return false.
|
||||
bool ShouldResistFingerprinting(CallerType aCallerType);
|
||||
|
||||
// This method returns the nsIDocument which is associated with the event
|
||||
// target.
|
||||
already_AddRefed<nsIDocument> GetDocument();
|
||||
|
||||
// This method returns the spoofed modifier state of the given modifier key
|
||||
// for fingerprinting resistance.
|
||||
bool GetSpoofedModifierStates(const Modifiers aModifierKey,
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/dom/PointerEvent.h"
|
||||
#include "mozilla/dom/PointerEventBinding.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "prtime.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -146,8 +147,13 @@ NS_IMPL_ADDREF_INHERITED(PointerEvent, MouseEvent)
|
|||
NS_IMPL_RELEASE_INHERITED(PointerEvent, MouseEvent)
|
||||
|
||||
void
|
||||
PointerEvent::GetPointerType(nsAString& aPointerType)
|
||||
PointerEvent::GetPointerType(nsAString& aPointerType, CallerType aCallerType)
|
||||
{
|
||||
if (ShouldResistFingerprinting(aCallerType)) {
|
||||
aPointerType.AssignLiteral("mouse");
|
||||
return;
|
||||
}
|
||||
|
||||
ConvertPointerTypeToString(mEvent->AsPointerEvent()->inputSource, aPointerType);
|
||||
}
|
||||
|
||||
|
@ -158,45 +164,66 @@ PointerEvent::PointerId()
|
|||
}
|
||||
|
||||
int32_t
|
||||
PointerEvent::Width()
|
||||
PointerEvent::Width(CallerType aCallerType)
|
||||
{
|
||||
return mEvent->AsPointerEvent()->mWidth;
|
||||
return ShouldResistFingerprinting(aCallerType) ?
|
||||
1 : mEvent->AsPointerEvent()->mWidth;
|
||||
}
|
||||
|
||||
int32_t
|
||||
PointerEvent::Height()
|
||||
PointerEvent::Height(CallerType aCallerType)
|
||||
{
|
||||
return mEvent->AsPointerEvent()->mHeight;
|
||||
return ShouldResistFingerprinting(aCallerType) ?
|
||||
1 : mEvent->AsPointerEvent()->mHeight;
|
||||
}
|
||||
|
||||
float
|
||||
PointerEvent::Pressure()
|
||||
PointerEvent::Pressure(CallerType aCallerType)
|
||||
{
|
||||
return mEvent->AsPointerEvent()->pressure;
|
||||
if (mEvent->mMessage == ePointerUp ||
|
||||
!ShouldResistFingerprinting(aCallerType)) {
|
||||
return mEvent->AsPointerEvent()->pressure;
|
||||
}
|
||||
|
||||
// According to [1], we should use 0.5 when it is in active buttons state and
|
||||
// 0 otherwise for devices that don't support pressure. And a pointerup event
|
||||
// always reports 0, so we don't need to spoof that.
|
||||
//
|
||||
// [1] https://www.w3.org/TR/pointerevents/#dom-pointerevent-pressure
|
||||
float spoofedPressure = 0.0;
|
||||
if (mEvent->AsPointerEvent()->buttons) {
|
||||
spoofedPressure = 0.5;
|
||||
}
|
||||
|
||||
return spoofedPressure;
|
||||
}
|
||||
|
||||
float
|
||||
PointerEvent::TangentialPressure()
|
||||
PointerEvent::TangentialPressure(CallerType aCallerType)
|
||||
{
|
||||
return mEvent->AsPointerEvent()->tangentialPressure;
|
||||
return ShouldResistFingerprinting(aCallerType) ?
|
||||
0 : mEvent->AsPointerEvent()->tangentialPressure;
|
||||
}
|
||||
|
||||
int32_t
|
||||
PointerEvent::TiltX()
|
||||
PointerEvent::TiltX(CallerType aCallerType)
|
||||
{
|
||||
return mEvent->AsPointerEvent()->tiltX;
|
||||
return ShouldResistFingerprinting(aCallerType) ?
|
||||
0 : mEvent->AsPointerEvent()->tiltX;
|
||||
}
|
||||
|
||||
int32_t
|
||||
PointerEvent::TiltY()
|
||||
PointerEvent::TiltY(CallerType aCallerType)
|
||||
{
|
||||
return mEvent->AsPointerEvent()->tiltY;
|
||||
return ShouldResistFingerprinting(aCallerType) ?
|
||||
0 : mEvent->AsPointerEvent()->tiltY;
|
||||
}
|
||||
|
||||
int32_t
|
||||
PointerEvent::Twist()
|
||||
PointerEvent::Twist(CallerType aCallerType)
|
||||
{
|
||||
return mEvent->AsPointerEvent()->twist;
|
||||
return ShouldResistFingerprinting(aCallerType) ?
|
||||
0 : mEvent->AsPointerEvent()->twist;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -249,6 +276,30 @@ PointerEvent::GetCoalescedEvents(nsTArray<RefPtr<PointerEvent>>& aPointerEvents)
|
|||
aPointerEvents.AppendElements(mCoalescedEvents);
|
||||
}
|
||||
|
||||
bool
|
||||
PointerEvent::ShouldResistFingerprinting(CallerType aCallerType)
|
||||
{
|
||||
// There are four situations we don't need to spoof this pointer event.
|
||||
// 1. This event is generated by scripts.
|
||||
// 2. This event is a mouse pointer event.
|
||||
// 3. The caller type is system.
|
||||
// 4. The pref privcy.resistFingerprinting' is false, we fast return here
|
||||
// since we don't need to do any QI of following codes.
|
||||
// We don't need to check for the system group since pointer events won't be
|
||||
// dispatched to the system group.
|
||||
if (!mEvent->IsTrusted() ||
|
||||
aCallerType == CallerType::System ||
|
||||
!nsContentUtils::ShouldResistFingerprinting() ||
|
||||
mEvent->AsPointerEvent()->inputSource ==
|
||||
MouseEvent_Binding::MOZ_SOURCE_MOUSE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = GetDocument();
|
||||
|
||||
return doc && !nsContentUtils::IsChromeDoc(doc);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -45,21 +45,25 @@ public:
|
|||
const PointerEventInit& aParam);
|
||||
|
||||
int32_t PointerId();
|
||||
int32_t Width();
|
||||
int32_t Height();
|
||||
float Pressure();
|
||||
float TangentialPressure();
|
||||
int32_t TiltX();
|
||||
int32_t TiltY();
|
||||
int32_t Twist();
|
||||
int32_t Width(CallerType aCallerType);
|
||||
int32_t Height(CallerType aCallerType);
|
||||
float Pressure(CallerType aCallerType);
|
||||
float TangentialPressure(CallerType aCallerType);
|
||||
int32_t TiltX(CallerType aCallerType);
|
||||
int32_t TiltY(CallerType aCallerType);
|
||||
int32_t Twist(CallerType aCallerType);
|
||||
bool IsPrimary();
|
||||
void GetPointerType(nsAString& aPointerType);
|
||||
void GetPointerType(nsAString& aPointerType, CallerType aCallerType);
|
||||
void GetCoalescedEvents(nsTArray<RefPtr<PointerEvent>>& aPointerEvents);
|
||||
|
||||
protected:
|
||||
~PointerEvent() {}
|
||||
|
||||
private:
|
||||
// This method returns the boolean to indicate whether spoofing pointer
|
||||
// event for fingerprinting resistance.
|
||||
bool ShouldResistFingerprinting(CallerType aCallerType);
|
||||
|
||||
nsTArray<RefPtr<PointerEvent>> mCoalescedEvents;
|
||||
};
|
||||
|
||||
|
|
|
@ -14,13 +14,23 @@ interface WindowProxy;
|
|||
interface PointerEvent : MouseEvent
|
||||
{
|
||||
readonly attribute long pointerId;
|
||||
|
||||
[NeedsCallerType]
|
||||
readonly attribute long width;
|
||||
[NeedsCallerType]
|
||||
readonly attribute long height;
|
||||
[NeedsCallerType]
|
||||
readonly attribute float pressure;
|
||||
[NeedsCallerType]
|
||||
readonly attribute float tangentialPressure;
|
||||
[NeedsCallerType]
|
||||
readonly attribute long tiltX;
|
||||
[NeedsCallerType]
|
||||
readonly attribute long tiltY;
|
||||
[NeedsCallerType]
|
||||
readonly attribute long twist;
|
||||
|
||||
[NeedsCallerType]
|
||||
readonly attribute DOMString pointerType;
|
||||
readonly attribute boolean isPrimary;
|
||||
sequence<PointerEvent> getCoalescedEvents();
|
||||
|
|
Загрузка…
Ссылка в новой задаче