Commit 0a30f56c authored by Tim Huang's avatar Tim Huang
Browse files

Bug 1363508 - Part 1: Spoofing pen/touch pointer events into mouse pointer...

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
parent 2139aad5
......@@ -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();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment