Add initial support for 'Cross-Origin-Options' HTTP response header
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 May 2018 00:33:37 +0000 (00:33 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 May 2018 00:33:37 +0000 (00:33 +0000)
commit81494cbafb475c935d517d0fc8007ec21dd73643
tree9995a8eb4cd66602b7ec73b06824112cf037232b
parentdfb85a7cfca31c33829e993b23c6ff0ea33abc8f
Add initial support for 'Cross-Origin-Options' HTTP response header
https://bugs.webkit.org/show_bug.cgi?id=184996
<rdar://problem/39664620>

Reviewed by Geoff Garen.

Source/WebCore:

Add initial support for 'Cross-Origin-Options' HTTP response header behind an experimental
feature flag, on by default. When the HTTP server services this HTTP response header for a
main resource, we'll set these options on the corresponding Document. This will impact the
behavior of the Document's associated Window API when cross-origin.

The HTTP header has 3 possible values:
- allow: This is the default. Regular cross-origin Window API is available.
- allow-postmessage: Only postMessage() is available on a cross-origin window, trying to
  access anything else will throw a SecurityError.
- deny: Trying to do anything with a cross-origin window will throw a SecurityError.

The header has no effect when accessing same origin windows.

Note that on cross-origin access from Window A to Window B, we check the cross-origin
options for both Window A and Window B and use the lowest common denominator as effective
cross-origin options for the access. So if Window A has 'Cross-Origin-Options: deny' and
tries to call postMessage() on Window B which has 'Cross-Origin-Options: allow-postmessage',
we will throw a SecurityError. This is because Window A's more restrictive options (deny)
apply.

Tests: http/wpt/cross-origin-options/allow-postmessage-from-deny.html
       http/wpt/cross-origin-options/allow-postmessage.html
       http/wpt/cross-origin-options/cross-origin-options-header.html

* bindings/js/JSDOMBindingSecurity.cpp:
(WebCore::BindingSecurity::shouldAllowAccessToDOMWindowGivenMinimumCrossOriginOptions):
* bindings/js/JSDOMBindingSecurity.h:
* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::effectiveCrossOriginOptionsForAccess):
(WebCore::jsDOMWindowGetOwnPropertySlotRestrictedAccess):
(WebCore::JSDOMWindow::getOwnPropertySlot):
(WebCore::JSDOMWindow::getOwnPropertySlotByIndex):
(WebCore::addCrossOriginWindowPropertyNames):
(WebCore::addScopedChildrenIndexes):
(WebCore::addCrossOriginWindowOwnPropertyNames):
(WebCore::JSDOMWindow::getOwnPropertyNames):
* bindings/js/JSDOMWindowCustom.h:
* bindings/js/JSRemoteDOMWindowCustom.cpp:
(WebCore::JSRemoteDOMWindow::getOwnPropertySlot):
(WebCore::JSRemoteDOMWindow::getOwnPropertySlotByIndex):
(WebCore::JSRemoteDOMWindow::getOwnPropertyNames):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateAttributeGetterBodyDefinition):
(GetCrossOriginsOptionsFromExtendedAttributeValue):
(GenerateAttributeSetterBodyDefinition):
(GenerateOperationBodyDefinition):
* bindings/scripts/IDLAttributes.json:
* dom/Document.cpp:
(WebCore::Document::setCrossOriginOptions):
* dom/Document.h:
(WebCore::Document::crossOriginOptions const):
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::didBeginDocument):
* page/AbstractDOMWindow.cpp:
(WebCore::AbstractDOMWindow::AbstractDOMWindow):
* page/AbstractDOMWindow.h:
(WebCore::AbstractDOMWindow::crossOriginOptions):
(WebCore::AbstractDOMWindow::setCrossOriginOptions):
* page/DOMWindow.cpp:
(WebCore::DOMWindow::DOMWindow):
(WebCore::DOMWindow::didSecureTransitionTo):
* page/DOMWindow.idl:
* page/Frame.h:
* page/RemoteDOMWindow.cpp:
(WebCore::RemoteDOMWindow::RemoteDOMWindow):
* page/RemoteDOMWindow.h:
* page/Settings.yaml:
* platform/network/HTTPHeaderNames.in:
* platform/network/HTTPParsers.cpp:
(WebCore::parseCrossOriginOptionsHeader):
* platform/network/HTTPParsers.h:

Source/WebKit:

* Shared/WebPreferences.yaml:
Add this as an experimental feature, on by default.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::frameBecameRemote):
Make sure we pass the cross-origin options from the local Window
to the remote one when transitioning.

LayoutTests:

Add layout test coverage.

* http/wpt/cross-origin-options/allow-postmessage-expected.txt: Added.
* http/wpt/cross-origin-options/allow-postmessage-from-deny-expected.txt: Added.
* http/wpt/cross-origin-options/allow-postmessage-from-deny.html: Added.
* http/wpt/cross-origin-options/allow-postmessage-from-deny.html.headers: Added.
* http/wpt/cross-origin-options/allow-postmessage.html: Added.
* http/wpt/cross-origin-options/cross-origin-options-header-expected.txt: Added.
* http/wpt/cross-origin-options/cross-origin-options-header.html: Added.
* http/wpt/cross-origin-options/resources/cross-origin-options-allow-postmessage-pong.html: Added.
* http/wpt/cross-origin-options/resources/cross-origin-options-allow-postmessage-pong.html.headers: Added.
* http/wpt/cross-origin-options/resources/serve-cross-origin-options-header.py: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231622 268f45cc-cd09-0410-ab3c-d52691b4dbfc
48 files changed:
LayoutTests/ChangeLog
LayoutTests/http/wpt/cross-origin-options/allow-postmessage-expected.txt [new file with mode: 0644]
LayoutTests/http/wpt/cross-origin-options/allow-postmessage-from-deny-expected.txt [new file with mode: 0644]
LayoutTests/http/wpt/cross-origin-options/allow-postmessage-from-deny.html [new file with mode: 0644]
LayoutTests/http/wpt/cross-origin-options/allow-postmessage-from-deny.html.headers [new file with mode: 0644]
LayoutTests/http/wpt/cross-origin-options/allow-postmessage.html [new file with mode: 0644]
LayoutTests/http/wpt/cross-origin-options/cross-origin-options-header-expected.txt [new file with mode: 0644]
LayoutTests/http/wpt/cross-origin-options/cross-origin-options-header.html [new file with mode: 0644]
LayoutTests/http/wpt/cross-origin-options/resources/cross-origin-options-allow-postmessage-pong.html [new file with mode: 0644]
LayoutTests/http/wpt/cross-origin-options/resources/cross-origin-options-allow-postmessage-pong.html.headers [new file with mode: 0644]
LayoutTests/http/wpt/cross-origin-options/resources/serve-cross-origin-options-header.py [new file with mode: 0644]
LayoutTests/http/wpt/cross-origin-options/resources/utils.js [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSDOMBindingSecurity.cpp
Source/WebCore/bindings/js/JSDOMBindingSecurity.h
Source/WebCore/bindings/js/JSDOMWindowCustom.cpp
Source/WebCore/bindings/js/JSDOMWindowCustom.h
Source/WebCore/bindings/js/JSRemoteDOMWindowCustom.cpp
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/IDLAttributes.json
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/page/AbstractDOMWindow.cpp
Source/WebCore/page/AbstractDOMWindow.h
Source/WebCore/page/DOMWindow.cpp
Source/WebCore/page/DOMWindow.idl
Source/WebCore/page/Frame.h
Source/WebCore/page/RemoteDOMWindow.cpp
Source/WebCore/page/RemoteDOMWindow.h
Source/WebCore/page/Settings.yaml
Source/WebCore/platform/network/HTTPHeaderNames.in
Source/WebCore/platform/network/HTTPParsers.cpp
Source/WebCore/platform/network/HTTPParsers.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebPreferences.yaml
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h
Source/WebKitLegacy/mac/WebView/WebPreferences.mm
Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h
Source/WebKitLegacy/mac/WebView/WebView.mm
Source/WebKitLegacy/win/Interfaces/IWebPreferencesPrivate.idl
Source/WebKitLegacy/win/WebPreferenceKeysPrivate.h
Source/WebKitLegacy/win/WebPreferences.cpp
Source/WebKitLegacy/win/WebPreferences.h
Source/WebKitLegacy/win/WebView.cpp
Tools/DumpRenderTree/mac/DumpRenderTree.mm
Tools/DumpRenderTree/win/DumpRenderTree.cpp