Title: [281885] trunk
Revision
281885
Author
[email protected]
Date
2021-09-01 15:54:42 -0700 (Wed, 01 Sep 2021)

Log Message

Add "payment" permissions policy
https://bugs.webkit.org/show_bug.cgi?id=229406

Patch by Marcos Caceres <[email protected]> on 2021-09-01
Reviewed by Devin Rousso.

Source/WebCore:

Test: http/tests/paymentrequest/payment-allow-attribute.https.html

* Modules/applepay/PaymentSession.cpp:
(WebCore::PaymentSession::canCreateSession):
* html/FeaturePolicy.cpp:
(WebCore::policyTypeName):
(WebCore::FeaturePolicy::parse):
(WebCore::FeaturePolicy::allows const):
* html/FeaturePolicy.h:

LayoutTests:

* http/tests/paymentrequest/payment-allow-attribute.https-expected.txt: Added.
* http/tests/paymentrequest/payment-allow-attribute.https.html: Added.
* http/tests/paymentrequest/resources/payment-postmessage.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (281884 => 281885)


--- trunk/LayoutTests/ChangeLog	2021-09-01 22:49:44 UTC (rev 281884)
+++ trunk/LayoutTests/ChangeLog	2021-09-01 22:54:42 UTC (rev 281885)
@@ -1,3 +1,14 @@
+2021-09-01  Marcos Caceres  <[email protected]>
+
+        Add "payment" permissions policy
+        https://bugs.webkit.org/show_bug.cgi?id=229406
+
+        Reviewed by Devin Rousso.
+
+        * http/tests/paymentrequest/payment-allow-attribute.https-expected.txt: Added.
+        * http/tests/paymentrequest/payment-allow-attribute.https.html: Added.
+        * http/tests/paymentrequest/resources/payment-postmessage.html: Added.
+
 2021-09-01  Ayumi Kojima  <[email protected]>
 
         [ iOS15 ] editing/caret/ios/caret-in-overflow-area.html is failing.

Added: trunk/LayoutTests/http/tests/paymentrequest/payment-allow-attribute.https-expected.txt (0 => 281885)


--- trunk/LayoutTests/http/tests/paymentrequest/payment-allow-attribute.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/paymentrequest/payment-allow-attribute.https-expected.txt	2021-09-01 22:54:42 UTC (rev 281885)
@@ -0,0 +1,18 @@
+CONSOLE MESSAGE: Feature policy 'Payment' check failed for iframe with origin 'https://localhost:8443' and allow attribute ''.
+CONSOLE MESSAGE: Feature policy 'Payment' check failed for iframe with origin 'https://localhost:8443' and allow attribute 'payment 'none''.
+CONSOLE MESSAGE: Feature policy 'Payment' check failed for iframe with origin 'https://127.0.0.1:8443' and allow attribute 'payment 'none''.
+CONSOLE MESSAGE: Feature policy 'Payment' check failed for iframe with origin 'https://localhost:8443' and allow attribute 'payment 'self''.
+CONSOLE MESSAGE: Feature policy 'Payment' check failed for iframe with origin 'https://127.0.0.1:8443' and allow attribute 'payment https://localhost:8443'.
+PASS iframe src: "https://localhost:8443/paymentrequest/resources/payment-postmessage.html" with allow="" MUST NOT create a PaymentRequest. SecurityError Third-party iframes are not allowed to request payments unless explicitly allowed via Feature-Policy (payment)
+PASS iframe src: "https://127.0.0.1:8443/paymentrequest/resources/payment-postmessage.html" with allow="" is allowed to create a PaymentRequest.
+PASS iframe src: "https://localhost:8443/paymentrequest/resources/payment-postmessage.html" with allow="payment" is allowed to create a PaymentRequest. SecurityError Trying to start an Apple Pay session from a document with an different security origin than its top-level frame.
+PASS iframe src: "https://127.0.0.1:8443/paymentrequest/resources/payment-postmessage.html" with allow="payment" is allowed to create a PaymentRequest.
+PASS iframe src: "https://localhost:8443/paymentrequest/resources/payment-postmessage.html" with allow="payment *" is allowed to create a PaymentRequest. SecurityError Trying to start an Apple Pay session from a document with an different security origin than its top-level frame.
+PASS iframe src: "https://127.0.0.1:8443/paymentrequest/resources/payment-postmessage.html" with allow="payment *" is allowed to create a PaymentRequest.
+PASS iframe src: "https://localhost:8443/paymentrequest/resources/payment-postmessage.html" with allow="payment 'none'" MUST NOT create a PaymentRequest. SecurityError Third-party iframes are not allowed to request payments unless explicitly allowed via Feature-Policy (payment)
+PASS iframe src: "https://127.0.0.1:8443/paymentrequest/resources/payment-postmessage.html" with allow="payment 'none'" MUST NOT create a PaymentRequest. SecurityError Third-party iframes are not allowed to request payments unless explicitly allowed via Feature-Policy (payment)
+PASS iframe src: "https://localhost:8443/paymentrequest/resources/payment-postmessage.html" with allow="payment 'self'" MUST NOT create a PaymentRequest. SecurityError Third-party iframes are not allowed to request payments unless explicitly allowed via Feature-Policy (payment)
+PASS iframe src: "https://127.0.0.1:8443/paymentrequest/resources/payment-postmessage.html" with allow="payment 'self'" is allowed to create a PaymentRequest.
+PASS iframe src: "https://localhost:8443/paymentrequest/resources/payment-postmessage.html" with allow="payment https://localhost:8443" is allowed to create a PaymentRequest. SecurityError Trying to start an Apple Pay session from a document with an different security origin than its top-level frame.
+PASS iframe src: "https://127.0.0.1:8443/paymentrequest/resources/payment-postmessage.html" with allow="payment https://localhost:8443" MUST NOT create a PaymentRequest. SecurityError Third-party iframes are not allowed to request payments unless explicitly allowed via Feature-Policy (payment)
+

Added: trunk/LayoutTests/http/tests/paymentrequest/payment-allow-attribute.https.html (0 => 281885)


--- trunk/LayoutTests/http/tests/paymentrequest/payment-allow-attribute.https.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/paymentrequest/payment-allow-attribute.https.html	2021-09-01 22:54:42 UTC (rev 281885)
@@ -0,0 +1,152 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      iframe {
+        display: none;
+      }
+    </style>
+    <script src=""
+    <script>
+      if (window.testRunner) {
+        testRunner.dumpAsText();
+        testRunner.waitUntilDone();
+      }
+
+      function waitFor(target, eventName) {
+        return new Promise((resolve) => {
+          target.addEventListener(eventName, resolve, { once: true });
+        });
+      }
+
+      window.addEventListener("load", async () => {
+        const action = ""
+        for (const iframe of document.querySelectorAll("iframe")) {
+          iframe.src = ""
+          await waitFor(iframe, "load");
+          const isAllowed = iframe.dataset.enabled === "true";
+          iframe.contentWindow.postMessage({ action }, "*");
+          const { data } = await waitFor(window, "message");
+          const { exceptionMessage, exceptionName, result } = data;
+
+          const msg = `iframe src: "${iframe.src}" with allow="${
+            iframe.allow
+          }" ${
+            isAllowed ? "is allowed to" : "MUST NOT"
+          } create a PaymentRequest. ${exceptionName ?? ""} ${
+            exceptionMessage ?? ""
+          }`;
+
+          if (isAllowed) {
+            // ApplePay session doesn't allow remote origins to create PaymentRequests
+            // so we need to distinguish between the two cases.
+            switch (result) {
+              case "payment request created":
+                testPassed(msg);
+                continue;
+              case "threw":
+                // This is ok! policy worked, but ApplePay intervened!
+                if (data.exceptionMessage?.includes("Apple Pay")) {
+                  testPassed(msg);
+                  continue;
+                }
+                testFailed(msg);
+                continue;
+              default:
+                testFailed(msg);
+            }
+            continue;
+          }
+
+          if (!isAllowed) {
+            switch (result) {
+              case "payment request created":
+                testFailed(msg);
+                continue;
+              case "threw":
+                // The only legitimate reason for throwing is if the policy
+                // disallowed creating the PaymentRequest.
+                if (
+                  data.exceptionMessage ===
+                  "Third-party iframes are not allowed to request payments unless explicitly allowed via Feature-Policy (payment)"
+                ) {
+                  testPassed(msg);
+                  continue;
+                }
+                testFailed(msg);
+                continue;
+              default:
+                testFailed(msg);
+            }
+          }
+        }
+        testRunner.notifyDone();
+      });
+
+      window.addEventListener("error", (ev) => {
+        testFailed(`Unexpected error. Threw exception ${ev.message}.`);
+        testRunner?.notifyDone();
+      });
+    </script>
+  </head>
+  <body>
+    <iframe
+      data-enabled="false"
+      data-src=""
+    ></iframe>
+    <iframe
+      data-enabled="true"
+      data-src=""
+    ></iframe>
+    <iframe
+      allow="payment"
+      data-enabled="true"
+      data-src=""
+    ></iframe>
+    <iframe
+      allow="payment"
+      data-enabled="true"
+      data-src=""
+    ></iframe>
+    <iframe
+      allow="payment *"
+      data-enabled="true"
+      data-src=""
+    ></iframe>
+    <iframe
+      allow="payment *"
+      data-enabled="true"
+      data-src=""
+    ></iframe>
+    <iframe
+      allow="payment 'none'"
+      data-enabled="false"
+      data-src=""
+    ></iframe>
+    <iframe
+      allow="payment 'none'"
+      data-enabled="false"
+      data-src=""
+    ></iframe>
+    <iframe
+      allow="payment 'self'"
+      data-enabled="false"
+      data-src=""
+    ></iframe>
+    <iframe
+      allow="payment 'self'"
+      data-enabled="true"
+      data-src=""
+    ></iframe>
+    <iframe
+      allow="payment https://localhost:8443"
+      data-enabled="true"
+      data-src=""
+    ></iframe>
+    <iframe
+      allow="payment https://localhost:8443"
+      data-enabled="false"
+      data-src=""
+    ></iframe>
+  </body>
+</html>

Added: trunk/LayoutTests/http/tests/paymentrequest/resources/payment-postmessage.html (0 => 281885)


--- trunk/LayoutTests/http/tests/paymentrequest/resources/payment-postmessage.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/paymentrequest/resources/payment-postmessage.html	2021-09-01 22:54:42 UTC (rev 281885)
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<script src=""
+<body>
+  <script>
+    window.addEventListener("message", (event) => {
+      const { action } = event.data;
+      switch (action) {
+        case "create-payment-request":
+          let result = "";
+          let exceptionMessage;
+          let exceptionName = "";
+          try {
+            new PaymentRequest(validMethods, validDetails);
+            result = "payment request created";
+          } catch (e) {
+            result = "threw";
+            exceptionMessage = e.message;
+            exceptionName = e.name;
+          }
+          event.source.postMessage(
+            { action, result, exceptionMessage, exceptionName },
+            "*"
+          );
+          break;
+        default:
+          event.source.postMessage(
+            {
+              action,
+              exceptionMessage: "Unknown action",
+            },
+            "*"
+          );
+          throw new Error(`Unknown action: ${action}`);
+      }
+    });
+  </script>
+</body>

Modified: trunk/Source/WebCore/ChangeLog (281884 => 281885)


--- trunk/Source/WebCore/ChangeLog	2021-09-01 22:49:44 UTC (rev 281884)
+++ trunk/Source/WebCore/ChangeLog	2021-09-01 22:54:42 UTC (rev 281885)
@@ -1,3 +1,20 @@
+2021-09-01  Marcos Caceres  <[email protected]>
+
+        Add "payment" permissions policy
+        https://bugs.webkit.org/show_bug.cgi?id=229406
+
+        Reviewed by Devin Rousso.
+
+        Test: http/tests/paymentrequest/payment-allow-attribute.https.html
+
+        * Modules/applepay/PaymentSession.cpp:
+        (WebCore::PaymentSession::canCreateSession):
+        * html/FeaturePolicy.cpp:
+        (WebCore::policyTypeName):
+        (WebCore::FeaturePolicy::parse):
+        (WebCore::FeaturePolicy::allows const):
+        * html/FeaturePolicy.h:
+
 2021-09-01  Alex Christensen  <[email protected]>
 
         PerformanceNavigationTiming should be instantiated before scripts run then updated when response finishes

Modified: trunk/Source/WebCore/Modules/applepay/PaymentSession.cpp (281884 => 281885)


--- trunk/Source/WebCore/Modules/applepay/PaymentSession.cpp	2021-09-01 22:49:44 UTC (rev 281884)
+++ trunk/Source/WebCore/Modules/applepay/PaymentSession.cpp	2021-09-01 22:54:42 UTC (rev 281885)
@@ -30,6 +30,7 @@
 
 #include "Document.h"
 #include "DocumentLoader.h"
+#include "FeaturePolicy.h"
 #include "Page.h"
 #include "PaymentCoordinator.h"
 #include "SecurityOrigin.h"
@@ -49,6 +50,9 @@
 
 ExceptionOr<void> PaymentSession::canCreateSession(Document& document)
 {
+    if (!isFeaturePolicyAllowedByDocumentAndAllOwners(FeaturePolicy::Type::Payment, document, LogFeaturePolicyFailure::Yes))
+        return Exception { SecurityError, "Third-party iframes are not allowed to request payments unless explicitly allowed via Feature-Policy (payment)"_s };
+
     if (!document.frame())
         return Exception { InvalidAccessError, "Trying to start an Apple Pay session from an inactive document." };
 

Modified: trunk/Source/WebCore/html/FeaturePolicy.cpp (281884 => 281885)


--- trunk/Source/WebCore/html/FeaturePolicy.cpp	2021-09-01 22:49:44 UTC (rev 281884)
+++ trunk/Source/WebCore/html/FeaturePolicy.cpp	2021-09-01 22:54:42 UTC (rev 281885)
@@ -50,6 +50,8 @@
         return "DisplayCapture";
     case FeaturePolicy::Type::Geolocation:
         return "Geolocation";
+    case FeaturePolicy::Type::Payment:
+        return "Payment";
     case FeaturePolicy::Type::SyncXHR:
         return "SyncXHR";
     case FeaturePolicy::Type::Fullscreen:
@@ -170,6 +172,7 @@
     bool isSpeakerSelectionInitialized = false;
     bool isDisplayCaptureInitialized = false;
     bool isGeolocationInitialized = false;
+    bool isPaymentInitialized = false;
     bool isSyncXHRInitialized = false;
     bool isFullscreenInitialized = false;
 #if ENABLE(DEVICE_ORIENTATION)
@@ -207,6 +210,11 @@
             updateList(document, policy.m_geolocationRule, item.substring(12));
             continue;
         }
+        if (item.startsWith("payment")) {
+            isPaymentInitialized = true;
+            updateList(document, policy.m_paymentRule, item.substring(8));
+            continue;
+        }
         if (item.startsWith("sync-xhr")) {
             isSyncXHRInitialized = true;
             updateList(document, policy.m_syncXHRRule, item.substring(9));
@@ -254,6 +262,8 @@
         policy.m_displayCaptureRule.allowedList.add(document.securityOrigin().data());
     if (!isGeolocationInitialized)
         policy.m_geolocationRule.allowedList.add(document.securityOrigin().data());
+    if (!isPaymentInitialized)
+        policy.m_paymentRule.allowedList.add(document.securityOrigin().data());
 #if ENABLE(DEVICE_ORIENTATION)
     if (!isGyroscopeInitialized)
         policy.m_gyroscopeRule.allowedList.add(document.securityOrigin().data());
@@ -301,6 +311,8 @@
         return isAllowedByFeaturePolicy(m_displayCaptureRule, origin);
     case Type::Geolocation:
         return isAllowedByFeaturePolicy(m_geolocationRule, origin);
+    case Type::Payment:
+        return isAllowedByFeaturePolicy(m_paymentRule, origin);
     case Type::SyncXHR:
         return isAllowedByFeaturePolicy(m_syncXHRRule, origin);
     case Type::Fullscreen:

Modified: trunk/Source/WebCore/html/FeaturePolicy.h (281884 => 281885)


--- trunk/Source/WebCore/html/FeaturePolicy.h	2021-09-01 22:49:44 UTC (rev 281884)
+++ trunk/Source/WebCore/html/FeaturePolicy.h	2021-09-01 22:54:42 UTC (rev 281885)
@@ -44,6 +44,7 @@
         SpeakerSelection,
         DisplayCapture,
         Geolocation,
+        Payment,
         SyncXHR,
         Fullscreen,
 #if ENABLE(DEVICE_ORIENTATION)
@@ -69,6 +70,7 @@
     AllowRule m_speakerSelectionRule;
     AllowRule m_displayCaptureRule;
     AllowRule m_geolocationRule;
+    AllowRule m_paymentRule;
     AllowRule m_syncXHRRule;
     AllowRule m_fullscreenRule;
 #if ENABLE(DEVICE_ORIENTATION)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to