diff --git a/index.bs b/index.bs index f6fd44c..9180fab 100644 --- a/index.bs +++ b/index.bs @@ -2,8 +2,9 @@ Title: User Interface Security and the Visibility API Status: WD Group: WebAppSec +TR: https://www.w3.org/TR/UISecurity/ ED: https://w3c.github.io/webappsec-uisecurity/ -Shortname: UI Security +Shortname: UISecurity Level: 1 Editor: Brad Hill, Facebook, hillbrad@fb.com !Author: Dan Kaminsky, White Ops @@ -12,7 +13,7 @@ Editor: Brad Hill, Facebook, hillbrad@fb.com Abstract: UI Security and the Visibility API defines both a declarative and imperative means for resources - displayed in an embedded context to protect + displayed in an embedded context to protect themselves against having their content obscured, moved, or otherwise displayed in a misleading manner. @@ -54,9 +55,9 @@ spec:dom; type:interface; text:Document
-

Introduction

+

Introduction

- This section is not normative. + This section is not normative. Composite or "mash-up" web applications built using iframes are ubiquitous because they allow users to interact seamlessly and @@ -73,19 +74,19 @@ spec:dom; type:interface; text:Document Collectively known as User Interface Redressing, the goal of such manipulations might be to entice the user to interact - with embedded content without knowing its context, (e.g. to + with embedded content without knowing its context, (e.g. to send a payment or share content) commonly known as "clickjacking", or to convince paid content that it is being shown to the user when it is actually obscured, commonly known in the advertising business as "display fraud". - Existing anti-clickjacking measures such as frame-busting - scripts and headers granting origin-based embedding permissions have + Existing anti-clickjacking measures such as frame-busting + scripts and headers granting origin-based embedding permissions have shortcomings which prevent their application to important use-cases. - Frame-busting scripts, for example, rely on browser behavior that has not been + Frame-busting scripts, for example, rely on browser behavior that has not been engineered to provide a security guarantee and as a consequence, such scripts may be unreliable if loaded inside a sandbox - or otherwise disabled. The X-Frame-Options header and the frame-ancestors + or otherwise disabled. The X-Frame-Options header and the frame-ancestors Content Security Policy directive offer an all-or-none approach to display of embedded content that is not appropriate for content which may be embedded in arbitrary locations, or known locations @@ -93,7 +94,7 @@ spec:dom; type:interface; text:Document This document defines mechanisms to allow resources to request to be displayed free of interference by their embedding context and - learn if the user agent was able to satisfy such a request, with + learn if the user agent was able to satisfy such a request, with sufficient granularity to make decisions that can protect both users and content purveyors from various types of fraud. @@ -103,15 +104,15 @@ spec:dom; type:interface; text:Document failure of meeting such guarantees. This API should be suitable for e.g. paid content such as advertising to receive trustworthy signals about its viewability from a conforming user agent. - + Secondly, this specification defines a declarative mechanism (via a Content Security Poicy directive) to request visibility protection and receive notification, via event properties or out-of-band reporting, if certain events are delivered to - a resource while it does not meet its requested visibility + a resource while it does not meet its requested visibility contract. - The declarative CSP interface does not offer the same fine-granularity control as + The declarative CSP interface does not offer the same fine-granularity control as the JavaScript API. Its goal is to allow protection to be retrofitted to legacy applications, with no or minimal code changes, as a replacement for X-Frame-Options, or potentially for use with content that is sandboxed and cannot @@ -119,7 +120,7 @@ spec:dom; type:interface; text:Document ISSUE: Do we need to deal with form submission / navigations that aren't JS-event-based? - ISSUE: how to interact with frame-ancestors and XFO? + ISSUE: how to interact with frame-ancestors and XFO? A notable non-goal is pixel-accurate information about what was actually displayed beyond its bounding rectangle, as this information @@ -129,7 +130,7 @@ spec:dom; type:interface; text:Document
NOTE: - Similar to, and modeled on the + Similar to, and modeled on the Intersection Observer draft, this specification shares a goal of allowing reliable and low-cost calculation of element visibility for, e.g purposes of @@ -142,71 +143,71 @@ spec:dom; type:interface; text:Document Distinct from the Intersection Observer proposal, this specification operates internally on entire documents, on a per-iframe basis (although it provides some syntatic sugar for the declarative, - event-driven API) rather than observing individual elements, and it affirmatively modifies the final + event-driven API) rather than observing individual elements, and it affirmatively modifies the final composited result in the global viewport by promoting the graphics layer of an iframe that has requested visibility.
- +
-

Special Conformance Notes

- - This section is not normative. - - UI Redressing attacks rely on fooling the subjective perceptions of - human actors to induce them to interact with a web application out of - its intended context. Because of this, the specific mechanisms which - may be used in attack and defense may vary greatly with the details of - a user agent implementation. For example, attacks which rely on - redressing the cursor may not apply in a touch environment, or entire - classes of attack may be impossible on a text-only browser or screen - reader. - - Similarly, the implementation of the policies specified herein is highly - dependent on internal architecture and implementation strategies of - the user agent; such strategies may vary greatly between user agents - or even across versions or platforms for a single user agent. - - This specification provides a normative means by which a resource - owner can communicate to a user agent its desire for additional - protective measures, actions to take if violations are detected, - and tuning hints which may be useful for certain means of - implementation. A user agent is conformant if it understands - these directives and makes a best effort to provide the desired - security properties, which might require no additional implementation - steps, e.g. in the case of a screen reader that does not support - embedded resources in a manner that is subject to any of the - attack classes of concern. - - While the indeterminacy of the user agent implementation protects - applications from needing to constantly update their policies as - user agents make internal changes, application authors should - understand that even a conformant user agent cannot make - perfect security guarantees against UI Redressing. - - These directives should be used as part of a comprehensive risk - mitigation strategy with an appropriate understanding of their - limitations. +

Special Conformance Notes

+ + This section is not normative. + + UI Redressing attacks rely on fooling the subjective perceptions of + human actors to induce them to interact with a web application out of + its intended context. Because of this, the specific mechanisms which + may be used in attack and defense may vary greatly with the details of + a user agent implementation. For example, attacks which rely on + redressing the cursor may not apply in a touch environment, or entire + classes of attack may be impossible on a text-only browser or screen + reader. + + Similarly, the implementation of the policies specified herein is highly + dependent on internal architecture and implementation strategies of + the user agent; such strategies may vary greatly between user agents + or even across versions or platforms for a single user agent. + + This specification provides a normative means by which a resource + owner can communicate to a user agent its desire for additional + protective measures, actions to take if violations are detected, + and tuning hints which may be useful for certain means of + implementation. A user agent is conformant if it understands + these directives and makes a best effort to provide the desired + security properties, which might require no additional implementation + steps, e.g. in the case of a screen reader that does not support + embedded resources in a manner that is subject to any of the + attack classes of concern. + + While the indeterminacy of the user agent implementation protects + applications from needing to constantly update their policies as + user agents make internal changes, application authors should + understand that even a conformant user agent cannot make + perfect security guarantees against UI Redressing. + + These directives should be used as part of a comprehensive risk + mitigation strategy with an appropriate understanding of their + limitations.
@@ -231,7 +232,7 @@ spec:dom; type:interface; text:Document readonly attribute DOMRectReadOnly globalVisibleBounds; readonly attribute DOMRectReadOnly visibleBounds; readonly attribute DOMHighResTimeStamp time; - }; + }; dictionary VisibilityObserverEntryInit { required DOMRectInit globalVisibleBounds; @@ -242,7 +243,7 @@ spec:dom; type:interface; text:Document
globalVisibleBounds - The {{DOMRect}} coresponding to the visible dimensions of the + The {{DOMRect}} coresponding to the visible dimensions of the top-level document in the global viewport's coordinate space. visibleBounds @@ -256,7 +257,7 @@ spec:dom; type:interface; text:Document A {{DOMHighResTimeStamp}} that corresponds to the time the visibility state was recorded.
- +

The VisibilityObserver Interface

The VisibilityObserver interface can be used to observe changes in the document's visibility state relative to the global viewport. @@ -269,18 +270,18 @@ spec:dom; type:interface; text:Document sequence<VisibilityObserverEntry> takeRecords (); }; - -
- : new VisibilityObserver(callback, options) - :: -
    -
  1. Let |this| be a new {{VisibilityObserver}} object
  2. -
  3. Set |this|'s internal {{[[callback]]}} slot to |callback|.
  4. -
+ +
+ : new VisibilityObserver(callback, options) + :: +
    +
  1. Let |this| be a new {{VisibilityObserver}} object
  2. +
  3. Set |this|'s internal {{[[callback]]}} slot to |callback|.
  4. +
: observe() ::
    -
  1. Add |this| to the document's {{[[RegisteredVisibilityObservers]]}} list
  2. +
  3. Add |this| to the document's {{[[RegisteredVisibilityObservers]]}} list
: unobserve() :: @@ -299,12 +300,12 @@ spec:dom; type:interface; text:Document

The VisibilityObserverInit dictionary

- 	     dictionary VisibilityObserverInit {
- 	       (double or sequence<double>) areaThreshold = 0;
-				 (boolean) displacementAware = false;
-				 (DOMString) visibleMargin = "0px";
-				 (Element)? observedElement;
- 	     };
+			dictionary VisibilityObserverInit {
+				(double or sequence<double>) areaThreshold = 0;
+				(boolean) displacementAware = false;
+				(DOMString) visibleMargin = "0px";
+				(Element)? observedElement;
+			};
 		
@@ -330,57 +331,57 @@ spec:dom; type:interface; text:Document : visibleMargin :: - Same as 'margin', extends the required visibility rectangle - behind the protected-element.{{Element/getBoundingClientRect()}}. - Can be 1, 2, 3 or 4 components, possibly negative lengths. - - If there is only one component value, it applies to all sides. - If there are two values, the top and bottom margins are set to - the first value and the right and left margins are set to the - second. If there are three values, the top is set to the first - value, the left and right are set to the second, and the bottom - is set to the third. If there are four values, they apply to the - top, right, bottom, and left, respectively.e.g. -
-					
-						"5px"                // all margins set to 5px
-						"5px 10px"           // top & bottom = 5px, right & left = 10px
-						"-10px 5px 8px"      // top = -10px, right & left = 5px, bottom = 8px
-						"-10px -5px 5px 8px" // top = -10px, right = -5px, bottom = 5px, left = 8px
-					
-				
+ Same as 'margin', extends the required visibility rectangle + behind the protected-element.{{Element/getBoundingClientRect()}}. + Can be 1, 2, 3 or 4 components, possibly negative lengths. + + If there is only one component value, it applies to all sides. + If there are two values, the top and bottom margins are set to + the first value and the right and left margins are set to the + second. If there are three values, the top is set to the first + value, the left and right are set to the second, and the bottom + is set to the third. If there are four values, they apply to the + top, right, bottom, and left, respectively.e.g. +
+				
+					"5px"                // all margins set to 5px
+					"5px 10px"           // top & bottom = 5px, right & left = 10px
+					"-10px 5px 8px"      // top = -10px, right & left = 5px, bottom = 8px
+					"-10px -5px 5px 8px" // top = -10px, right = -5px, bottom = 5px, left = 8px
+				
+			
: observedElement :: The {{Element}} being observed. If unset, the internal slot will be initialized to the {{Document}} element. -
+
-

Content Security Policy Interface

+

Content Security Policy Interface

- This section describes the Content Security Policy - directive introduced in this specification to provide declarative - configuration of protection against input when an element does not meet it's - visibility requirements. + This section describes the Content Security Policy + directive introduced in this specification to provide declarative + configuration of protection against input when an element does not meet it's + visibility requirements. - The optional directive-value allows configuration of conditions for which violations - will be triggered. + The optional directive-value allows configuration of conditions for which violations + will be triggered. -

The input-protection Directive

+

The input-protection Directive

 			directive-name    = 'input-protection'
@@ -398,21 +399,21 @@ spec:dom; type:interface; text:Document
 				protected area is below this threshold.
 
 				Threshold values must be in the range [0, 1.0] and represent a
-				percentage of the area as specified by 
+				percentage of the area as specified by
 				protected-element.{{Element/getBoundingClientRect()}},
 				adjusted by visible-margin.  Unlike the imperative API,
 				only a single value may be specified.
 
 			protected-element
 				A {{DOMString}} used as the argument to {{NonElementParentNode/getElementById()}}
-				to resolve the {{Element}} to which the policy applies.  
+				to resolve the {{Element}} to which the policy applies.
 
 				If unspecified the policy is applied to the resource's {{Document}} node.
 
 			time-threshold
 				A numeric value in the range [0, 10000] that specifies how long,
 				in milliseconds, the screen area containing the protected-element
-				must have unmodified viewiability properties when an event is 
+				must have unmodified viewiability properties when an event is
 				delivered to it or one of its ancestors.
 
 				If not specified, it defaults to 800.  If a value outside of the
@@ -421,18 +422,18 @@ spec:dom; type:interface; text:Document
 
 			visible-margin
 				Same as {{VisibilityObserverInit/visibleMargin}}.
-				
+
 				If unspecified, it defaults to "0px".
 
 
@@ -448,7 +449,7 @@ spec:dom; type:interface; text:Document Each unit of related similar-origin browsing contexts has an VisibilityObserverTaskQueued flag which is initialized to false. - +

Element

{{Element}} objects have an internal \[[InputProtectionObservers]] list, @@ -465,7 +466,7 @@ spec:dom; type:interface; text:Document @@ -477,13 +478,13 @@ spec:dom; type:interface; text:Document
  • \[[visibleMargin]]
  • \[[observedElement]] which is initialized to the {{Document}} Element if not set in the {{VisibilityObserverInit}} dictionary
  • - - The following internal slots will be initialzed to null unless the - object was constructed to represent an input-protection directive. - + + The following internal slots will be initialzed to null unless the + object was constructed to represent an input-protection directive. +

    Algorithms

    @@ -499,36 +500,39 @@ spec:dom; type:interface; text:Document task to notify visibility observers in the list of idle request callbacks with an appropriate |timeout|. - Issue: Should we define an appropriate |timeout|? + Issue: Should we define an appropriate |timeout|?

    Notify VisibilityObservers

    - To notify visibility observers for a + To notify visibility observers for a unit of related similar-origin browsing contexts |unit|, run these steps:
    1. Set |unit|'s VisibilityObserverTaskQueued flag to false.
    2. -
    3. For each {{Document}} |document| in |unit|
    4. -
        -
      1. Let |notify list| be a copy of |document|'s {{[[RegisteredVisibilityObservers]]}} +
      2. For each {{Document}} |document| in |unit| +
          +
        1. Let |notify list| be a copy of |document|'s {{[[RegisteredVisibilityObservers]]}} list.
        2. -
        3. For each {{VisibilityObserver}} object |observer| in - |notify list|, run these steps:
        4. +
        5. For each {{VisibilityObserver}} object |observer| in + |notify list|, run these steps:
          1. If |observer|'s internal {{[[QueuedEntries]]}} slot is - empty, continue.
          2. + empty, continue.
          3. Let |queue| be a copy of |observer|'s internal - {{[[QueuedEntries]]}} slot.
          4. + {{[[QueuedEntries]]}} slot.
          5. Clear |observer|'s internal {{[[QueuedEntries]]}} slot.
          6. Invoke |callback| with |queue| as the first argument and - |observer| as the second argument and - callback this value. If this throws an exception, - report the exception.
          7. + |observer| as the second argument and + callback this value. If this throws an exception, + report the exception.
          +
        -
      + +
    +

    Queue a VisibilityObserverEntry

    @@ -545,16 +549,16 @@ spec:dom; type:interface; text:Document This section is non-normative.
    - NOTE: The full internal details of rendering a document to the pixels - actually displayed to the user is not standardized. UA implementations + NOTE: The full internal details of rendering a document to the pixels + actually displayed to the user is not standardized. UA implementations may vary widely. - The implementation strategy detailed in this section is not normative. Any - strategy which produces correct outcomes for the normative algorithms is + The implementation strategy detailed in this section is not normative. Any + strategy which produces correct outcomes for the normative algorithms is conformant and implementers are encouraged to optimize whenever possible. The possibility of variance among user agent implementations notwithstanding, - the normative algorithms of this specification are designed such that a highly performant + the normative algorithms of this specification are designed such that a highly performant implementation should be possible on the most common internal software and hardware architectures that are state-of-the-art for user agents and consumer computing platforms as of the time of writing. @@ -564,104 +568,107 @@ spec:dom; type:interface; text:Document rendering of the global viewport is delgated to a a Graphics Processing Unit (GPU) using higher-level abstractions like surfaces, polygons, and vectors. As a consequence, the main execution context of the user agent does not "know" what pixels actually result - without reading them back. System architectures are optimized for sending data + without reading them back. System architectures are optimized for sending data to a GPU, not returning data from it, therefore, approaches which rely on pixel comparisons - are likely to have an unacceptable performance cost. Instead, the approach detailed - here relies on correctness by design, by manipulating the order in which instructions + are likely to have an unacceptable performance cost. Instead, the approach detailed + here relies on correctness by design, by manipulating the order in which instructions are sent to the GPU such that malicious interference is not possible.
    Generally, at some point in the rendering of a set of documents in nested browsing contexts into the fully composed graphical representation in the global viewport, - a user agent will arrive at a set of intermediate representations we will designate + a user agent will arrive at a set of intermediate representations we will designate as GraphicsLayers, each of which represents a graphical surface to be painted / clipped / scrolled. A GraphicsLayer representing the contents of a document in an iframe will - be arranged in the layer stack such that at a later phase in the rendering - it is automatically clipped and positioned relative to the series of viewports + be arranged in the layer stack such that at a later phase in the rendering + it is automatically clipped and positioned relative to the series of viewports above it, and also subject to being drawn over or transformed by the layers above it. To prevent potentially malicious composition, the user agent can promote observed graphicsLayers by manipulating them such that a document with {{[[RegisteredVisibilityObservers]]}} - + To promote observed graphicsLayers, given a time |now|, and an initially empty list |promotedLayers|, run these steps during the rendering loop at the stage where the intermediate representation of a set of {{Document}}s is a set of GraphicsLayers |graphicsLayers|. -
      -
    1. For each |graphicsLayer| in |graphicsLayers|
    2. -
    3. For each {{Document}} |document| with an intermediate representation in |graphicsLayer|
    4. +
        +
      1. For each |graphicsLayer| in |graphicsLayers|
      2. +
      3. For each {{Document}} |document| with an intermediate representation in |graphicsLayer|
          -
        1. If |document| has an empty list of {{[[RegisteredVisibilityObservers]]}}, continue.
        2. -
        3. If |document| has a non-empty list of {{[[RegisteredVisibilityObservers]]}}
        4. +
        5. If |document| has an empty list of {{[[RegisteredVisibilityObservers]]}}, continue.
        6. +
        7. If |document| has a non-empty list of {{[[RegisteredVisibilityObservers]]}}
          1. If |document| is not the only {{Document}} represented in |graphicsLayer|, apply - whatever implementation-specific steps are necessary to place it in its own layer. - (e.g. apply translatez(0) to the documentElement) Let |graphicsLayer| be that - new layer.
          2. + whatever implementation-specific steps are necessary to place it in its own layer. + (e.g. apply translatez(0) to the documentElement) Let |graphicsLayer| be that + new layer.
          +
        8. Let |rectToRaise| be the value of |document|.{{Element/getBoundingClientRect()}}.
        9. Intersect |rectToRaise| with |document|'s viewport clip rect.
        10. For every parent browsing context |parent| between |document| and the top-level document, - intersect |rectToRaise| with |parent|'s viewport clip rect, - and finally with the global viewport clip rect.
        11. + intersect |rectToRaise| with |parent|'s viewport clip rect, + and finally with the global viewport clip rect.
        12. Clip |graphicsLayer| to |rectToRaise|. (|graphicsLayer| may have zero width and height - if it is scrolled off screen by an ancestor browsing context)
        13. -
        14. Intersect |rectToRaise| with any items in the |promotedLayers| list.
        15. + if it is scrolled off screen by an ancestor browsing context) +
        16. Intersect |rectToRaise| with any items in the |promotedLayers| list.
        17. Add |rectToRaise| to the |promotedLayers| list.
        18. -
        19. Without reordering prior intermediate representations in a manner which would - change event dispatching, hit testing, or the DOM as exposed to JavaScript, reorder - the GraphicsLayers such that |rectToRaise| is on top of the root GraphicsLayer. - (e.g. by making it a direct child of the root layer) but beneath any layers in |promotedLayers| - that clipped it.
        20. +
        21. Without reordering prior intermediate representations in a manner which would + change event dispatching, hit testing, or the DOM as exposed to JavaScript, reorder + the GraphicsLayers such that |rectToRaise| is on top of the root GraphicsLayer. + (e.g. by making it a direct child of the root layer) but beneath any layers in |promotedLayers| + that clipped it.
        22. Let |protectedRect| be the value of |observer|'s {{[[observedElement]]}}.{{Element/getBoundingClientRect()}}, - adjusted by {{[[visibleMargin]]}}.
        23. + adjusted by {{[[visibleMargin]]}}.
        24. Let |visibleRatio| be the intersection of |protectedRect| with |rectToRaise|, divided by |protectedRect| - if |protectedRect| is non-zero, and 0 otherwise.
        25. -
        26. For each of |document|'s {{[[RegisteredVisibilityObservers]]}} |observer|
        27. + if |protectedRect| is non-zero, and 0 otherwise. +
        28. For each of |document|'s {{[[RegisteredVisibilityObservers]]}} |observer|
            -
          1. Let |threshold| be the index of the first entry in - |observer|'s internal {{[[areaThreshold]]}} slot whose value - is greater than or equal to |visibleRatio|. If - |visibleRatio| is equal to 0, let |threshold| be - -1.
          2. -
          3. Let |oldVisibleRatio| be set to |observer|'s internal - {{[[previousVisibleRatio]]}} slot.
          4. -
          5. Let |oldThreshold| be the index of the first entry in - |observer|'s internal {{[[areaThreshold]]}} slot whose value - is greater than or equal to |oldVisibleRatio|. If - |oldVisibleRatio| is equal to 0, let - |oldThreshold| be -1.
          6. -
          7. Let |oldPosition| be the value of the |observer|'s internal - {{[[previousGlobalViewportPosition]]}}.
          8. -
          9. If |threshold| does not equal |oldThreshold|, or if |observer|'s - internal {{[[displacementAware]]}} slot is true and - |oldPosition| is not equal to |protectedRect|,
          10. -
              -
            • queue a VisibilityObserverEntry
            • -
            • Assign |visibleRatio| to |observer|'s internal - {{[[previousVisibleRatio]]}} slot.
            • -
            • Assign |protectedRect| to the value of the |observer|'s internal - {{[[previousGlobalViewportPosition]]}} slot.
            • -
            - +
          11. Let |threshold| be the index of the first entry in + |observer|'s internal {{[[areaThreshold]]}} slot whose value + is greater than or equal to |visibleRatio|. If + |visibleRatio| is equal to 0, let |threshold| be + -1.
          12. +
          13. Let |oldVisibleRatio| be set to |observer|'s internal + {{[[previousVisibleRatio]]}} slot.
          14. +
          15. Let |oldThreshold| be the index of the first entry in + |observer|'s internal {{[[areaThreshold]]}} slot whose value + is greater than or equal to |oldVisibleRatio|. If + |oldVisibleRatio| is equal to 0, let + |oldThreshold| be -1.
          16. +
          17. Let |oldPosition| be the value of the |observer|'s internal + {{[[previousGlobalViewportPosition]]}}.
          18. +
          19. If |threshold| does not equal |oldThreshold|, or if |observer|'s + internal {{[[displacementAware]]}} slot is true and + |oldPosition| is not equal to |protectedRect|, +
              +
            • queue a VisibilityObserverEntry
            • +
            • Assign |visibleRatio| to |observer|'s internal + {{[[previousVisibleRatio]]}} slot.
            • +
            • Assign |protectedRect| to the value of the |observer|'s internal + {{[[previousGlobalViewportPosition]]}} slot.
            • +
            +
          +
        -
      - - ISSUE: find exact terms to make sure that we have viewport definitions minus scrollbars + +
    + + ISSUE: find exact terms to make sure that we have viewport definitions minus scrollbars ISSUE: need to also clip to any other layers that were promoted ahead of us! @@ -669,40 +676,42 @@ spec:dom; type:interface; text:Document

    Enforce An input-protection Directive

    To enforce an input-protection directive for a {{Document}} |document|, - run the following steps: + run the following steps:
    1. Parse the policy according to [[!CSP2]].
    2. If a value is set for protected-element, let |protectedElement| be the - {{Element}} returned by invoking |document|.{{NonElementParentNode/getElementById()}} with - the value as the input, or |document| if null or unset.
    3. + {{Element}} returned by invoking |document|.{{NonElementParentNode/getElementById()}} with + the value as the input, or |document| if null or unset.
    4. If |document|'s {{[[InputProtectionRequested]]}} flag is false, set it - to true.
    5. + to true.
    6. Construct a new {{VisibilityObserver}} |observer|, with {{[[areaThreshold]]}} set to the value of - area-threshold, {{[[visibleMargin]]}} set to the value of visible-margin, - {{[[observedElement]]}} set to |protectedElement|, {{[[displacementAware]]}} set to true, - and {{[[callback]]}} set to a new function with an empty function body.
    7. -
    8. Set the internal {{[[timeThreshold]]}} slot of |observer| to the value of time-threshold
    9. + area-threshold, {{[[visibleMargin]]}} set to the value of visible-margin, + {{[[observedElement]]}} set to |protectedElement|, {{[[displacementAware]]}} set to true, + and {{[[callback]]}} set to a new function with an empty function body. +
    10. Set the internal {{[[timeThreshold]]}} slot of |observer| to the value of time-threshold
    11. Set the internal {{[[associatedContentSecurityPolicy]]}} slot of |observer| to a reference to the - Content Security Policy which the input-protection directive is associated with.
    12. + Content Security Policy which the input-protection directive is associated with.
    13. When dispatching events, when an {{Element}} |element| will handle an {{Event}} |event|, - if |event| is of type Mouse Event, Pointer Event, Drag-and-Drop, or Clipboard Event, (TODO:linkify) - and if |element| has {{[[InputProtectionObservers]]}} |observers|:
    14. -
        -
      1. If applicable, check the computed style for the cursor. If a cursor is typically displayed but - has been hidden or changed to a non-standard bitmap, handle a violation for |event| and each - |observer| in |observers|.
      2. -
      3. Otherwise, for each |observer| in |observers|:
      4. -
          -
        1. If |observer|'s {{[[previousVisibleRatio]]}} is less than {{[[areaThreshold]]}}, - handle a violation for |observer|.
        2. -
        3. If |observer|'s {{[[previousVisibleRatio]]}} is greater than {{[[areaThreshold]]}}, - get the most recent {{VisibilityObserverEntry}} |entry| from |observer|'s - {{[[QueuedEntries]]}}. If the difference between |entry|.{{VisibilityObserverEntry/time}} - and |now| is less than {{[[timeThreshold]]}}, handle a violation for |observer|. -
        -
      + if |event| is of type Mouse Event, Pointer Event, Drag-and-Drop, or Clipboard Event, (TODO:linkify) + and if |element| has {{[[InputProtectionObservers]]}} |observers|: +
        +
      1. If applicable, check the computed style for the cursor. If a cursor is typically displayed but + has been hidden or changed to a non-standard bitmap, handle a violation for |event| and each + |observer| in |observers|.
      2. +
      3. Otherwise, for each |observer| in |observers|: +
          +
        1. If |observer|'s {{[[previousVisibleRatio]]}} is less than {{[[areaThreshold]]}}, + handle a violation for |observer|.
        2. +
        3. If |observer|'s {{[[previousVisibleRatio]]}} is greater than {{[[areaThreshold]]}}, + get the most recent {{VisibilityObserverEntry}} |entry| from |observer|'s + {{[[QueuedEntries]]}}. If the difference between |entry|.{{VisibilityObserverEntry/time}} + and |now| is less than {{[[timeThreshold]]}}, handle a violation for |observer|. +
        +
      4. +
      +
    - +

    Handle a Violation

    To handle a violation of an input-protection directive for |observer| and |event|, run the following steps:

    External Spec Integrations

    HTML Processing Model: Event Loop

    - As part of substep 10 of the + As part of substep 10 of the - update the rendering event loop in the HTML Processing Model, + update the rendering event loop in the HTML Processing Model, Promote Observed GraphicsLayers, passing in now as the timestamp.

    DOM: Dispatching Events

    @@ -741,25 +749,24 @@ spec:dom; type:interface; text:Document Will be set to true if the event fired when the event did not meet the document's input-protection requirements. - - +

    Privacy Considerations

    -This section is non-normative. + This section is non-normative. The timing of visibilityEvents may leak some information across Origin boundaries. An embedded document might have previously been unable to learn that it was obscured, or the timing and @@ -774,24 +781,24 @@ spec:dom; type:interface; text:Document

    Security Considerations

    -This section is non-normative. + This section is non-normative. - UI Redressing and Clickjacking attacks rely on violating the contextual and temporal - integrity of embedded content. Because these attacks target the subjective perception - of the user and not well-defined security boundaries, the heuristic protections - afforded by the input-protection directive can never be 100% effective for every - interface. It provides no protection against certain classes of attacks, such as - displaying content around an embedded resource that appears to extend a trusted + UI Redressing and Clickjacking attacks rely on violating the contextual and temporal + integrity of embedded content. Because these attacks target the subjective perception + of the user and not well-defined security boundaries, the heuristic protections + afforded by the input-protection directive can never be 100% effective for every + interface. It provides no protection against certain classes of attacks, such as + displaying content around an embedded resource that appears to extend a trusted dialog but provides misleading information. When used as a mechanism to report visibility for purposes of monetizing content, @@ -805,12 +812,12 @@ spec:dom; type:interface; text:Document

    Accessibility Considerations

    @@ -820,6 +827,4 @@ spec:dom; type:interface; text:Document modality is not subject to UI redressing attacks or definitions of "visibility" do not apply, the user agent SHOULD report a VisibilityEvent indicating 100% visibility, and SHOULD never fire a violation for any input-protection policy. - -
    diff --git a/index.html b/index.html index a9e3f59..481ae04 100644 --- a/index.html +++ b/index.html @@ -5,253 +5,326 @@ User Interface Security and the Visibility API - - +.css.css, .property.property, .descriptor.descriptor { + color: var(--a-normal-text); + font-size: inherit; + font-family: inherit; +} +.css::before, .property::before, .descriptor::before { + content: "‘"; +} +.css::after, .property::after, .descriptor::after { + content: "’"; +} +.property, .descriptor { + /* Don't wrap property and descriptor names */ + white-space: nowrap; +} +.type { /* CSS value */ + font-style: italic; +} +pre .property::before, pre .property::after { + content: ""; +} +[data-link-type="property"]::before, +[data-link-type="propdesc"]::before, +[data-link-type="descriptor"]::before, +[data-link-type="value"]::before, +[data-link-type="function"]::before, +[data-link-type="at-rule"]::before, +[data-link-type="selector"]::before, +[data-link-type="maybe"]::before { + content: "‘"; +} +[data-link-type="property"]::after, +[data-link-type="propdesc"]::after, +[data-link-type="descriptor"]::after, +[data-link-type="value"]::after, +[data-link-type="function"]::after, +[data-link-type="at-rule"]::after, +[data-link-type="selector"]::after, +[data-link-type="maybe"]::after { + content: "’"; +} + +[data-link-type].production::before, +[data-link-type].production::after, +.prod [data-link-type]::before, +.prod [data-link-type]::after { + content: ""; +} + +[data-link-type=element], +[data-link-type=element-attr] { + font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace; + font-size: .9em; +} +[data-link-type=element]::before { content: "<" } +[data-link-type=element]::after { content: ">" } + +[data-link-type=biblio] { + white-space: pre; +} +figcaption { + counter-increment: figure; +} +figcaption:not(.no-marker)::before { + content: "Figure " counter(figure) " "; +} + +/* This is a weird hack for me not yet following the commonmark spec + regarding paragraph and lists. */ +[data-md] > :first-child { + margin-top: 0; +} +[data-md] > :last-child { + margin-bottom: 0; +} - + +.highlight:not(.idl) { background: rgba(0, 0, 0, .03); } +c-[a] { color: #990055 } /* Keyword.Declaration */ +c-[b] { color: #990055 } /* Keyword.Type */ +c-[c] { color: #708090 } /* Comment */ +c-[d] { color: #708090 } /* Comment.Multiline */ +c-[e] { color: #0077aa } /* Name.Attribute */ +c-[f] { color: #669900 } /* Name.Tag */ +c-[g] { color: #222222 } /* Name.Variable */ +c-[k] { color: #990055 } /* Keyword */ +c-[l] { color: #000000 } /* Literal */ +c-[m] { color: #000000 } /* Literal.Number */ +c-[n] { color: #0077aa } /* Name */ +c-[o] { color: #999999 } /* Operator */ +c-[p] { color: #999999 } /* Punctuation */ +c-[s] { color: #a67f59 } /* Literal.String */ +c-[t] { color: #a67f59 } /* Literal.String.Single */ +c-[u] { color: #a67f59 } /* Literal.String.Double */ +c-[cp] { color: #708090 } /* Comment.Preproc */ +c-[c1] { color: #708090 } /* Comment.Single */ +c-[cs] { color: #708090 } /* Comment.Special */ +c-[kc] { color: #990055 } /* Keyword.Constant */ +c-[kn] { color: #990055 } /* Keyword.Namespace */ +c-[kp] { color: #990055 } /* Keyword.Pseudo */ +c-[kr] { color: #990055 } /* Keyword.Reserved */ +c-[ld] { color: #000000 } /* Literal.Date */ +c-[nc] { color: #0077aa } /* Name.Class */ +c-[no] { color: #0077aa } /* Name.Constant */ +c-[nd] { color: #0077aa } /* Name.Decorator */ +c-[ni] { color: #0077aa } /* Name.Entity */ +c-[ne] { color: #0077aa } /* Name.Exception */ +c-[nf] { color: #0077aa } /* Name.Function */ +c-[nl] { color: #0077aa } /* Name.Label */ +c-[nn] { color: #0077aa } /* Name.Namespace */ +c-[py] { color: #0077aa } /* Name.Property */ +c-[ow] { color: #999999 } /* Operator.Word */ +c-[mb] { color: #000000 } /* Literal.Number.Bin */ +c-[mf] { color: #000000 } /* Literal.Number.Float */ +c-[mh] { color: #000000 } /* Literal.Number.Hex */ +c-[mi] { color: #000000 } /* Literal.Number.Integer */ +c-[mo] { color: #000000 } /* Literal.Number.Oct */ +c-[sb] { color: #a67f59 } /* Literal.String.Backtick */ +c-[sc] { color: #a67f59 } /* Literal.String.Char */ +c-[sd] { color: #a67f59 } /* Literal.String.Doc */ +c-[se] { color: #a67f59 } /* Literal.String.Escape */ +c-[sh] { color: #a67f59 } /* Literal.String.Heredoc */ +c-[si] { color: #a67f59 } /* Literal.String.Interpol */ +c-[sx] { color: #a67f59 } /* Literal.String.Other */ +c-[sr] { color: #a67f59 } /* Literal.String.Regex */ +c-[ss] { color: #a67f59 } /* Literal.String.Symbol */ +c-[vc] { color: #0077aa } /* Name.Variable.Class */ +c-[vg] { color: #0077aa } /* Name.Variable.Global */ +c-[vi] { color: #0077aa } /* Name.Variable.Instance */ +c-[il] { color: #000000 } /* Literal.Number.Integer.Long */ +
    -

    +

    User Interface Security and the Visibility API

    -

    W3C Working Draft,

    +

    W3C Working Draft,

    This version: -
    http://www.w3.org/TR/2016/WD-UI Security-1-20160603/ +
    https://www.w3.org/TR/1970/WD-UISecurity-1-19700101/ +
    Latest published version: +
    https://www.w3.org/TR/UISecurity/
    Editor's Draft: -
    https://w3c.github.io/webappsec/specs/uisecurity/ +
    https://w3c.github.io/webappsec-uisecurity/
    Feedback: -
    public-webappsec@w3.org with subject line “[UI Security] … message topic …” (archives) -
    Issue Tracking: -
    Inline In Spec +
    public-webappsec@w3.org with subject line “[UISecurity] … message topic …” (archives)
    Editor:
    (Facebook)
    Author: -
    Dan Kaminsky, White Ops -
    David Lin-Shung Huang, Carnegie Mellon University -
    Giorgio Maone, Invited Expert +
    Dan Kaminsky, White Ops +
    David Lin-Shung Huang, Carnegie Mellon University +
    Giorgio Maone, Invited Expert
    - +
    -

    Abstract

    +

    Abstract

    UI Security and the Visibility API defines both a -declarative and imperative means for resources -displayed in an embedded context to protect -themselves against having their content obscured, -moved, or otherwise displayed in a misleading -manner.

    + declarative and imperative means for resources + displayed in an embedded context to protect + themselves against having their content obscured, + moved, or otherwise displayed in a misleading + manner.

    Status of this document

    This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report - can be found in the W3C technical reports - index at http://www.w3.org/TR/.

    -

    This document was published by the Web Application Security Working Group as a Working Draft. This document is intended to become a W3C Recommendation.

    -

    The (archived) public mailing list public-webappsec@w3.org (see instructions) + can be found in the W3C technical reports + index at https://www.w3.org/TR/.

    +

    This document was published by the Web Application Security Working Group as a Working Draft. This document is intended to become a W3C Recommendation.

    +

    The (archived) public mailing list public-webappsec@w3.org (see instructions) is preferred for discussion of this specification. When sending e-mail, - please put the text “UI Security” in the subject, + please put the text “UISecurity” in the subject, preferably like this: - “[UI Security] …summary of comment…

    + “[UISecurity] …summary of comment…

    Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

    -

    This document was produced by the Web Application Security Working Group.

    +

    This document was produced by the Web Application Security Working Group.

    This document was produced by a group operating under - the 5 February 2004 W3C Patent Policy. - W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; + the W3C Patent Policy. + W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. - An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

    -

    This document is governed by the 1 September 2015 W3C Process Document.

    + An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

    +

    This document is governed by the 15 September 2020 W3C Process Document.

    @@ -347,25 +420,25 @@

    1.

    Collectively known as User Interface Redressing, the goal of such manipulations might be to entice the user to interact - with embedded content without knowing its context, (e.g. to + with embedded content without knowing its context, (e.g. to send a payment or share content) commonly known as "clickjacking", or to convince paid content that it is being shown to the user when it is actually obscured, commonly known in the advertising business as "display fraud".

    Existing anti-clickjacking measures such as frame-busting - scripts and headers granting origin-based embedding permissions have + scripts and headers granting origin-based embedding permissions have shortcomings which prevent their application to important use-cases. - Frame-busting scripts, for example, rely on browser behavior that has not been + Frame-busting scripts, for example, rely on browser behavior that has not been engineered to provide a security guarantee and as a consequence, such scripts may be unreliable if loaded inside a sandbox - or otherwise disabled. The X-Frame-Options header and the frame-ancestors + or otherwise disabled. The X-Frame-Options header and the frame-ancestors Content Security Policy directive offer an all-or-none approach to display of embedded content that is not appropriate for content which may be embedded in arbitrary locations, or known locations which might still be adversarial.

    This document defines mechanisms to allow resources to request to be displayed free of interference by their embedding context and - learn if the user agent was able to satisfy such a request, with + learn if the user agent was able to satisfy such a request, with sufficient granularity to make decisions that can protect both users and content purveyors from various types of fraud.

    First, this document defines an imperative API, VisibilityObserver, @@ -378,7 +451,7 @@

    1.

    The declarative CSP interface does not offer the same fine-granularity control as the JavaScript API. Its goal is to allow protection to be @@ -402,7 +475,7 @@

    1. Distinct from the Intersection Observer proposal, this specification operates internally on entire documents, on a per-iframe basis (although it provides some syntatic sugar for the declarative, - event-driven API) rather than observing individual elements, and it affirmatively modifies the final + event-driven API) rather than observing individual elements, and it affirmatively modifies the final composited result in the global viewport by promoting the graphics layer of an iframe that has requested visibility.

    @@ -410,35 +483,35 @@

    1. 2. Special Conformance Notes

    This section is not normative.

    UI Redressing attacks rely on fooling the subjective perceptions of - human actors to induce them to interact with a web application out of - its intended context. Because of this, the specific mechanisms which - may be used in attack and defense may vary greatly with the details of - a user agent implementation. For example, attacks which rely on - redressing the cursor may not apply in a touch environment, or entire - classes of attack may be impossible on a text-only browser or screen - reader.

    + human actors to induce them to interact with a web application out of + its intended context. Because of this, the specific mechanisms which + may be used in attack and defense may vary greatly with the details of + a user agent implementation. For example, attacks which rely on + redressing the cursor may not apply in a touch environment, or entire + classes of attack may be impossible on a text-only browser or screen + reader.

    Similarly, the implementation of the policies specified herein is highly - dependent on internal architecture and implementation strategies of - the user agent; such strategies may vary greatly between user agents - or even across versions or platforms for a single user agent.

    + dependent on internal architecture and implementation strategies of + the user agent; such strategies may vary greatly between user agents + or even across versions or platforms for a single user agent.

    This specification provides a normative means by which a resource - owner can communicate to a user agent its desire for additional - protective measures, actions to take if violations are detected, - and tuning hints which may be useful for certain means of - implementation. A user agent is conformant if it understands - these directives and makes a best effort to provide the desired - security properties, which might require no additional implementation - steps, e.g. in the case of a screen reader that does not support - embedded resources in a manner that is subject to any of the - attack classes of concern.

    + owner can communicate to a user agent its desire for additional + protective measures, actions to take if violations are detected, + and tuning hints which may be useful for certain means of + implementation. A user agent is conformant if it understands + these directives and makes a best effort to provide the desired + security properties, which might require no additional implementation + steps, e.g. in the case of a screen reader that does not support + embedded resources in a manner that is subject to any of the + attack classes of concern.

    While the indeterminacy of the user agent implementation protects - applications from needing to constantly update their policies as - user agents make internal changes, application authors should - understand that even a conformant user agent cannot make - perfect security guarantees against UI Redressing.

    + applications from needing to constantly update their policies as + user agents make internal changes, application authors should + understand that even a conformant user agent cannot make + perfect security guarantees against UI Redressing.

    These directives should be used as part of a comprehensive risk - mitigation strategy with an appropriate understanding of their - limitations.

    + mitigation strategy with an appropriate understanding of their + limitations.

    3. VisibilityObserver API

    @@ -446,140 +519,128 @@

    3.1. The VisibilityObserverCallback

    -
    callback VisibilityObserverCallback = void(sequence<VisibilityObserverEntry> entries, VisibilityObserver observer)
    +
    callback VisibilityObserverCallback = void(sequence<VisibilityObserverEntry> entries, VisibilityObserver observer);
     

    This callback will be invoked when there are changes to the document’s visibility state.

    3.2. The VisibilityObserverEntry interface

    -
    [Constructor(VisibilityObserverCallback callback, optional VisibilityObserverEntryInit visibilityObserverEntryInit), Exposed=Window]
    -interface VisibilityObserverEntry {
    -  readonly attribute DOMRectReadOnly globalVisibleBounds;
    -  readonly attribute DOMRectReadOnly visibleBounds;
    -  readonly attribute DOMHighResTimeStamp time;
    - };
    +
    [Constructor(VisibilityObserverCallback callback, optional VisibilityObserverEntryInit visibilityObserverEntryInit), Exposed=Window]
    +interface VisibilityObserverEntry {
    +  readonly attribute DOMRectReadOnly globalVisibleBounds;
    +  readonly attribute DOMRectReadOnly visibleBounds;
    +  readonly attribute DOMHighResTimeStamp time;
    +};
     
    -dictionary VisibilityObserverEntryInit {
    -  required DOMRectInit globalVisibleBounds;
    -  required DOMRectInit visibleBounds;
    -  required DOMHighResTimeStamp time;
    +dictionary VisibilityObserverEntryInit {
    +  required DOMRectInit globalVisibleBounds;
    +  required DOMRectInit visibleBounds;
    +  required DOMHighResTimeStamp time;
     };
     
    - globalVisibleBounds The DOMRect coresponding to the visible dimensions of the + globalVisibleBounds The DOMRect coresponding to the visible dimensions of the top-level document in the global viewport’s coordinate space. -

    visibleBounds The DOMRect corresponding to the document’s boundingClientRect, +

    visibleBounds The DOMRect corresponding to the document’s boundingClientRect, intersected by each of the document’s ancestor’s clipping rects, - intersected with globalVisibleBounds. - This value represents the portion of the document actually visible within globalVisibleBounds.

    -

    time A DOMHighResTimeStamp that corresponds to the time the visibility + intersected with globalVisibleBounds. + This value represents the portion of the document actually visible within globalVisibleBounds.

    +

    time A DOMHighResTimeStamp that corresponds to the time the visibility state was recorded.

    3.3. The VisibilityObserver Interface

    The VisibilityObserver interface can be used to observe changes in the document’s visibility state relative to the global viewport. -
    [Constructor(VisibilityObserverCallback callback), Exposed=Window]
    -interface VisibilityObserver {
    -  void observe ();
    -  void unobserve ();
    -  sequence<VisibilityObserverEntry> takeRecords ();
    +
    [Constructor(VisibilityObserverCallback callback), Exposed=Window]
    +interface VisibilityObserver {
    +  void observe ();
    +  void unobserve ();
    +  sequence<VisibilityObserverEntry> takeRecords ();
     };
     
    -
    -

    new VisibilityObserver(callback, options)

    -
    -
    -
    -
    -
      -
    1. Let this be a new VisibilityObserver object -
    2. Set this’s internal [[callback]] slot to callback. -
    -
    -
    -

    observe()

    -
    +
    new VisibilityObserver(callback, options) +
      -
    1. Add this to the document’s [[RegisteredVisibilityObservers]] list +
    2. Let this be a new VisibilityObserver object +
    3. Set this’s internal [[callback]] slot to callback.
    -
    -

    unobserve()

    -
    +
    observe() +
      -
    1. Remove this from the document’s [[RegisteredVisibilityObservers]] set. +
    2. Add this to the document’s [[RegisteredVisibilityObservers]] list
    -
    -

    takeRecords()

    -
    +
    unobserve() +
      -
    1. Let queue be a copy of this’s internal [[QueuedEntries]] slot. -
    2. Clear this’s internal [[QueuedEntries]] slot. +
    3. Remove this from the document’s [[RegisteredVisibilityObservers]] set. +
    +
    takeRecords() +
    +
      +
    1. Let queue be a copy of this’s internal [[QueuedEntries]] slot. +
    2. Clear this’s internal [[QueuedEntries]] slot.
    3. Return queue.

    3.4. The VisibilityObserverInit dictionary

    -
    dictionary VisibilityObserverInit {
    -  (double or sequence<double>) areaThreshold = 0;
    - (boolean) displacementAware = false;
    - (DOMString) visibleMargin = "0px";
    - (Element)? observedElement;
    +
    dictionary VisibilityObserverInit {
    +  (double or sequence<double>) areaThreshold = 0;
    +  (boolean) displacementAware = false;
    +  (DOMString) visibleMargin = "0px";
    +  (Element)? observedElement;
     };
     
    -
    -

    areaThreshold, of type (double or sequence<double>), defaulting to 0

    -
    +
    areaThreshold, of type (double or sequence<double>), defaulting to 0 +

    List of threshold(s) at which to trigger callback. callback will be invoked when visibleBounds area changes from greater than or equal to any threshold to less than that threshold, and vice versa.

    Threshold values must be in the range of [0, 1.0] and represent a -percentage of the area as specified by target.getBoundingClientRect().

    -

    Note: 0.0 is effectively "any non-zero number of pixels".

    -
    -

    displacementAware, of type (boolean), defaulting to false

    -
    +percentage of the area as specified by target.getBoundingClientRect().

    +

    Note: 0.0 is effectively "any non-zero number of pixels".

    +
    displacementAware, of type (boolean), defaulting to false +

    If true, this observer should trigger the callback -when the position of the [[observedElement]] changes relative to the +when the position of the [[observedElement]] changes relative to the global viewport.

    -
    -

    visibleMargin, of type (DOMString), defaulting to "0px"

    -
    -

    Same as margin, extends the required visibility rectangle - behind the protected-element.getBoundingClientRect(). - Can be 1, 2, 3 or 4 components, possibly negative lengths.

    +
    visibleMargin, of type (DOMString), defaulting to "0px" +
    +

    Same as margin, extends the required visibility rectangle +behind the protected-element.getBoundingClientRect(). +Can be 1, 2, 3 or 4 components, possibly negative lengths.

    If there is only one component value, it applies to all sides. - If there are two values, the top and bottom margins are set to - the first value and the right and left margins are set to the - second. If there are three values, the top is set to the first - value, the left and right are set to the second, and the bottom - is set to the third. If there are four values, they apply to the - top, right, bottom, and left, respectively.e.g.

    -
    
    +If there are two values, the top and bottom margins are set to
    +the first value and the right and left margins are set to the
    +second. If there are three values, the top is set to the first
    +value, the left and right are set to the second, and the bottom
    +is set to the third. If there are four values, they apply to the
    +top, right, bottom, and left, respectively.e.g.

    +
    
       "5px"                // all margins set to 5px
       "5px 10px"           // top & bottom = 5px, right & left = 10px
       "-10px 5px 8px"      // top = -10px, right & left = 5px, bottom = 8px
       "-10px -5px 5px 8px" // top = -10px, right = -5px, bottom = 5px, left = 8px
     
    -
    -

    observedElement, of type (Element), nullable

    -
    -

    The Element being observed. If unset, the internal slot will be -initialized to the Document element.

    +
    observedElement, of type (Element), nullable +
    +

    The Element being observed. If unset, the internal slot will be +initialized to the Document element.

    4. Content Security Policy Interface

    This section describes the Content Security Policy - directive introduced in this specification to provide declarative - configuration of protection against input when an element does not meet it’s - visibility requirements.

    + directive introduced in this specification to provide declarative + configuration of protection against input when an element does not meet it’s + visibility requirements.

    The optional directive-value allows configuration of conditions for which violations - will be triggered.

    -

    4.1. The input-protection Directive

    + will be triggered.

    +

    4.1. The input-protection Directive

    directive-name    = 'input-protection'
     directive-value   = ['area-threshold=' num-val]
                         ['protected-element=' id-selector]
    @@ -587,23 +648,23 @@ 

    4.1.1. Directive Value

    -

    area-threshold A violation will be triggered if an event is delivered to the +

    area-threshold A violation will be triggered if an event is delivered to the protected-element or one of its ancestors if the visibility of the protected area is below this threshold.

    Threshold values must be in the range [0, 1.0] and represent a - percentage of the area as specified by protected-element.getBoundingClientRect(), - adjusted by visible-margin. Unlike the imperative API, + percentage of the area as specified by protected-element.getBoundingClientRect(), + adjusted by visible-margin. Unlike the imperative API, only a single value may be specified.

    -

    protected-element A DOMString used as the argument to getElementById() to resolve the Element to which the policy applies.

    -

    If unspecified the policy is applied to the resource’s Document node.

    -

    time-threshold A numeric value in the range [0, 10000] that specifies how long, +

    protected-element A DOMString used as the argument to getElementById() to resolve the Element to which the policy applies.

    +

    If unspecified the policy is applied to the resource’s Document node.

    +

    time-threshold A numeric value in the range [0, 10000] that specifies how long, in milliseconds, the screen area containing the protected-element - must have unmodified viewiability properties when an event is + must have unmodified viewiability properties when an event is delivered to it or one of its ancestors.

    If not specified, it defaults to 800. If a value outside of the range stated above is given, it defaults ot the nearest value between the lower and higher bounds.

    -

    visible-margin Same as visibleMargin.

    +

    visible-margin Same as visibleMargin.

    If unspecified, it defaults to "0px".

    @@ -612,84 +673,86 @@

    5.1. Internal Slot Definitions

    5.1.1. Browsing Contexts

    - Each unit of related similar-origin browsing contexts has an VisibilityObserverTaskQueued flag which + Each unit of related similar-origin browsing contexts has an VisibilityObserverTaskQueued flag which is initialized to false.

    5.1.2. Element

    - Element objects have an internal [[InputProtectionObservers]] list, + Element objects have an internal [[InputProtectionObservers]] list, which is initially empty.

    5.1.3. Document

    - Document objects have an internal [[RegisteredVisibilityObservers]] list, - which is initially empty, and an [[InputProtectionRequested]] flag which is intitially false. + Document objects have an internal [[RegisteredVisibilityObservers]] list, + which is initially empty, and an [[InputProtectionRequested]] flag which is intitially false.

    5.1.4. VisibilityObserver

    - VisibilityObserver objects have the following internal slots: + VisibilityObserver objects have the following internal slots:
      -
    • [[QueuedEntries]] which is initialized to an empty list -
    • [[previousVisibleRatio]] which is initialized to 0 -
    • [[previousGlobalViewportPosition]] +
    • [[QueuedEntries]] which is initialized to an empty list +
    • [[previousVisibleRatio]] which is initialized to 0 +
    • [[previousGlobalViewportPosition]]
    - As well as internal slots initialized by VisibilityObserver(callback,options): + As well as internal slots initialized by VisibilityObserver(callback,options):
      -
    • [[callback]] -
    • [[areaThreshold]] -
    • [[displacementAware]] -
    • [[visibleMargin]] -
    • [[observedElement]] which is - initialized to the Document Element if not set in the VisibilityObserverInit dictionary +
    • [[callback]] +
    • [[areaThreshold]] +
    • [[displacementAware]] +
    • [[visibleMargin]] +
    • [[observedElement]] which is + initialized to the Document Element if not set in the VisibilityObserverInit dictionary
    - The following internal slots will be initialzed to null unless the - object was constructed to represent an input-protection directive. + The following internal slots will be initialzed to null unless the + object was constructed to represent an input-protection directive.
      -
    • [[timeThreshold]] -
    • [[associatedContentSecurityPolicy]] +
    • [[timeThreshold]] +
    • [[associatedContentSecurityPolicy]]

    5.2. Algorithms

    5.2.1. Queue a VisibilityObserver Task

    - To queue a visibility observer task for a unit of related similar-origin browsing contexts unit, + To queue a visibility observer task for a unit of related similar-origin browsing contexts unit, run these steps:
      -
    1. If unit’s VisibilityObserverTaskQueued flag is set to +
    2. If unit’s VisibilityObserverTaskQueued flag is set to true, return. -
    3. Set unit’s VisibilityObserverTaskQueued flag to true. +
    4. Set unit’s VisibilityObserverTaskQueued flag to true.
    5. - Post a task to notify visibility observers, or enqueue a - task to notify visibility observers in the list of idle request callbacks with an appropriate timeout. -

      Should we define an appropriate timeout?

      + Post a task to notify visibility observers, or enqueue a + task to notify visibility observers in the list of idle request callbacks with an appropriate timeout. +

      Should we define an appropriate timeout?

    5.2.2. Notify VisibilityObservers

    - To notify visibility observers for a unit of related similar-origin browsing contexts unit, + To notify visibility observers for a unit of related similar-origin browsing contexts unit, run these steps:
      -
    1. Set unit’s VisibilityObserverTaskQueued flag to false. -
    2. For each Document document in unit -
        -
      1. Let notify list be a copy of document’s [[RegisteredVisibilityObservers]] list. -
      2. For each VisibilityObserver object observer in notify list, run these steps: +
      3. Set unit’s VisibilityObserverTaskQueued flag to false. +
      4. + For each Document document in unit
          -
        1. If observer’s internal [[QueuedEntries]] slot is - empty, continue. -
        2. Let queue be a copy of observer’s internal [[QueuedEntries]] slot. -
        3. Clear observer’s internal [[QueuedEntries]] slot. -
        4. Invoke callback with queue as the first argument and observer as the second argument and callback this value. If this throws an exception, report the exception. +
        5. Let notify list be a copy of document’s [[RegisteredVisibilityObservers]] list. +
        6. + For each VisibilityObserver object observer in notify list, run these steps: +
            +
          1. If observer’s internal [[QueuedEntries]] slot is + empty, continue. +
          2. Let queue be a copy of observer’s internal [[QueuedEntries]] slot. +
          3. Clear observer’s internal [[QueuedEntries]] slot. +
          4. Invoke callback with queue as the first argument and observer as the second argument and callback this value. If this throws an exception, report the exception. +
        -

    5.2.3. Queue a VisibilityObserverEntry

    - To queue a VisibilityObserverEntry for observer, given a unit of related similar-origin browsing contexts unit, VisibilityObserver observer, and VisibilityObserverEntry entry run these steps: + To queue a VisibilityObserverEntry for observer, given a unit of related similar-origin browsing contexts unit, VisibilityObserver observer, and VisibilityObserverEntry entry run these steps:
      -
    1. Append entry to observer’s internal [[QueuedEntries]] slot. -
    2. Queue a visibility observer task for unit. +
    3. Append entry to observer’s internal [[QueuedEntries]] slot. +
    4. Queue a visibility observer task for unit.

    5.2.4. Promote Observed GraphicsLayers

    This section is non-normative.

    - NOTE: The full internal details of rendering a document to the pixels - actually displayed to the user is not standardized. UA implementations + NOTE: The full internal details of rendering a document to the pixels + actually displayed to the user is not standardized. UA implementations may vary widely.

    The implementation strategy detailed in this section is not normative. Any - strategy which produces correct outcomes for the normative algorithms is + strategy which produces correct outcomes for the normative algorithms is conformant and implementers are encouraged to optimize whenever possible.

    The possibility of variance among user agent implementations notwithstanding, - the normative algorithms of this specification are designed such that a highly performant + the normative algorithms of this specification are designed such that a highly performant implementation should be possible on the most common internal software and hardware architectures that are state-of-the-art for user agents and consumer computing platforms as of the time of writing.

    @@ -698,134 +761,140 @@

    Generally, at some point in the rendering of a set of documents in nested browsing contexts into the fully composed graphical representation in the global viewport, - a user agent will arrive at a set of intermediate representations we will designate - as GraphicsLayers, each of which represents a graphical surface to be + a user agent will arrive at a set of intermediate representations we will designate + as GraphicsLayers, each of which represents a graphical surface to be painted / clipped / scrolled.

    -

    A GraphicsLayer representing the contents of a document in an iframe will - be arranged in the layer stack such that at a later phase in the rendering - it is automatically clipped and positioned relative to the series of viewports +

    A GraphicsLayer representing the contents of a document in an iframe will + be arranged in the layer stack such that at a later phase in the rendering + it is automatically clipped and positioned relative to the series of viewports above it, and also subject to being drawn over or transformed by the layers above it.

    -

    To prevent potentially malicious composition, the user agent can promote observed graphicsLayers by manipulating them such that - a document with [[RegisteredVisibilityObservers]]

    +

    To prevent potentially malicious composition, the user agent can promote observed graphicsLayers by manipulating them such that + a document with [[RegisteredVisibilityObservers]]

      -
    • Is clipped and positioned as-if-unmodified within the set of viewports of its ancestor - browsing contexts. A promoted document should not be able to occupy more - screen real estate than it is given by its embedding contexts. +
    • Is clipped and positioned as-if-unmodified within the set of viewports of its ancestor + browsing contexts. A promoted document should not be able to occupy more + screen real estate than it is given by its embedding contexts.
    • Responds to hit testing and events as-if-unmodified. Implementation-specific modifications - to internal representations of the document should not change the behavior of the DOM. -
    • Is not subject to being drawn over or transformed by any other GraphicsLayers, - except other promoted layers, which should be treated as fully opaque occlusions - when reporting the visibility state of the document. + to internal representations of the document should not change the behavior of the DOM. +
    • Is not subject to being drawn over or transformed by any other GraphicsLayers, + except other promoted layers, which should be treated as fully opaque occlusions + when reporting the visibility state of the document.
    -

    To promote observed graphicsLayers, given a time now, and an initially empty list promotedLayers, run these steps during the rendering - loop at the stage where the intermediate representation of a set of Documents is a set of GraphicsLayers graphicsLayers.

    +

    To promote observed graphicsLayers, given a time now, and an initially empty list promotedLayers, run these steps during the rendering + loop at the stage where the intermediate representation of a set of Documents is a set of GraphicsLayers graphicsLayers.

    1. For each graphicsLayer in graphicsLayers -
    2. For each Document document with an intermediate representation in graphicsLayer -
        -
      1. If document has an empty list of [[RegisteredVisibilityObservers]], continue. -
      2. If document has a non-empty list of [[RegisteredVisibilityObservers]] -
          -
        1. If document is not the only Document represented in graphicsLayer, apply - whatever implementation-specific steps are necessary to place it in its own layer. - (e.g. apply translatez(0) to the documentElement) Let graphicsLayer be that - new layer. -
        -
      3. Let rectToRaise be the value of document.getBoundingClientRect(). -
      4. Intersect rectToRaise with document’s viewport clip rect. -
      5. For every parent browsing context parent between document and the top-level document, - intersect rectToRaise with parent’s viewport clip rect, - and finally with the global viewport clip rect. -
      6. Clip graphicsLayer to rectToRaise. (graphicsLayer may have zero width and height - if it is scrolled off screen by an ancestor browsing context) -
      7. Intersect rectToRaise with any items in the promotedLayers list. -
      8. Add rectToRaise to the promotedLayers list. -
      9. Without reordering prior intermediate representations in a manner which would - change event dispatching, hit testing, or the DOM as exposed to JavaScript, reorder - the GraphicsLayers such that rectToRaise is on top of the root GraphicsLayer. - (e.g. by making it a direct child of the root layer) but beneath any layers in promotedLayers that clipped it. -
      10. Let protectedRect be the value of observer’s [[observedElement]].getBoundingClientRect(), - adjusted by [[visibleMargin]]. -
      11. Let visibleRatio be the intersection of protectedRect with rectToRaise, divided by protectedRect if protectedRect is non-zero, and 0 otherwise. -
      12. For each of document’s [[RegisteredVisibilityObservers]] observer +
      13. + For each Document document with an intermediate representation in graphicsLayer
          -
        1. Let threshold be the index of the first entry in observer’s internal [[areaThreshold]] slot whose value - is greater than or equal to visibleRatio. If visibleRatio is equal to 0, let threshold be -1. -
        2. Let oldVisibleRatio be set to observer’s internal [[previousVisibleRatio]] slot. -
        3. Let oldThreshold be the index of the first entry in observer’s internal [[areaThreshold]] slot whose value - is greater than or equal to oldVisibleRatio. If oldVisibleRatio is equal to 0, let oldThreshold be -1. -
        4. Let oldPosition be the value of the observer’s internal [[previousGlobalViewportPosition]]. -
        5. If threshold does not equal oldThreshold, or if observer’s - internal [[displacementAware]] slot is true and oldPosition is not equal to protectedRect, - +
        6. If document has an empty list of [[RegisteredVisibilityObservers]], continue. +
        7. + If document has a non-empty list of [[RegisteredVisibilityObservers]] +
            +
          1. If document is not the only Document represented in graphicsLayer, apply + whatever implementation-specific steps are necessary to place it in its own layer. + (e.g. apply translatez(0) to the documentElement) Let graphicsLayer be that + new layer. +
          +
        8. Let rectToRaise be the value of document.getBoundingClientRect(). +
        9. Intersect rectToRaise with document’s viewport clip rect. +
        10. For every parent browsing context parent between document and the top-level document, + intersect rectToRaise with parent’s viewport clip rect, + and finally with the global viewport clip rect. +
        11. Clip graphicsLayer to rectToRaise. (graphicsLayer may have zero width and height + if it is scrolled off screen by an ancestor browsing context) +
        12. Intersect rectToRaise with any items in the promotedLayers list. +
        13. Add rectToRaise to the promotedLayers list. +
        14. Without reordering prior intermediate representations in a manner which would + change event dispatching, hit testing, or the DOM as exposed to JavaScript, reorder + the GraphicsLayers such that rectToRaise is on top of the root GraphicsLayer. + (e.g. by making it a direct child of the root layer) but beneath any layers in promotedLayers that clipped it. +
        15. Let protectedRect be the value of observer’s [[observedElement]].getBoundingClientRect(), + adjusted by [[visibleMargin]]. +
        16. Let visibleRatio be the intersection of protectedRect with rectToRaise, divided by protectedRect if protectedRect is non-zero, and 0 otherwise. +
        17. + For each of document’s [[RegisteredVisibilityObservers]] observer +
            +
          1. Let threshold be the index of the first entry in observer’s internal [[areaThreshold]] slot whose value + is greater than or equal to visibleRatio. If visibleRatio is equal to 0, let threshold be -1. +
          2. Let oldVisibleRatio be set to observer’s internal [[previousVisibleRatio]] slot. +
          3. Let oldThreshold be the index of the first entry in observer’s internal [[areaThreshold]] slot whose value + is greater than or equal to oldVisibleRatio. If oldVisibleRatio is equal to 0, let oldThreshold be -1. +
          4. Let oldPosition be the value of the observer’s internal [[previousGlobalViewportPosition]]. +
          5. + If threshold does not equal oldThreshold, or if observer’s + internal [[displacementAware]] slot is true and oldPosition is not equal to protectedRect, + +
        -

    find exact terms to make sure that we have viewport definitions minus scrollbars

    need to also clip to any other layers that were promoted ahead of us!

    -

    if a parent and child layer both request to be promoted, the parent’s clipping window will have a complex geometry with holes in it that is not accounted for by this algorithm. Likely need to specify that graphics layers be processed by order of depth.

    +

    if a parent and child layer both request to be promoted, the parent’s clipping window will have a complex geometry with holes in it that is not accounted for by this algorithm. Likely need to specify that graphics layers be processed by order of depth.

    5.2.5. Enforce An input-protection Directive

    - To enforce an input-protection directive for a Document document, + To enforce an input-protection directive for a Document document, run the following steps:
    1. Parse the policy according to [CSP2]. -
    2. If a value is set for protected-element, let protectedElement be the Element returned by invoking document.getElementById() with - the value as the input, or document if null or unset. -
    3. If document’s [[InputProtectionRequested]] flag is false, set it - to true. -
    4. Construct a new VisibilityObserver observer, with [[areaThreshold]] set to the value of area-threshold, [[visibleMargin]] set to the value of visible-margin, [[observedElement]] set to protectedElement, [[displacementAware]] set to true, - and [[callback]] set to a new function with an empty function body. -
    5. Set the internal [[timeThreshold]] slot of observer to the value of time-threshold -
    6. Set the internal [[associatedContentSecurityPolicy]] slot of observer to a reference to the - Content Security Policy which the input-protection directive is associated with. -
    7. When dispatching events, when an Element element will handle an Event event, - if event is of type Mouse Event, Pointer Event, Drag-and-Drop, or Clipboard Event, (TODO:linkify) - and if element has [[InputProtectionObservers]] observers: -
        -
      1. If applicable, check the computed style for the cursor. If a cursor is typically displayed but - has been hidden or changed to a non-standard bitmap, handle a violation for event and each observer in observers. -
      2. Otherwise, for each observer in observers: +
      3. If a value is set for protected-element, let protectedElement be the Element returned by invoking document.getElementById() with + the value as the input, or document if null or unset. +
      4. If document’s [[InputProtectionRequested]] flag is false, set it + to true. +
      5. Construct a new VisibilityObserver observer, with [[areaThreshold]] set to the value of area-threshold, [[visibleMargin]] set to the value of visible-margin, [[observedElement]] set to protectedElement, [[displacementAware]] set to true, + and [[callback]] set to a new function with an empty function body. +
      6. Set the internal [[timeThreshold]] slot of observer to the value of time-threshold +
      7. Set the internal [[associatedContentSecurityPolicy]] slot of observer to a reference to the + Content Security Policy which the input-protection directive is associated with. +
      8. + When dispatching events, when an Element element will handle an Event event, + if event is of type Mouse Event, Pointer Event, Drag-and-Drop, or Clipboard Event, (TODO:linkify) + and if element has [[InputProtectionObservers]] observers:
          -
        1. If observer’s [[previousVisibleRatio]] is less than [[areaThreshold]], handle a violation for observer. -
        2. If observer’s [[previousVisibleRatio]] is greater than [[areaThreshold]], - get the most recent VisibilityObserverEntry entry from observer’s [[QueuedEntries]]. If the difference between entry.time and now is less than [[timeThreshold]], handle a violation for observer. +
        3. If applicable, check the computed style for the cursor. If a cursor is typically displayed but + has been hidden or changed to a non-standard bitmap, handle a violation for event and each observer in observers. +
        4. + Otherwise, for each observer in observers: +
            +
          1. If observer’s [[previousVisibleRatio]] is less than [[areaThreshold]], handle a violation for observer. +
          2. If observer’s [[previousVisibleRatio]] is greater than [[areaThreshold]], + get the most recent VisibilityObserverEntry entry from observer’s [[QueuedEntries]]. If the difference between entry.time and now is less than [[timeThreshold]], handle a violation for observer. +
        -

    5.2.6. Handle a Violation

    - To handle a violation of an input-protection directive for observer and event, run the following steps: + To handle a violation of an input-protection directive for observer and event, run the following steps:

    5.3. External Spec Integrations

    5.3.1. HTML Processing Model: Event Loop

    - As part of substep 10 of the update the rendering event loop in the HTML Processing Model, Promote Observed GraphicsLayers, passing in now as the timestamp. + As part of substep 10 of the update the rendering event loop in the HTML Processing Model, Promote Observed GraphicsLayers, passing in now as the timestamp.

    5.3.2. DOM: Dispatching Events

    As part of dispatching events in the DOM Standard, add a substep to step 5, ("For each object in event path..."), - invoking step 7 of enforce an input-protection directive before proceeding to + invoking step 7 of enforce an input-protection directive before proceeding to "invoke object with event".

    5.3.3. isUnsafe Attribute

    -
    partial interface Event {
    -  readonly attribute boolean isUnsafe;
    +
    partial interface Event {
    +  readonly attribute boolean isUnsafe;
     };
     
    -
    isUnsafe, of type boolean, readonly +
    isUnsafe, of type boolean, readonly
    Will be set to true if the event fired when the event did not meet the document’s input-protection requirements.
    @@ -846,11 +915,11 @@

    7. Security Considerations

    This section is non-normative.

    UI Redressing and Clickjacking attacks rely on violating the contextual and temporal - integrity of embedded content. Because these attacks target the subjective perception - of the user and not well-defined security boundaries, the heuristic protections - afforded by the input-protection directive can never be 100% effective for every - interface. It provides no protection against certain classes of attacks, such as - displaying content around an embedded resource that appears to extend a trusted + integrity of embedded content. Because these attacks target the subjective perception + of the user and not well-defined security boundaries, the heuristic protections + afforded by the input-protection directive can never be 100% effective for every + interface. It provides no protection against certain classes of attacks, such as + displaying content around an embedded resource that appears to extend a trusted dialog but provides misleading information.

    When used as a mechanism to report visibility for purposes of monetizing content, operators should be aware that a malicious or modified user agent can always report @@ -884,8 +953,8 @@

    Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

    -
    - +
    +

    This is an example of an informative example.

    Informative notes begin with the word “Note” and are set apart from the @@ -910,14 +979,14 @@

    areaThreshold, in §3.4
  • [[associatedContentSecurityPolicy]], in §5.1.4
  • [[callback]], in §5.1.4 -
  • displacementAware, in §3.4
  • [[displacementAware]], in §5.1.4 +
  • displacementAware, in §3.4
  • enforce an input-protection directive, in §5.2.5
  • globalVisibleBounds
  • GraphicsLayer, in §5.2.4
  • handle a violation, in §5.2.6 @@ -927,8 +996,8 @@

    isUnsafe, in §5.3.3
  • notify visibility observers, in §5.2.2
  • observe(), in §3.3 -
  • observedElement, in §3.4
  • [[observedElement]], in §5.1.4 +
  • observedElement, in §3.4
  • [[previousGlobalViewportPosition]], in §5.1.4
  • [[previousVisibleRatio]], in §5.1.4
  • promote observed graphicsLayers, in §5.2.4 @@ -941,117 +1010,225 @@

    dict-member for VisibilityObserverEntryInit, in §3.2
  • attribute for VisibilityObserverEntry, in §3.2 +
  • dict-member for VisibilityObserverEntryInit, in §3.2
  • [[timeThreshold]], in §5.1.4
  • time-threshold, in §4.1.1
  • unobserve(), in §3.3
  • VisibilityObserver, in §3.3
  • VisibilityObserverCallback, in §3.1 -
  • VisibilityObserver(callback), in §3.3 -
  • VisibilityObserver(callback, options), in §3.3 +
  • VisibilityObserver(callback, options), in §3.3
  • VisibilityObserverEntry, in §3.2 -
  • VisibilityObserverEntry(callback), in §3.2 -
  • VisibilityObserverEntry(callback, visibilityObserverEntryInit), in §3.2
  • VisibilityObserverEntryInit, in §3.2
  • VisibilityObserverInit, in §3.4
  • VisibilityObserverTaskQueued, in §5.1.1
  • visibleBounds -
  • visible-margin, in §4.1.1
  • [[visibleMargin]], in §5.1.4 +
  • visible-margin, in §4.1.1
  • visibleMargin, in §3.4 + + + + + + + + + + + + + + +

    Terms defined by reference

    References

    Normative References

    [CSP2] -
    Mike West; Adam Barth; Daniel Veditz. Content Security Policy Level 2. 21 July 2015. CR. URL: http://www.w3.org/TR/CSP2/ -
    [CSS2] -
    Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 7 June 2011. REC. URL: http://www.w3.org/TR/CSS2 +
    Mike West; Adam Barth; Daniel Veditz. Content Security Policy Level 2. 15 December 2016. REC. URL: https://www.w3.org/TR/CSP2/ +
    [CSS-BOX-4] +
    Elika Etemad. CSS Box Model Module Level 4. 21 April 2020. WD. URL: https://www.w3.org/TR/css-box-4/
    [CSSOM-VIEW-1] -
    Simon Pieters. CSSOM View Module. 17 March 2016. WD. URL: http://www.w3.org/TR/cssom-view-1/ +
    Simon Pieters. CSSOM View Module. 17 March 2016. WD. URL: https://www.w3.org/TR/cssom-view-1/ +
    [DOM] +
    Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
    [GEOMETRY-1] -
    Simon Pieters; Dirk Schulze; Rik Cabanier. Geometry Interfaces Module Level 1. 25 November 2014. CR. URL: http://www.w3.org/TR/geometry-1/ +
    Simon Pieters; Chris Harrelson. Geometry Interfaces Module Level 1. 4 December 2018. CR. URL: https://www.w3.org/TR/geometry-1/
    [RFC2119]
    S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119 -
    [WebIDL-1] -
    Cameron McCormack; Boris Zbarsky. WebIDL Level 1. 8 March 2016. CR. URL: http://www.w3.org/TR/WebIDL-1/ -
    [WHATWG-DOM] -
    Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/ +
    [WebIDL] +
    Boris Zbarsky. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/

    IDL Index

    -
    callback VisibilityObserverCallback = void(sequence<VisibilityObserverEntry> entries, VisibilityObserver observer)
    +
    callback VisibilityObserverCallback = void(sequence<VisibilityObserverEntry> entries, VisibilityObserver observer);
     
    -[Constructor(VisibilityObserverCallback callback, optional VisibilityObserverEntryInit visibilityObserverEntryInit), Exposed=Window]
    -interface VisibilityObserverEntry {
    -  readonly attribute DOMRectReadOnly globalVisibleBounds;
    -  readonly attribute DOMRectReadOnly visibleBounds;
    -  readonly attribute DOMHighResTimeStamp time;
    - };
    +[Constructor(VisibilityObserverCallback callback, optional VisibilityObserverEntryInit visibilityObserverEntryInit), Exposed=Window]
    +interface VisibilityObserverEntry {
    +  readonly attribute DOMRectReadOnly globalVisibleBounds;
    +  readonly attribute DOMRectReadOnly visibleBounds;
    +  readonly attribute DOMHighResTimeStamp time;
    +};
     
    -dictionary VisibilityObserverEntryInit {
    -  required DOMRectInit globalVisibleBounds;
    -  required DOMRectInit visibleBounds;
    -  required DOMHighResTimeStamp time;
    +dictionary VisibilityObserverEntryInit {
    +  required DOMRectInit globalVisibleBounds;
    +  required DOMRectInit visibleBounds;
    +  required DOMHighResTimeStamp time;
     };
     
    -[Constructor(VisibilityObserverCallback callback), Exposed=Window]
    -interface VisibilityObserver {
    -  void observe ();
    -  void unobserve ();
    -  sequence<VisibilityObserverEntry> takeRecords ();
    +[Constructor(VisibilityObserverCallback callback), Exposed=Window]
    +interface VisibilityObserver {
    +  void observe ();
    +  void unobserve ();
    +  sequence<VisibilityObserverEntry> takeRecords ();
     };
     
    -dictionary VisibilityObserverInit {
    -  (double or sequence<double>) areaThreshold = 0;
    - (boolean) displacementAware = false;
    - (DOMString) visibleMargin = "0px";
    - (Element)? observedElement;
    +dictionary VisibilityObserverInit {
    +  (double or sequence<double>) areaThreshold = 0;
    +  (boolean) displacementAware = false;
    +  (DOMString) visibleMargin = "0px";
    +  (Element)? observedElement;
     };
     
    -partial interface Event {
    -  readonly attribute boolean isUnsafe;
    +partial interface Event {
    +  readonly attribute boolean isUnsafe;
     };
     
     
    @@ -1059,353 +1236,352 @@

    Do we need to deal with form submission / navigations that aren’t JS-event-based?
    how to interact with frame-ancestors and XFO?
    -
    Should we define an appropriate timeout?
    +
    Should we define an appropriate timeout?
    find exact terms to make sure that we have viewport definitions minus scrollbars
    need to also clip to any other layers that were promoted ahead of us!
    -
    if a parent and child layer both request to be promoted, the parent’s clipping window will have a complex geometry with holes in it that is not accounted for by this algorithm. Likely need to specify that graphics layers be processed by order of depth.
    +
    if a parent and child layer both request to be promoted, the parent’s clipping window will have a complex geometry with holes in it that is not accounted for by this algorithm. Likely need to specify that graphics layers be processed by order of depth.

  • -