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)