From 72015628c4ddc2bc484da620e12d2b8b70ef8353 Mon Sep 17 00:00:00 2001 From: Mike West Date: Mon, 1 Aug 2016 15:32:23 +0200 Subject: [PATCH] Move 'frame-ancestors' processing to navigation (whatwg/html#1230) This introduces a new 'navigation check', which we'll need to wire up to HTML. That, in turn, requires HTML to use Fetch. WHATWG's does, W3C's does not (w3c/html#548). --- index.html | 224 +++++++++++++++++++++++++++++++------------------ index.src.html | 100 ++++++++++++++++------ 2 files changed, 218 insertions(+), 106 deletions(-) diff --git a/index.html b/index.html index 5e11f9bd22..cffde8f20b 100644 --- a/index.html +++ b/index.html @@ -1534,6 +1534,7 @@

Table of Contents

  • 4.2.1 Initialize a Document's CSP list
  • 4.2.2 Initialize a global object’s CSP list
  • 4.2.3 Should element’s inline type behavior be blocked by Content Security Policy? +
  • 4.2.4 Should navigation response in context be blocked by Content Security Policy?
  • 4.3 Integration with ECMAScript @@ -1662,7 +1663,7 @@

    Table of Contents

  • 6.3.2 frame-ancestors
      -
    1. 6.3.2.1 Algorithms +
    2. 6.3.2.1 frame-ancestors Navigation Check
  • @@ -1913,7 +1914,7 @@

    RWS is defined in section 3.2.3 of RFC7230. ALPHA, DIGIT, and ; VCHAR are defined in Appendix B.1 of RFC 5234. -

    Directives have five associated algorithms:

    +

    Directives have six associated algorithms:

    1. A pre-request check, which takes a request and a policy as an argument, and is executed during §4.1.3 Should request be blocked by Content Security Policy?. This algorithm returns "Allowed" unless @@ -1933,9 +1934,13 @@

      §4.2.3 Should element’s inline type behavior be blocked by Content Security Policy?. This algorithm returns "Allowed" unless otherwise specified.

    2. -

      An initialization, which takes a Document or global object, a response, and a policy as +

      An initialization, which takes a Document or global object, a response, and a policy as arguments. This algorithm is executed during §4.2.1 Initialize a Document's CSP list, and has no effect unless otherwise specified.

      +
    3. +

      A navigation check, which takes a response and a browsing context as arguments, and is executed + during process a navigate response. It returns "Allowed" unless + otherwise specified.

    2.2.1. Source Lists

    Many directives' values consist of source lists: sets @@ -2004,9 +2009,9 @@

    URL matches a source list if the algorithm in §6.1.13.3 Does url match source list? returns Matches.

    2.3. Violations

    A violation represents an action or resource which goes against the - set of policy objects associated with a global object.

    + set of policy objects associated with a global object.

    Each violation has a global object, which - is the global object whose policy has been violated.

    + is the global object whose policy has been violated.

    Each violation has a url which is its global object’s URL.

    Each violation has a status which is a non-negative integer representing the HTTP status code of the resource for @@ -2026,7 +2031,7 @@

    Each violation has a column number, which is a non-negative integer.

    2.3.1. Create a violation object for global, policy, and directive

    -

    Given a global object (global), a policy (policy), and a +

    Given a global object (global), a policy (policy), and a string (directive), the following algorithm creates a new violation object, and populates it with an initial set of data:

    1. @@ -2160,9 +2165,9 @@

      is called as part of step #13 of its Main Fetch algorithm.

    -

    A policy is generally enforced upon a global object, but the +

    A policy is generally enforced upon a global object, but the user agent needs to parse any policy - delivered via an HTTP response header field before any global object is created in order to handle directives that require knowledge of a response’s details. To that end:

    + delivered via an HTTP response header field before any global object is created in order to handle directives that require knowledge of a response’s details. To that end:

    1. A response has an associated CSP list which @@ -2299,12 +2304,12 @@

      §4.2.2 Initialize a global object’s CSP list algorithm.

      This concept is missing from W3C’s Workers. <https://github.com/w3c/html/issues/187>

    2. -

      A policy is enforced or monitored for a global object by inserting it into the global object’s CSP list.

      +

      A policy is enforced or monitored for a global object by inserting it into the global object’s CSP list.

    3. §4.2.2 Initialize a global object’s CSP list is called during the initialising a new Document object and run a worker algorithms in order to bind a set of policy objects associated with a response to a - newly created global object.

      + newly created global object.

    4. §4.2.3 Should element’s inline type behavior be blocked by Content Security Policy? is called during the prepare a script and update a style block algorithms in order to determine whether or not an inline script or style block is allowed to execute/render.

      @@ -2335,6 +2340,12 @@

      This hook is missing from WHATWG’s HTML. <https://github.com/whatwg/html/issues/1618>

      This hook is missing from W3C’s HTML. <https://github.com/w3c/html/issues/547>

      +
    5. +

      §4.2.4 Should navigation response in context be blocked by Content Security Policy? is called during the process a navigate + response algorithm to apply directive’s navigation check.

      +

      Upstream this to HTML. <https://github.com/whatwg/html/issues/1230>

      +

      W3C’s HTML is not based on Fetch, and does not + have a process a navigate response algorithm into which to hook. <https://github.com/w3c/html/issues/548>

    4.2.1. Initialize a Document's CSP list

    Given a Document (document), and a response (response), the @@ -2378,7 +2389,7 @@

    4.2.2. Initialize a global object’s CSP list

    -

    Given a global object (global), and a response (response), the user agent performs the following steps in order +

    Given a global object (global), and a response (response), the user agent performs the following steps in order to initialize global’s CSP list:

    1. @@ -2392,7 +2403,7 @@

      -

      For each policy in document’s global +

      For each policy in document’s global object’s CSP list:

      1. @@ -2414,7 +2425,7 @@

        Let result be "Allowed".

      2. -

        For each policy in element’s Document's global object’s CSP list:

        +

        For each policy in element’s Document's global object’s CSP list:

        1. For each directive in policy:

          @@ -2424,15 +2435,47 @@

          Allowed" when executed upon element, type, and source, skip to the next directive.

        2. -

          Otherwise, let violation be the result of executing §2.3.1 Create a violation object for global, policy, and directive on the incumbent settings - object, policy, and "style-src" if type is "style" or - "style-attribute", or "script-src" otherwise.

          +

          Otherwise, let violation be the result of executing §2.3.1 Create a violation object for global, policy, and directive on the current settings + object’s global object, policy, + and "style-src" if type is "style" or "style-attribute", + or "script-src" otherwise.

        3. Set violation’s resource to "inline".

        4. Execute §5.3 Report a violation on violation.

        5. If policy’s disposition is "enforce", then + set result to "Blocked".

          +
        +
      +
    2. +

      Return result.

      +
    +

    4.2.4. Should navigation response in context be blocked by Content Security Policy?

    +

    Given a response navigation response, and a browsing context (context), this algorithm returns "Blocked" if the active policy blocks + the navigation, and "Allowed" otherwise:

    +
      +
    1. +

      Let result be "Allowed".

      +
    2. +

      For each policy in navigation response’s CSP list:

      +
        +
      1. +

        For each directive in policy:

        +
          +
        1. +

          If directive’s navigation check returns + "Allowed" when executed upon navigation response and context, + skip to the next directive.

          +
        2. +

          Otherwise, let violation be the result of executing §2.3.1 Create a violation object for global, policy, and directive on null, policy, and directive’s name.

          +
        3. +

          Set violation’s resource to navigation + response’s URL.

          +
        4. +

          Execute §5.3 Report a violation on violation.

          +
        5. +

          If policy’s disposition is "enforce", then set result to "Blocked".

      @@ -2460,8 +2503,8 @@

      Let source-list be null.

    3. -

      If policy contains a directive whose name is "script-src", then set source-list to that directive’s value.

      -

      Otherwise if policy contains a directive whose name is "default-src", then set source-list to that directive’s value.

      +

      If policy contains a directive whose name is "script-src", then set source-list to that directive’s value.

      +

      Otherwise if policy contains a directive whose name is "default-src", then set source-list to that directive’s value.

    4. If source-list is non-null, and does not contain a source expression which is an ASCII case-insensitive match for the @@ -2523,7 +2566,7 @@

      "blocked-uri"

      -

      The result of executing the URL serializer on violation’s resource, with the exclude fragment flag set.

      +

      The result of executing the URL serializer on violation’s resource, with the exclude fragment flag set.

      "effective-directive"

      @@ -2576,7 +2619,7 @@

      blockedURI

      -

      violation’s resource

      +

      violation’s resource

      effectiveDirective

      @@ -2789,10 +2832,10 @@

      If name is not frame-src or worker-src, return "Allowed".

    5. -

      If policy contains a directive whose name is name, return "Allowed"

      +

      If policy contains a directive whose name is name, return "Allowed"

    6. Return the result of executing the pre-request - check for the directive whose name is name on request and policy, using this directive’s value for the comparison.

      + check for the directive whose name is name on request and policy, using this directive’s value for the comparison.

    This directive’s post-request check is as follows:

    Given a request (request), a response (response), and a policy (policy):

    @@ -2802,10 +2845,10 @@

    If name is not frame-src or worker-src, return "Allowed".

  • -

    If policy contains a directive whose name is name, return "Allowed"

    +

    If policy contains a directive whose name is name, return "Allowed"

  • Return the result of executing the post-request - check for the directive whose name is name on request and policy, using this directive’s value for the comparison.

    + check for the directive whose name is name on request and policy, using this directive’s value for the comparison.

    6.1.2. connect-src

    The connect-src directive restricts the URLs which can be loaded @@ -2938,15 +2981,15 @@

    If name is null, return "Allowed".

  • -

    If policy contains a directive whose name is name, return "Allowed".

    +

    If policy contains a directive whose name is name, return "Allowed".

  • -

    If name is "frame-src" or "worker-src", and policy contains a directive whose name is "child-src", +

    If name is "frame-src" or "worker-src", and policy contains a directive whose name is "child-src", return "Allowed".

    Note: It would be lovely to remove this special case. Perhaps "effective directive" could return "child-src" and that could delegate out in the same way this algorithm does?

  • -

    Otherwise, return the result of executing the pre-request check for the directive whose name is name on request and policy, using +

    Otherwise, return the result of executing the pre-request check for the directive whose name is name on request and policy, using this directive’s value for the comparison.

    This directive’s post-request check is as follows:

    @@ -2957,15 +3000,15 @@

    If name is null, return "Allowed".

  • -

    If policy contains a directive whose name is name, return "Allowed".

    +

    If policy contains a directive whose name is name, return "Allowed".

  • -

    If name is "frame-src" or "worker-src", and policy contains a directive whose name is "child-src", +

    If name is "frame-src" or "worker-src", and policy contains a directive whose name is "child-src", return "Allowed".

    Note: It would be lovely to remove this special case. Perhaps "effective directive" could return "child-src" and that could delegate out in the same way this algorithm does?

  • -

    Otherwise, return the result of executing the post-request check for the directive whose name is name on request and policy, using +

    Otherwise, return the result of executing the post-request check for the directive whose name is name on request and policy, using this directive’s value for the comparison.

    6.1.4. font-src

    @@ -3752,7 +3795,7 @@
    6.1.13.5. Get the effective directive for request

    Each fetch directive controls a specific type of request. Given - a request (request), the following algorithm returns either null or the name of the request’s effective directive:

    + a request (request), the following algorithm returns either null or the name of the request’s effective directive:

    1. Switch on request’s type, and execute @@ -3941,12 +3984,12 @@

      Allowed" if base may be used as the value of a base element’s href attribute, and "Blocked" otherwise:

      1. -

        For each policy in document’s global object’s csp list:

        +

        For each policy in document’s global object’s csp list:

        1. Let source list be null.

        2. -

          If a directive whose name is +

          If a directive whose name is "base-uri" is present in policy’s directive set, set source list to that directive’s value.

        3. @@ -3955,14 +3998,14 @@
          §6.1.13.3 Does url match source list? on base and source list is "Does Not Match":

          1. -

            Let violation be the result of executing §2.3.1 Create a violation object for global, policy, and directive on document’s global +

            Let violation be the result of executing §2.3.1 Create a violation object for global, policy, and directive on document’s global object, policy, and "base-uri".

          2. -

            Set violation’s resource to "inline".

            +

            Set violation’s resource to "inline".

          3. Execute §5.3 Report a violation on violation.

          4. -

            If policy’s disposition is "enforce", +

            If policy’s disposition is "enforce", return "Blocked".

        @@ -4099,10 +4142,10 @@
        This directive’s initialization algorithm is responsible for adjusting a Document's forced sandboxing flag set according to the sandbox values present in its policies, as follows:

        -

        Given a Document or global object (context), a response (response), and a policy (policy):

        +

        Given a Document or global object (context), a response (response), and a policy (policy):

        1. -

          If policy’s disposition is not "Enforce", or context is not a Document, then abort this algorithm.

          +

          If policy’s disposition is not "Enforce", or context is not a Document, then abort this algorithm.

          Note: This will need to change if we allow Workers to be sandboxed, which seems like a pretty reasonable thing to do.

        2. @@ -4127,7 +4170,7 @@

          6.2.4.1. Algorithms

          This directive’s initialization algorithm is as follows:

          -

          Given a Document or global object (context), a response (response), and a policy (policy):

          +

          Given a Document or global object (context), a response (response), and a policy (policy):

          1. If context’s responsible browsing context has an opener browsing @@ -4155,31 +4198,29 @@

            meta element.

            Note: The frame-ancestors directive’s syntax is similar to a source list, but frame-ancestors will not fall back to the default-src directive’s value if one is specified. That is, a policy that declares default-src 'none' will still allow the resource to be embedded by anyone.

            -
            6.3.2.1. Algorithms
            -

            This directive’s response check is as follows:

            -

            Given a request (request), a response (response), and a policy (policy):

            -
              +
              6.3.2.1. frame-ancestors Navigation Check
              +

              Given a response (navigation response) and a browsing context (context), this algorithm returns "Blocked" if the navigation violates + the frame-ancestors directive, and "Allowed" otherwise. This constitutes + the frame-ancestors' directive’s navigation check:

              +
                +
              1. +

                If context is not a nested browsing context, return "Allowed".

              2. -

                If request’s destination is "document" and the request’s target browsing - context is a nested browsing context:

                +

                Let current be context.

                +
              3. +

                While current has a parent browsing context (parent):

                1. -

                  For each ancestor of the request’s target browsing context’s ancestor - browsing contexts:

                  -
                    -
                  1. -

                    Let origin-as-url be the result of executing the URL - parser on the unicode serialization of ancestor’s active document’s origin.

                    -
                  2. -

                    If §6.1.13.3 Does url match source list? returns Does Not Match when - executed upon origin-as-url and this directive’s value, return "Blocked".

                    -

                    Do we need syntax to allow matching a unique origin?

                    -
                  +

                  Set current to parent.

                  +
                2. +

                  Let origin be the result of executing the URL parser on the unicode serialization of parent’s active document’s origin.

                  +
                3. +

                  If §6.1.13.3 Does url match source list? returns Does Not Match when + executed upon origin and this directive’s value, return "Blocked".

              4. Return "Allowed".

              -

              Rewrite this in terms of HTML’s navigation algorithm.

              6.4. Reporting Directives

              Various algorithms in this document hook into the reporting process by constructing a violation object via §2.3.2 Create a violation object for request, policy, and directive or §2.3.1 Create a violation object for global, policy, and directive, and passing that object to §5.3 Report a violation to deliver the report.

              @@ -4224,7 +4265,7 @@

              Extensions to CSP MUST register themselves via the process outlined in [RFC7762]. In particular, note the criteria discussed in Section 4.2 of that document.

              -

              New directives SHOULD use the pre-request check, post-request check, response +

              New directives SHOULD use the pre-request check, post-request check, response check, and initialization hooks in order to integrate themselves into Fetch and HTML.

              @@ -4234,7 +4275,7 @@

              nonce-source expression as part of a policy, the server MUST generate a unique value each time it +

              If a server delivers a nonce-source expression as part of a policy, the server MUST generate a unique value each time it transmits a policy. The generated value SHOULD be at least 128 bits long (before encoding), and SHOULD be generated via a cryptographically secure random number generator in order to ensure that the value is difficult for @@ -4374,7 +4415,7 @@

              9. Implementation Considerations

              9.1. Vendor-specific Extensions and Addons

              -

              Policy enforced on a resource SHOULD NOT interfere with the operation +

              Policy enforced on a resource SHOULD NOT interfere with the operation of user-agent features like addons, extensions, or bookmarklets. These kinds of features generally advance the user’s priority over page authors, as espoused in [HTML-DESIGN].

              @@ -4599,6 +4640,7 @@

              media-type-list, in §6.2.2
            1. monitored, in §4.2
            2. name, in §2.2 +
            3. navigation check, in §2.2
            4. nonce-source, in §2.2.1
            5. 'none', in §2.2.1
            6. object-src, in §6.1.9 @@ -4713,6 +4755,7 @@

              initialising a new document object
            7. nonce
            8. ping +
            9. process a navigate response
            10. realm's global object
            11. run a worker
            12. the worker's documents @@ -4726,7 +4769,6 @@

              a
            13. active document
            14. an iframe srcdoc document -
            15. ancestor browsing context
            16. applet
            17. ascii case-insensitive match
            18. base @@ -4735,6 +4777,7 @@

              collect a sequence of characters
            19. content
            20. csp list +
            21. current settings object
            22. disown its opener
            23. document
            24. embed @@ -4742,16 +4785,16 @@

              fire
            25. forced sandboxing flag set
            26. frame -
            27. global object +
            28. global object
            29. http-equiv
            30. iframe -
            31. incumbent settings object
            32. link
            33. meta
            34. nested browsing context
            35. nested through
            36. object
            37. opener browsing context +
            38. parent browsing context
            39. parse a sandboxing directive
            40. parser-inserted
            41. prepare a script @@ -5028,6 +5071,9 @@

              <https://github.com/whatwg/html/issues/968>
              This hook is missing from WHATWG’s HTML. <https://github.com/whatwg/html/issues/1618>
              This hook is missing from W3C’s HTML. <https://github.com/w3c/html/issues/547>
              + +
              W3C’s HTML is not based on Fetch, and does not + have a process a navigate response algorithm into which to hook. <https://github.com/w3c/html/issues/548>
              This needs to be better explained.
              Do something interesting to the execution context in order to lock down interesting CSSOM algorithms. I don’t think CSSOM gives us any hooks here, so @@ -5039,8 +5085,6 @@

              What should this do in an iframe? Anything?
              Define the hooks into HTML’s navigation and form submission algorithms.
              -
              Do we need syntax to allow matching a unique origin?
              -
              Rewrite this in terms of HTML’s navigation algorithm.
              @@ -5239,7 +5286,8 @@

              6.2.3.1. Algorithms (2) -
            42. 6.3.2.1. Algorithms +
            43. 6.3.2.1. + frame-ancestors Navigation Check @@ -5344,6 +5391,17 @@

              + #directive-navigation-checkReferenced in: + + diff --git a/index.src.html b/index.src.html index 5eb409afe4..e21f9800cb 100644 --- a/index.src.html +++ b/index.src.html @@ -50,6 +50,7 @@

              Content Security Policy Level 3

              text: disown its opener text: opener browsing context text: nested browsing context + text: parent browsing context text: nested through; url: browsing-context-nested-through text: forced sandboxing flag set text: parse a sandboxing directive @@ -63,6 +64,7 @@

              Content Security Policy Level 3

              text: global object text: global object; for: settings object; url: concept-settings-object-global text: incumbent settings object + text: current settings object text: relevant settings object; url: relevant-settings-object-for-a-global-object text: responsible browsing context text: queue a task @@ -241,6 +243,7 @@

              Content Security Policy Level 3

              text: the worker's documents text: Content-Security-Policy http-equiv processing instructions; url: attr-meta-http-equiv-content-security-policy text: realm's global object; url: concept-realm-global-object + text: process a navigate response type: element-attr text: ping; for: a text: nonce; for: script; url: attr-script-nonce @@ -546,7 +549,7 @@

              Directives

              ; VCHAR are defined in Appendix B.1 of RFC 5234. - Directives have five associated algorithms: + Directives have six associated algorithms: 1. A pre-request check, which takes a request and a policy as an argument, and is executed during @@ -573,6 +576,11 @@

              Directives

              arguments. This algorithm is executed during [[#initialize-document-csp]], and has no effect unless otherwise specified. + 6. A navigation check, which takes a + response and a browsing context as arguments, and is executed + during process a navigate response. It returns "`Allowed`" unless + otherwise specified. +

              Source Lists

              Many directives' values consist of source lists: sets @@ -1130,6 +1138,14 @@

              ISSUE(w3c/html#547): This hook is missing from W3C's HTML. + 10. [[#should-block-navigation]] is called during the process a navigate + response algorithm to apply directive's navigation check. + + ISSUE(whatwg/html#1230): Upstream this to HTML. + + ISSUE(w3c/html#548): W3C's HTML is not based on Fetch, and does not + have a process a navigate response algorithm into which to hook. +

              Initialize a `Document`'s `CSP list`

              @@ -1227,9 +1243,10 @@

              skip to the next |directive|. 2. Otherwise, let |violation| be the result of executing - [[#create-violation-for-global]] on the incumbent settings - object, |policy|, and "`style-src`" if |type| is "`style`" or - "`style-attribute`", or "`script-src`" otherwise. + [[#create-violation-for-global]] on the current settings + object's global object, |policy|, + and "`style-src`" if |type| is "`style`" or "`style-attribute`", + or "`script-src`" otherwise. 3. Set |violation|'s resource to "`inline`". @@ -1240,6 +1257,41 @@

              3. Return |result|. +

              + Should |navigation response| in |context| be blocked by Content Security Policy? +

              + + Given a response |navigation response|, and a browsing context + (|context|), this algorithm returns "`Blocked`" if the active policy blocks + the navigation, and "`Allowed`" otherwise: + +
                + 1. Let |result| be "`Allowed`". + + 2. For each |policy| in |navigation response|'s + CSP list: + + 1. For each |directive| in |policy|: + + 1. If |directive|'s navigation check returns + "`Allowed`" when executed upon |navigation response| and |context|, + skip to the next |directive|. + + 2. Otherwise, let |violation| be the result of executing + [[#create-violation-for-global]] on `null`, |policy|, and + |directive|'s name. + + 3. Set |violation|'s resource to |navigation + response|'s URL. + + 4. Execute [[#report-violation]] on |violation|. + + 5. If |policy|'s disposition is "`enforce`", then + set |result| to "`Blocked`". + + 3. Return |result|. +
              +

              Integration with ECMAScript

              ECMAScript defines a {{HostEnsureCanCompileStrings()}} abstract operation @@ -3198,34 +3250,34 @@

              `frame-ancestors`

              directive's value if one is specified. That is, a policy that declares `default-src 'none'` will still allow the resource to be embedded by anyone. -
              Algorithms
              - - This directive's response check is as follows: +
              + `frame-ancestors` Navigation Check +
              - Given a request (|request|), a response (|response|), and a - policy (|policy|): + Given a response (|navigation response|) and a browsing context + (|context|), this algorithm returns "`Blocked`" if the navigation violates + the `frame-ancestors` directive, and "`Allowed`" otherwise. This constitutes + the `frame-ancestors`' directive's navigation check: - 1. If |request|'s destination is "`document`" - and the |request|'s target browsing - context is a nested browsing context: +
                + 1. If |context| is not a nested browsing context, return "`Allowed`". - 1. For each |ancestor| of the |request|'s - target browsing context's ancestor - browsing contexts: + 2. Let |current| be |context|. - 1. Let |origin-as-url| be the result of executing the URL - parser on the unicode serialization of |ancestor|'s - active document's origin. + 3. While |current| has a parent browsing context (|parent|): - 2. If [[#match-url-to-source-list]] returns `Does Not Match` when - executed upon |origin-as-url| and this directive's - value, return "`Blocked`". + 1. Set |current| to |parent|. - ISSUE: Do we need syntax to allow matching a unique origin? + 2. Let |origin| be the result of executing the URL parser on the + unicode serialization of |parent|'s active document's + origin. - 2. Return "`Allowed`". + 3. If [[#match-url-to-source-list]] returns `Does Not Match` when + executed upon |origin| and this directive's + value, return "`Blocked`". - ISSUE: Rewrite this in terms of HTML's navigation algorithm. + 4. Return "`Allowed`". +

              Reporting Directives