From 42297a2cb0d0db0c7d4a3a0b3b6e30aceefd8f80 Mon Sep 17 00:00:00 2001 From: Raphael Kubo da Costa Date: Tue, 13 Dec 2022 17:00:02 +0100 Subject: [PATCH] Editorial: Drop own powerful feature, require active local video source. Fixes #79. The idea is that, based on the research on potential attacks on the Ambient Light Sensor API, it is important to prompt users before allowing access to illuminance readouts. This was already mandated by the main Generic Sensors spec, as `Sensor.start()` runs the "Request sensor access" abstract operation. The challenge with the Ambient Light Sensor API is prompting users in a way that they understand what they are being prompted for; the assumption is that most users are not familiar with what an Ambient Light sensor is. We have chosen to solve this issue by dropping our "ambient-light-sensor" powerful feature name altogether and integrating with the Media Capture and Streams specification instead: we consider an Ambient Light Sensor to be a 1x1 camera and require there to be at least one local video source that is not muted or stopped in order for illuminance readouts to be provided. Per the Media Capture and Streams specification, this is only possible if script has called `MediaDevices.getUserMedia()` and granted the "camera" permission. This also means the User Agent has at least indicated to the user that a local video source has started being used. In other words, an Ambient Light Sensor only provides readings if a local video source (such as a camera) is currently active and being used in the same window as the AmbientLightSensor instance, and when all local video sources stop we also stop providing readouts and fire an "error" with a NotReadableError exception. --- index.bs | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 111 insertions(+), 9 deletions(-) diff --git a/index.bs b/index.bs index 8915688..08c862b 100644 --- a/index.bs +++ b/index.bs @@ -55,6 +55,12 @@ urlPrefix: https://w3c.github.io/sensors/; spec: GENERIC-SENSOR urlPrefix: https://tc39.es/ecma262/; spec: ECMA-262 type: abstract-op text: abs; url: eqn-abs +urlPrefix: https://w3c.github.io/mediacapture-main/; spec: MEDIACAPTURE-STREAMS + type: dfn + text: stopped; url: source-stopped + +
@@ -237,9 +243,13 @@ Works such as [[ALSPRIVACYANALYSIS]], [[PINSKIMMINGVIASENSOR]],
 [[STEALINGSENSITIVEDATA]], and [[VIDEORECOGNITIONAMBIENTLIGHT]] delve further
 into these issues.
 
-To mitigate these threats specific to Ambient Light Sensor, user agents must
-reduce accuracy of sensor readings. User agents may also limit
-maximum sampling frequency.
+To mitigate these threats specific to Ambient Light Sensor, user agents must:
+- [=Reduce accuracy=] of sensor readings. See [[#reduce-sensor-accuracy]].
+- Obtain user consent before providing sensor readings. This is done by
+  integrating with the [[MEDIACAPTURE-STREAMS]] specification. See
+  [[#local-video-source-requirement]].
+
+User agents may also limit maximum sampling frequency.
 
 These mitigation strategies complement the [=mitigation strategies|generic mitigations=]
 defined in the Generic Sensor API [[!GENERIC-SENSOR]].
@@ -283,6 +293,39 @@ experience. Chromium bug 1332536 and Chromium review 3666917 contain more
 information about this.
 
+Active local video source requirement {#local-video-source-requirement}
+-----
+
+Many of the attacks on Ambient Light sensors referenced above rely on being
+able to access illuminance readouts for a certain amount of time without a user
+being aware that the data is being read.
+
+[[STEALINGSENSITIVEDATA]] and [[ALSPRIVACYANALYSIS]] specifically recommend
+requesting user permission before allowing access to illuminance readouts as a
+privacy measure. On the other hand, it can be argued that conveying to users
+what an Ambient Light Sensor is so that they can make an informed choice to
+grant or deny access to it can be difficult.
+
+What this specification does instead is consider an Ambient Light Sensor to be
+a 1x1 grayscale camera, integrate with the [[MEDIACAPTURE-STREAMS]]
+specification and require there to be at least one local video [=source=] that
+is not [=muted=] or [=stopped=] in order for illuminance readouts to be
+provided. In other words, an Ambient Light Sensor only provides readings if a
+local video source (such as a camera) is currently active and being used in the
+same window as the {{AmbientLightSensor}} instance.
+
+Per the [[MEDIACAPTURE-STREAMS]] specification, this is only possible if script
+has called {{MediaDevices/getUserMedia()}} and granted the "camera" permission. This also means the User Agent has at least
+indicated to the user that a local video source has started being used as per
+[[MEDIACAPTURE-STREAMS#privacy-indicator-requirements]].
+
+The goal of this model is to treat an Ambient Light Sensor as potentially as
+invasive as an actual camera device and subject it to the same strict privacy
+requirements together with the Generic Sensor mitigations described in
+[[GENERIC-SENSOR#security-and-privacy]] and the other Ambient Light
+Sensor-specific measures described in this section.
+
 Model {#model}
 =====
 
@@ -292,12 +335,12 @@ subclass is the {{AmbientLightSensor}} class.
 The Ambient Light Sensor has a default sensor,
 which is the device's main light detector.
 
-The Ambient Light Sensor is a [=powerful feature=] that is identified by
-the [=powerful feature/name=] "ambient-light-sensor",
-which is also its associated [=sensor permission name=]. Its
-[=powerful feature/permission revocation algorithm=] is the result of calling
-the [=generic sensor permission revocation algorithm=] with
-"ambient-light-sensor".
+The Ambient Light Sensor's [=sensor permission names=] is an
+[=set/empty=] [=ordered set|set=].
+
+Note: See [[#local-video-source-requirement]]. This specification relies on the
+permission model specified in the [[MEDIACAPTURE-STREAMS]] specification
+instead.
 
 The Ambient Light Sensor is a [=policy-controlled feature=] identified by the string "ambient-light-sensor". Its [=default allowlist=] is `'self'`.
 
@@ -345,6 +388,35 @@ The {{AmbientLightSensor/illuminance}} getter steps are:
    reading=] with [=this=] and "illuminance" as arguments.
 1. Return |illuminance|.
 
+### Media Capture and Streams integration ### {#media-capture-and-streams-integration}
+
+As discussed in [[#local-video-source-requirement]], illuminance readouts are
+provided only if the same {{Window}} with an {{AmbientLightSensor}} object has
+at least one local video [=source=] that is not [=muted=] or [=stopped=].
+
+The [=ambient light pre-activation checks algorithm=] is invoked by
+{{Sensor/start()}} as specified in [[GENERIC-SENSOR]].
+
+Furthermore, whenever an item is added to the {{Window}}.\[[devicesLiveMap]]
+internal slot, or one of its items has its value changed, implementations MUST
+run the following steps:
+
+
+ 1. Let |global| be the {{Window}} object of the affected \[[devicesLiveMap]] + internal slot. + 1. Let |result| be the result of invoking [=check for active local video sources=] with |global|. + 1. If |result| is true, return. + 1. For each {{AmbientLightSensor}} object |sensor| whose [=relevant global + object=] is |global|: + 1. If |sensor|.{{[[state]]}} is "idle", then [=continue=]. + 1. Invoke [=deactivate a sensor object=] with |sensor|. + 1. Let |e| be the result of [=created|creating=] + a "{{NotReadableError}}" {{DOMException}}. + 1. [=Queue a global task=] on the [=sensor task source=] with |global| to + run [=notify error=] with |sensor| and |e| as + arguments. +
+ Abstract Operations {#abstract-operations} =================== @@ -418,6 +490,36 @@ quantization algorithm=]: 1. Return |quantizedReading|. +

Ambient light pre-activation checks algorithm

+ +The [=Ambient Light Sensor=] [=sensor type=] defines the following +[=pre-activation checks algorithm=]: + +
+ : input + :: |sensor|, an {{AmbientLightSensor}} object + : output + :: A [=boolean=] indicating whether the checks have passed and sensor activation may proceed. + + 1. Let |global| be |sensor|'s [=relevant global object=]. + 1. Return the result of invoking [=check for active local video sources=] with |global|. +
+ +

Check for active local video source

+ +
+ : input + :: |global|, an {{Window}} object + : output + :: A [=boolean=] indicating whether there are active local video sources. + + 1. If |global| does not have a \[[mediaStreamTrackSources]] internal slot, return false. + 1. For each |source| in |global|'s \[[mediaStreamTrackSources]] internal slot: + 1. If |source| is not a video input device, then [=continue=]. + 1. If |source| is not [=stopped=] or [=muted=], then return true. + 1. Return false. +
+ Automation {#automation} ========== This section extends the [=automation=] section defined in the Generic Sensor API [[GENERIC-SENSOR]]