From 2bd51ffa6f51161027bf50e89dcf1192e5dc8eef Mon Sep 17 00:00:00 2001 From: Marcos Caceres Date: Wed, 3 May 2023 11:53:30 +1000 Subject: [PATCH] setAppBadge() should reject with SecurityError if child iframe is not same origin-domain as top-origin https://bugs.webkit.org/show_bug.cgi?id=256241 rdar://107109904 Reviewed by NOBODY (OOPS!). Now does same origin-domain check against top-level origin. Relevant spec change: https://github.com/w3c/badging/pull/107 * LayoutTests/imported/w3c/web-platform-tests/badging/setAppBadge_cross_origin.sub.https-expected.txt: * Source/WebCore/page/Navigator.cpp: (WebCore::Navigator::setAppBadge): --- ...setAppBadge_cross_origin.sub.https-expected.txt | 2 +- Source/WebCore/page/Navigator.cpp | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/LayoutTests/imported/w3c/web-platform-tests/badging/setAppBadge_cross_origin.sub.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/badging/setAppBadge_cross_origin.sub.https-expected.txt index d7771c92ba35d..a50c41fa72e08 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/badging/setAppBadge_cross_origin.sub.https-expected.txt +++ b/LayoutTests/imported/w3c/web-platform-tests/badging/setAppBadge_cross_origin.sub.https-expected.txt @@ -1,6 +1,6 @@ PASS Test that navigator.setAppBadge is available -FAIL Test that calling setAppBadge in a cross-origin iframe throws a SecurityError assert_equals: setAppBadge should have rejected with an error expected "error" but got "success" +PASS Test that calling setAppBadge in a cross-origin iframe throws a SecurityError PASS Test that calling setAppBadge in a same-origin iframe succeeds diff --git a/Source/WebCore/page/Navigator.cpp b/Source/WebCore/page/Navigator.cpp index ff982d4e5af8d..08d883949da0e 100644 --- a/Source/WebCore/page/Navigator.cpp +++ b/Source/WebCore/page/Navigator.cpp @@ -403,10 +403,16 @@ void Navigator::setAppBadge(std::optional badge, Refdocument(); - if (document && !document->isFullyActive()) { - promise->reject(InvalidStateError); - return; + if (auto* document = frame->document()) { + if (!document->isFullyActive()) { + promise->reject(InvalidStateError); + return; + } + + if (!frame->isMainFrame() && !document->topOrigin().isSameOriginDomain(document->securityOrigin())) { + promise->reject(SecurityError); + return; + } } page->badgeClient().setAppBadge(page, SecurityOriginData::fromFrame(frame), badge);