From 6b200c36eddce40147961173ac5a371a03650185 Mon Sep 17 00:00:00 2001 From: Andrew Williams Date: Wed, 30 Oct 2024 20:30:45 +0000 Subject: [PATCH 1/7] Enforce noopener on cross-top-level-site Blob URL navigations This change causes noopener to be set for window.open, clicks on 'a' / 'area' elements, and form submissions where the corresponding Blob URL is cross-site to the top-level site of the context performing the action. This corresponds to the discussion in https://github.com/w3c/FileAPI/issues/153. --- source | 89 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/source b/source index 742ca11758d..48377b46486 100644 --- a/source +++ b/source @@ -25532,7 +25532,8 @@ document.body.appendChild(wbr); web content.

To get an element's noopener, given an a, area, or - form element element and a string target:

+ form element element, a string url, and a string + target, perform the following steps. They return a boolean.

  1. If element's link types include the ASCII case-insensitive match for "_blank", then return true.

  2. +
  3. Let maybeURL be the result of encoding-parsing a URL given + url.

  4. + +
  5. If maybeURL is not failure and maybeURL's + scheme is "blob", run these + steps:

    + +
      +
    1. Let blobOrigin be maybeURL's + blob URL entry's + environment settings object's origin.

    2. + +
    3. Let topLevelOrigin be element's node navigable's + active document's relevant settings object's + top-level origin.

    4. + +
    5. If blobOriginis not same site with topLevelOrigin, + then return true.

    6. +
    +
  6. +
  7. Return false.

@@ -89707,23 +89729,36 @@ dictionary WindowPostMessageOptions : StructuredSeri
-

The window open steps, given a string url, a string target, - and a string features, are as follows:

+

To get noopener for window open, given a string url, a + Document sourceDocument, an ordered map + tokenizedFeatures, and a boolean noreferrer, perform the following steps. + They return a boolean.

    -
  1. If the event loop's termination nesting level is nonzero, - return null.

  2. +
  3. If noreferrer is true, return true.

  4. -
  5. Let sourceDocument be the entry global object's associated Document.

  6. +
  7. Let maybeURL be the result of encoding-parsing a URL given + url.

  8. -
  9. If target is the empty string, then set target to "_blank".

  10. +
  11. If maybeURL is not failure and maybeURL's + scheme is "blob", run these + steps:

    -
  12. Let tokenizedFeatures be the result of tokenizing features.

  13. +
      +
    1. Let blobOrigin be maybeURL's + blob URL entry's + environment settings object's origin. + +

    2. Let topLevelOrigin be sourceDocument's node navigable's + active document's relevant settings object's + top-level origin.

    3. -
    4. Let noopener and noreferrer be false.

    5. +
    6. If blobOriginis not same site with topLevelOrigin, + then return true.

    7. +
    + + +
  14. Let noopener be false.

  15. If tokenizedFeatures["noopener"] associated Document.

  16. + +
  17. If target is the empty string, then set target to "_blank".

  18. + +
  19. Let tokenizedFeatures be the result of tokenizing features.

  20. + +
  21. Let noreferrer be false.

  22. +
  23. If tokenizedFeatures["noreferrer"] exists, then:

    @@ -89755,10 +89811,15 @@ dictionary WindowPostMessageOptions : StructuredSeri
+
  • Let noopener be the result of + getting noopener for window open with + url, sourceDocument, tokenizedFeatures, and + noreferrer.

  • +
  • Let referrerPolicy be the empty string.

  • -
  • If noreferrer is true, then set noopener to true and set - referrerPolicy to "no-referrer".

  • +
  • If noreferrer is true, then set referrerPolicy to + "no-referrer".

  • Let targetNavigable and windowType be the result of applying the From 4786e670fbc63a7de284b6acb69aa270469566af Mon Sep 17 00:00:00 2001 From: Andrew Williams Date: Mon, 4 Nov 2024 13:06:13 +0000 Subject: [PATCH 2/7] Update callsites and pass urlRecord per review feedback --- source | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/source b/source index 48377b46486..a776214674d 100644 --- a/source +++ b/source @@ -25532,8 +25532,8 @@ document.body.appendChild(wbr); web content.

    To get an element's noopener, given an a, area, or - form element element, a string url, and a string - target, perform the following steps. They return a boolean.

    + form element element, a URL record url, and a + string target, perform the following steps. They return a boolean.

    1. If element's link types include the ASCII case-insensitive match for "_blank", then return true.

    2. -
    3. Let maybeURL be the result of encoding-parsing a URL given - url.

    4. - -
    5. If maybeURL is not failure and maybeURL's - scheme is "blob", run these - steps:

      +
    6. If url's scheme is + "blob", run these steps:

        -
      1. Let blobOrigin be maybeURL's +

      2. Let blobOrigin be url's blob URL entry's environment settings object's origin.

      3. @@ -25586,8 +25582,14 @@ document.body.appendChild(wbr);
        targetAttributeValue to the result of getting an element's target given subject.

        +
      4. Let urlRecord be the result of encoding-parsing a URL given + subject's href attribute value, relative to + subject's node document.

      5. + +
      6. If urlRecord is failure, then return.

      7. +
      8. Let noopener be the result of getting - an element's noopener with subject and + an element's noopener with subject, urlRecord, and targetAttributeValue.

      9. Let targetNavigable be the first return value of applying the rules for @@ -25596,11 +25598,8 @@ document.body.appendChild(wbr);

      10. If targetNavigable is null, then return.

      11. -
      12. Let urlString be the result of encoding-parsing-and-serializing a - URL given subject's href attribute - value, relative to subject's node document.

      13. - -
      14. If urlString is failure, then return.

      15. +
      16. Let urlString be the result of applying the + URL serializer to urlRecord.

      17. If hyperlinkSuffix is non-null, then append it to urlString.

      18. @@ -60016,7 +60015,8 @@ fur formTarget.

      19. Let noopener be the result of getting - an element's noopener with form and target.

      20. + an element's noopener with form, parsed action, and + target.

      21. Let targetNavigable be the first return value of applying the rules for choosing a navigable given target, form's node From bb5c5c88c8c79b20fc1c3627cb0130c1df69af78 Mon Sep 17 00:00:00 2001 From: Andrew Williams Date: Tue, 5 Nov 2024 23:01:40 +0000 Subject: [PATCH 3/7] Address most review feedback --- source | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/source b/source index 0332cd9c65a..620d81f6295 100644 --- a/source +++ b/source @@ -25552,19 +25552,19 @@ document.body.appendChild(wbr); ASCII case-insensitive match for "_blank", then return true.

      22. -
      23. If url's scheme is - "blob", run these steps:

        +
      24. +

        If url's scheme is "blob":

          -
        1. Let blobOrigin be url's - blob URL entry's +

        2. Let blobOrigin be url's blob URL entry's environment settings object's origin.

        3. -
        4. Let topLevelOrigin be element's node navigable's - active document's relevant settings object's - top-level origin.

        5. +
        6. Let topLevelOrigin be element's + relevant settings object's top-level origin.

        7. -
        8. If blobOriginis not same site with topLevelOrigin, +

        9. If blobOrigin is not same site with topLevelOrigin, then return true.

      25. @@ -25605,8 +25605,8 @@ document.body.appendChild(wbr);
      26. If targetNavigable is null, then return.

      27. -
      28. Let urlString be the result of applying the - URL serializer to urlRecord.

      29. +
      30. Let urlString be the result of applying the URL serializer to urlRecord.

      31. If hyperlinkSuffix is non-null, then append it to urlString.

      32. @@ -89840,9 +89840,8 @@ dictionary WindowPostMessageOptions : StructuredSeri blob URL entry's environment settings object's origin. -
      33. Let topLevelOrigin be sourceDocument's node navigable's - active document's relevant settings object's - top-level origin.

      34. +
      35. Let topLevelOrigin be sourceDocument's + relevant settings object's top-level origin.

      36. If blobOriginis not same site with topLevelOrigin, then return true.

      37. From 585567dbac0a8696793d341564022b02043ee955 Mon Sep 17 00:00:00 2001 From: Andrew Williams Date: Wed, 6 Nov 2024 01:21:34 +0000 Subject: [PATCH 4/7] Update 'get noopener for window open' to take a URL record --- source | 63 +++++++++++++++++++++++----------------------------------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/source b/source index 620d81f6295..a24c5cc5d92 100644 --- a/source +++ b/source @@ -89820,7 +89820,7 @@ dictionary WindowPostMessageOptions : StructuredSeri
        -

        To get noopener for window open, given a string url, a +

        To get noopener for window open, given a URL record url, a Document sourceDocument, an ordered map tokenizedFeatures, and a boolean noreferrer, perform the following steps. They return a boolean.

        @@ -89828,16 +89828,12 @@ dictionary WindowPostMessageOptions : StructuredSeri
        1. If noreferrer is true, return true.

        2. -
        3. Let maybeURL be the result of encoding-parsing a URL given - url.

        4. - -
        5. If maybeURL is not failure and maybeURL's - scheme is "blob", run these - steps:

          +
        6. If url is not failure and url's scheme is "blob":

            -
          1. Let blobOrigin be maybeURL's - blob URL entry's +

          2. Let blobOrigin be url's blob URL entry's environment settings object's origin.

          3. Let topLevelOrigin be sourceDocument's @@ -89901,16 +89897,23 @@ dictionary WindowPostMessageOptions : StructuredSeri

        7. -
        8. Let noopener be the result of - getting noopener for window open with - url, sourceDocument, tokenizedFeatures, and - noreferrer.

        9. -
        10. Let referrerPolicy be the empty string.

        11. If noreferrer is true, then set referrerPolicy to "no-referrer".

        12. +
        13. Let urlRecord be the URL record + about:blank.

        14. + +
        15. If url is not the empty string, then set urlRecord to the result + of encoding-parsing a URL given url, relative to the entry + settings object.

        16. + +
        17. Let noopener be the result of + getting noopener for window open with + urlRecord, sourceDocument, tokenizedFeatures, and + noreferrer.

        18. +
        19. Let targetNavigable and windowType be the result of applying the rules for choosing a navigable given target, sourceDocument's @@ -89926,6 +89929,9 @@ dictionary WindowPostMessageOptions : StructuredSeri

        20. If targetNavigable is null, then return null.

        21. +
        22. If urlRecord is failure, then throw a "SyntaxError" + DOMException.

        23. +
        24. If windowType is either "new and unrestricted" or "new with no opener", then:

          @@ -89939,16 +89945,6 @@ dictionary WindowPostMessageOptions : StructuredSeri data-x="nav-bc">active browsing context given tokenizedFeatures. CSSOMVIEW

        25. -
        26. Let urlRecord be the URL record - about:blank.

        27. - -
        28. If url is not the empty string, then set urlRecord to the result - of encoding-parsing a URL given url, relative to the entry - settings object.

        29. - -
        30. If urlRecord is failure, then throw a "SyntaxError" - DOMException.

        31. -
        32. If urlRecord matches about:blank, then perform the URL and history update steps given targetNavigable's WindowPostMessageOptions : StructuredSeri

          1. -

            If url is not the empty string, then:

            - -
              -
            1. Let urlRecord be the result of encoding-parsing a URL - url, relative to the entry settings object.

            2. - -
            3. If urlRecord is failure, then throw a - "SyntaxError" DOMException.

            4. - -
            5. Navigate targetNavigable to - urlRecord using sourceDocument, with referrerPolicy set to referrerPolicy and - exceptionsEnabled set to true.

            6. -
            +

            If url is not the empty string, then + navigate targetNavigable to + urlRecord using sourceDocument, with referrerPolicy set to referrerPolicy and + exceptionsEnabled set to true.

          2. If noopener is false, then set targetNavigable's Date: Wed, 6 Nov 2024 02:01:21 +0000 Subject: [PATCH 5/7] Make URL record optional for 'get noopener for window open' --- source | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/source b/source index a24c5cc5d92..e004c5eee51 100644 --- a/source +++ b/source @@ -89820,21 +89820,21 @@ dictionary WindowPostMessageOptions : StructuredSeri

            -

            To get noopener for window open, given a URL record url, a - Document sourceDocument, an ordered map - tokenizedFeatures, and a boolean noreferrer, perform the following steps. - They return a boolean.

            +

            To get noopener for window open, given a Document + sourceDocument, an ordered map tokenizedFeatures, a boolean + noreferrer, and an optional URL record url, perform the + following steps. They return a boolean.

            1. If noreferrer is true, return true.

            2. -
            3. If url is not failure and url's

              If url was given and url's scheme is "blob":

              1. Let blobOrigin be url's blob URL entry's - environment settings object's origin. + environment settings object's origin.

              2. Let topLevelOrigin be sourceDocument's relevant settings object's top-level origin.

              3. @@ -89909,10 +89909,13 @@ dictionary WindowPostMessageOptions : StructuredSeri of encoding-parsing a URL given url, relative to the entry settings object.

                -
              4. Let noopener be the result of - getting noopener for window open with - urlRecord, sourceDocument, tokenizedFeatures, and - noreferrer.

              5. +
              6. Let noopener be the result of getting noopener for window open with + sourceDocument, tokenizedFeatures, and noreferrer if + urlRecord is failure; Otherwise, the result of getting noopener for window open with + sourceDocument, tokenizedFeatures, noreferrer, and + urlRecord.

              7. Let targetNavigable and windowType be the result of applying the @@ -89966,13 +89969,11 @@ dictionary WindowPostMessageOptions : StructuredSeri

                Otherwise:

                  -
                1. -

                  If url is not the empty string, then - navigate targetNavigable to - urlRecord using sourceDocument, with referrerPolicy set to referrerPolicy and - exceptionsEnabled set to true.

                2. - +
                3. If url is not the empty string, then + navigate targetNavigable to + urlRecord using sourceDocument, with referrerPolicy set to referrerPolicy and + exceptionsEnabled set to true.

                4. If noopener is false, then set targetNavigable's active browsing context's opener browsing context to From 5a1700a9ddc264aa36d52bf06b1cf578ea8cec98 Mon Sep 17 00:00:00 2001 From: Andrew Williams Date: Wed, 6 Nov 2024 02:07:58 +0000 Subject: [PATCH 6/7] Fix whitespace in 'get noopener for window open' --- source | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source b/source index e004c5eee51..b46514bab5d 100644 --- a/source +++ b/source @@ -89828,8 +89828,9 @@ dictionary WindowPostMessageOptions : StructuredSeri

                  1. If noreferrer is true, return true.

                  2. -
                  3. If url was given and url's scheme is "blob":

                    +
                  4. +

                    If url was given and url's scheme is "blob":

                    1. Let blobOrigin be url's Date: Wed, 6 Nov 2024 16:09:24 +0000 Subject: [PATCH 7/7] Address review feedback --- source | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/source b/source index b46514bab5d..017073effac 100644 --- a/source +++ b/source @@ -25558,11 +25558,12 @@ document.body.appendChild(wbr);

                      1. Let blobOrigin be url's blob URL entry's - environment settings object's origin.

                      2. + data-x="concept-url-blob-entry">blob URL entry's environment's origin.

                        -
                      3. Let topLevelOrigin be element's - relevant settings object's top-level origin.

                      4. +
                      5. Let topLevelOrigin be element's relevant settings + object's top-level origin.

                      6. If blobOrigin is not same site with topLevelOrigin, then return true.

                      7. @@ -89821,24 +89822,23 @@ dictionary WindowPostMessageOptions : StructuredSeri

                        To get noopener for window open, given a Document - sourceDocument, an ordered map tokenizedFeatures, a boolean - noreferrer, and an optional URL record url, perform the - following steps. They return a boolean.

                        + sourceDocument, an ordered map tokenizedFeatures, and a + URL record or failure url, perform the following steps. They return a + boolean.

                          -
                        1. If noreferrer is true, return true.

                        2. -
                        3. -

                          If url was given and url's If url is not failure and url's scheme is "blob":

                          1. Let blobOrigin be url's blob URL entry's - environment settings object's origin.

                          2. + data-x="concept-url-blob-entry">blob URL entry's environment's origin.

                            -
                          3. Let topLevelOrigin be sourceDocument's - relevant settings object's top-level origin.

                          4. +
                          5. Let topLevelOrigin be sourceDocument's relevant settings + object's top-level origin.

                          6. If blobOriginis not same site with topLevelOrigin, then return true.

                          7. @@ -89870,7 +89870,7 @@ dictionary WindowPostMessageOptions : StructuredSeri
                            1. If the event loop's termination nesting level is nonzero, - return null.

                            2. + then return null.

                            3. Let sourceDocument be the entry global object's associated Document.

                            4. @@ -89898,11 +89898,6 @@ dictionary WindowPostMessageOptions : StructuredSeri
                            -
                          8. Let referrerPolicy be the empty string.

                          9. - -
                          10. If noreferrer is true, then set referrerPolicy to - "no-referrer".

                          11. -
                          12. Let urlRecord be the URL record about:blank.

                          13. @@ -89912,11 +89907,12 @@ dictionary WindowPostMessageOptions : StructuredSeri
                          14. Let noopener be the result of getting noopener for window open with - sourceDocument, tokenizedFeatures, and noreferrer if - urlRecord is failure; Otherwise, the result of getting noopener for window open with - sourceDocument, tokenizedFeatures, noreferrer, and - urlRecord.

                          15. + sourceDocument, tokenizedFeatures, and urlRecord.

                            + +
                          16. Let referrerPolicy be the empty string.

                          17. + +
                          18. If noreferrer is true, then set noopener to true and set + referrerPolicy to "no-referrer".

                          19. Let targetNavigable and windowType be the result of applying the