diff options
author | estark <estark@chromium.org> | 2016-03-16 16:30:37 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-16 23:31:48 +0000 |
commit | bd8e26fa87f192482bc35f5417a2616f85a5bde5 (patch) | |
tree | 9f6aa06a3ee84ec567923259c0d8aa56a8fada2a | |
parent | 5260676ed275358c7b44da823b97bc1084c7a25e (diff) | |
download | chromium_src-bd8e26fa87f192482bc35f5417a2616f85a5bde5.zip chromium_src-bd8e26fa87f192482bc35f5417a2616f85a5bde5.tar.gz chromium_src-bd8e26fa87f192482bc35f5417a2616f85a5bde5.tar.bz2 |
Make Document::isSecureContext() work for OOPIFs
The inputs needed for isSecureContext() were, previously:
a.) the origins of the current frame and its ancestors
b.) for any sandboxed origins in the ancestor chain, the URLs of those frames
(a) is easily accessible in --site-per-process, but (b) is not. For
sandboxed frames, the URL was used to construct a stand-in origin. The
sandboxed frame was considered potentially trustworthy if the stand-in
origin was potentially trustworthy.
In --site-per-process, instead of using the URL for a sandboxed origin,
we save the necessary information (the potential-trustworthiness) at the
time that the origin becomes sandboxed.
Based on https://codereview.chromium.org/1716303002/
BUG=571079
TEST=secureContexts/* layout tests with --site-per-process
CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_site_isolation
Review URL: https://codereview.chromium.org/1723753002
Cr-Commit-Position: refs/heads/master@{#381587}
42 files changed, 425 insertions, 67 deletions
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc index 3a2f122..c55212c 100644 --- a/content/browser/frame_host/frame_tree_node.cc +++ b/content/browser/frame_host/frame_tree_node.cc @@ -98,7 +98,8 @@ FrameTreeNode::FrameTreeNode( name, unique_name, blink::WebSandboxFlags::None, - false /* should enforce strict mixed content checking */), + false /* should enforce strict mixed content checking */, + false /* is a potentially trustworthy unique origin */), pending_sandbox_flags_(blink::WebSandboxFlags::None), frame_owner_properties_(frame_owner_properties), loading_progress_(kLoadingProgressNotStarted) { @@ -212,10 +213,18 @@ void FrameTreeNode::SetCurrentURL(const GURL& url) { TraceSnapshot(); } -void FrameTreeNode::SetCurrentOrigin(const url::Origin& origin) { - if (!origin.IsSameOriginWith(replication_state_.origin)) - render_manager_.OnDidUpdateOrigin(origin); +void FrameTreeNode::SetCurrentOrigin( + const url::Origin& origin, + bool is_potentially_trustworthy_unique_origin) { + if (!origin.IsSameOriginWith(replication_state_.origin) || + replication_state_.has_potentially_trustworthy_unique_origin != + is_potentially_trustworthy_unique_origin) { + render_manager_.OnDidUpdateOrigin(origin, + is_potentially_trustworthy_unique_origin); + } replication_state_.origin = origin; + replication_state_.has_potentially_trustworthy_unique_origin = + is_potentially_trustworthy_unique_origin; } void FrameTreeNode::SetFrameName(const std::string& name, diff --git a/content/browser/frame_host/frame_tree_node.h b/content/browser/frame_host/frame_tree_node.h index f806856..04582da 100644 --- a/content/browser/frame_host/frame_tree_node.h +++ b/content/browser/frame_host/frame_tree_node.h @@ -138,7 +138,8 @@ class CONTENT_EXPORT FrameTreeNode { } // Set the current origin and notify proxies about the update. - void SetCurrentOrigin(const url::Origin& origin); + void SetCurrentOrigin(const url::Origin& origin, + bool is_potentially_trustworthy_unique_origin); // Set the current name and notify proxies about the update. void SetFrameName(const std::string& name, const std::string& unique_name); diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index 79265e4..dc97afb 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc @@ -482,7 +482,8 @@ void NavigatorImpl::DidNavigate( // origin because it creates a RenderFrameProxy that needs this to initialize // its security context. This origin will also be sent to RenderFrameProxies // created via ViewMsg_New and FrameMsg_NewFrameProxy. - render_frame_host->frame_tree_node()->SetCurrentOrigin(params.origin); + render_frame_host->frame_tree_node()->SetCurrentOrigin( + params.origin, params.has_potentially_trustworthy_unique_origin); render_frame_host->frame_tree_node()->SetEnforceStrictMixedContentChecking( params.should_enforce_strict_mixed_content_checking); diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index c945e38..78480d2 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc @@ -541,6 +541,8 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) { IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeName, OnDidChangeName) IPC_MESSAGE_HANDLER(FrameHostMsg_EnforceStrictMixedContentChecking, OnEnforceStrictMixedContentChecking) + IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateToUniqueOrigin, + OnUpdateToUniqueOrigin) IPC_MESSAGE_HANDLER(FrameHostMsg_DidAssignPageId, OnDidAssignPageId) IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeSandboxFlags, OnDidChangeSandboxFlags) @@ -1479,6 +1481,14 @@ void RenderFrameHostImpl::OnEnforceStrictMixedContentChecking() { frame_tree_node()->SetEnforceStrictMixedContentChecking(true); } +void RenderFrameHostImpl::OnUpdateToUniqueOrigin( + bool is_potentially_trustworthy_unique_origin) { + url::Origin origin; + DCHECK(origin.unique()); + frame_tree_node()->SetCurrentOrigin(origin, + is_potentially_trustworthy_unique_origin); +} + void RenderFrameHostImpl::OnDidAssignPageId(int32_t page_id) { // Update the RVH's current page ID so that future IPCs from the renderer // correspond to the new page. diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 885258c..5901d5e 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h @@ -630,6 +630,7 @@ class CONTENT_EXPORT RenderFrameHostImpl : public RenderFrameHost, void OnDidChangeOpener(int32_t opener_routing_id); void OnDidChangeName(const std::string& name, const std::string& unique_name); void OnEnforceStrictMixedContentChecking(); + void OnUpdateToUniqueOrigin(bool is_potentially_trustworthy_unique_origin); void OnDidAssignPageId(int32_t page_id); void OnDidChangeSandboxFlags(int32_t frame_routing_id, blink::WebSandboxFlags flags); diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 24f9636..23f86ab 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc @@ -976,10 +976,13 @@ void RenderFrameHostManager::OnEnforceStrictMixedContentChecking( } } -void RenderFrameHostManager::OnDidUpdateOrigin(const url::Origin& origin) { +void RenderFrameHostManager::OnDidUpdateOrigin( + const url::Origin& origin, + bool is_potentially_trustworthy_unique_origin) { for (const auto& pair : proxy_hosts_) { pair.second->Send( - new FrameMsg_DidUpdateOrigin(pair.second->GetRoutingID(), origin)); + new FrameMsg_DidUpdateOrigin(pair.second->GetRoutingID(), origin, + is_potentially_trustworthy_unique_origin)); } } diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h index 2f288c9..12e1a1f 100644 --- a/content/browser/frame_host/render_frame_host_manager.h +++ b/content/browser/frame_host/render_frame_host_manager.h @@ -442,7 +442,8 @@ class CONTENT_EXPORT RenderFrameHostManager // Send updated origin to all frame proxies when the frame navigates to a new // origin. - void OnDidUpdateOrigin(const url::Origin& origin); + void OnDidUpdateOrigin(const url::Origin& origin, + bool is_potentially_trustworthy_unique_origin); void EnsureRenderViewInitialized(RenderViewHostImpl* render_view_host, SiteInstance* instance); diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index a2d5978..7ca7952 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h @@ -291,6 +291,10 @@ IPC_STRUCT_BEGIN_WITH_PARENT(FrameHostMsg_DidCommitProvisionalLoad_Params, // checking. IPC_STRUCT_MEMBER(bool, should_enforce_strict_mixed_content_checking) + // True if the document for the load is a unique origin that should be + // considered potentially trustworthy. + IPC_STRUCT_MEMBER(bool, has_potentially_trustworthy_unique_origin) + // True if the navigation originated as an srcdoc attribute. IPC_STRUCT_MEMBER(bool, is_srcdoc) IPC_STRUCT_END() @@ -384,6 +388,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::FrameReplicationState) IPC_STRUCT_TRAITS_MEMBER(unique_name) IPC_STRUCT_TRAITS_MEMBER(scope) IPC_STRUCT_TRAITS_MEMBER(should_enforce_strict_mixed_content_checking) + IPC_STRUCT_TRAITS_MEMBER(has_potentially_trustworthy_unique_origin) IPC_STRUCT_TRAITS_END() IPC_STRUCT_BEGIN(FrameMsg_NewFrame_WidgetParams) @@ -769,7 +774,9 @@ IPC_MESSAGE_ROUTED1(FrameMsg_EnforceStrictMixedContentChecking, // Update a proxy's replicated origin. Used when the frame is navigated to a // new origin. -IPC_MESSAGE_ROUTED1(FrameMsg_DidUpdateOrigin, url::Origin /* origin */) +IPC_MESSAGE_ROUTED2(FrameMsg_DidUpdateOrigin, + url::Origin /* origin */, + bool /* is potentially trustworthy unique origin */) // Notifies this frame or proxy that it is now focused. This is used to // support cross-process focused frame changes. @@ -952,6 +959,13 @@ IPC_MESSAGE_ROUTED2(FrameHostMsg_DidChangeName, // checking to be enforced. IPC_MESSAGE_ROUTED0(FrameHostMsg_EnforceStrictMixedContentChecking) +// Sent when the frame is set to a unique origin. TODO(estark): this IPC +// only exists to support dynamic sandboxing via a CSP delivered in a +// <meta> tag. This is not supposed to be allowed per the CSP spec and +// should be ripped out. https://crbug.com/594645 +IPC_MESSAGE_ROUTED1(FrameHostMsg_UpdateToUniqueOrigin, + bool /* is potentially trustworthy unique origin */) + // Sent when the renderer changed the progress of a load. IPC_MESSAGE_ROUTED1(FrameHostMsg_DidChangeLoadProgress, double /* load_progress */) diff --git a/content/common/frame_replication_state.cc b/content/common/frame_replication_state.cc index ab0a66d..13cd626 100644 --- a/content/common/frame_replication_state.cc +++ b/content/common/frame_replication_state.cc @@ -11,21 +11,25 @@ namespace content { FrameReplicationState::FrameReplicationState() : sandbox_flags(blink::WebSandboxFlags::None), scope(blink::WebTreeScopeType::Document), - should_enforce_strict_mixed_content_checking(false) {} + should_enforce_strict_mixed_content_checking(false), + has_potentially_trustworthy_unique_origin(false) {} FrameReplicationState::FrameReplicationState( blink::WebTreeScopeType scope, const std::string& name, const std::string& unique_name, blink::WebSandboxFlags sandbox_flags, - bool should_enforce_strict_mixed_content_checking) + bool should_enforce_strict_mixed_content_checking, + bool has_potentially_trustworthy_unique_origin) : origin(), sandbox_flags(sandbox_flags), name(name), unique_name(unique_name), scope(scope), should_enforce_strict_mixed_content_checking( - should_enforce_strict_mixed_content_checking) {} + should_enforce_strict_mixed_content_checking), + has_potentially_trustworthy_unique_origin( + has_potentially_trustworthy_unique_origin) {} FrameReplicationState::~FrameReplicationState() { } diff --git a/content/common/frame_replication_state.h b/content/common/frame_replication_state.h index 55f0ef3..9ec7b8b 100644 --- a/content/common/frame_replication_state.h +++ b/content/common/frame_replication_state.h @@ -23,7 +23,8 @@ struct CONTENT_EXPORT FrameReplicationState { const std::string& name, const std::string& unique_name, blink::WebSandboxFlags sandbox_flags, - bool should_enforce_strict_mixed_content_checking); + bool should_enforce_strict_mixed_content_checking, + bool has_potentially_trustworthy_unique_origin); ~FrameReplicationState(); // Current origin of the frame. This field is updated whenever a frame @@ -90,6 +91,10 @@ struct CONTENT_EXPORT FrameReplicationState { // frames live in different processes. bool should_enforce_strict_mixed_content_checking; + // True if a frame's origin is unique and should be considered potentially + // trustworthy. + bool has_potentially_trustworthy_unique_origin; + // TODO(alexmos): Eventually, this structure can also hold other state that // needs to be replicated, such as frame sizing info. }; diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 15debe0..ce26877 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc @@ -2732,6 +2732,12 @@ void RenderFrameImpl::didEnforceStrictMixedContentChecking() { Send(new FrameHostMsg_EnforceStrictMixedContentChecking(routing_id_)); } +void RenderFrameImpl::didUpdateToUniqueOrigin( + bool is_potentially_trustworthy_unique_origin) { + Send(new FrameHostMsg_UpdateToUniqueOrigin( + routing_id_, is_potentially_trustworthy_unique_origin)); +} + void RenderFrameImpl::didChangeSandboxFlags(blink::WebFrame* child_frame, blink::WebSandboxFlags flags) { Send(new FrameHostMsg_DidChangeSandboxFlags( @@ -4417,6 +4423,10 @@ void RenderFrameImpl::SendDidCommitProvisionalLoad( params.should_enforce_strict_mixed_content_checking = frame->shouldEnforceStrictMixedContentChecking(); + params.has_potentially_trustworthy_unique_origin = + frame->document().getSecurityOrigin().isUnique() && + frame->document().getSecurityOrigin().isPotentiallyTrustworthy(); + // Set the URL to be displayed in the browser UI to the user. params.url = GetLoadingUrl(); DCHECK(!is_swapped_out_ || params.url == GURL(kSwappedOutURL)); diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index b554ead..f6c2df9 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h @@ -450,6 +450,8 @@ class CONTENT_EXPORT RenderFrameImpl void didChangeName(const blink::WebString& name, const blink::WebString& unique_name) override; void didEnforceStrictMixedContentChecking() override; + void didUpdateToUniqueOrigin( + bool is_potentially_trustworthy_unique_origin) override; void didChangeSandboxFlags(blink::WebFrame* child_frame, blink::WebSandboxFlags flags) override; void didChangeFrameOwnerProperties( diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 8a12c6b..37b7059 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc @@ -222,6 +222,8 @@ void RenderFrameProxy::SetReplicatedState(const FrameReplicationState& state) { blink::WebString::fromUTF8(state.unique_name)); web_frame_->setReplicatedShouldEnforceStrictMixedContentChecking( state.should_enforce_strict_mixed_content_checking); + web_frame_->setReplicatedPotentiallyTrustworthyUniqueOrigin( + state.has_potentially_trustworthy_unique_origin); } // Update the proxy's SecurityContext and FrameOwner with new sandbox flags @@ -341,8 +343,12 @@ void RenderFrameProxy::OnEnforceStrictMixedContentChecking( should_enforce); } -void RenderFrameProxy::OnDidUpdateOrigin(const url::Origin& origin) { +void RenderFrameProxy::OnDidUpdateOrigin( + const url::Origin& origin, + bool is_potentially_trustworthy_unique_origin) { web_frame_->setReplicatedOrigin(origin); + web_frame_->setReplicatedPotentiallyTrustworthyUniqueOrigin( + is_potentially_trustworthy_unique_origin); } void RenderFrameProxy::OnSetPageFocus(bool is_focused) { diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h index 854b1a9..5fd375c 100644 --- a/content/renderer/render_frame_proxy.h +++ b/content/renderer/render_frame_proxy.h @@ -167,7 +167,8 @@ class CONTENT_EXPORT RenderFrameProxy void OnDispatchLoad(); void OnDidUpdateName(const std::string& name, const std::string& unique_name); void OnEnforceStrictMixedContentChecking(bool should_enforce); - void OnDidUpdateOrigin(const url::Origin& origin); + void OnDidUpdateOrigin(const url::Origin& origin, + bool is_potentially_trustworthy_unique_origin); void OnSetPageFocus(bool is_focused); void OnSetFocusedFrame(); diff --git a/media/blink/webencryptedmediaclient_impl.cc b/media/blink/webencryptedmediaclient_impl.cc index 8d2aa2e..0c2f48c 100644 --- a/media/blink/webencryptedmediaclient_impl.cc +++ b/media/blink/webencryptedmediaclient_impl.cc @@ -106,8 +106,7 @@ void WebEncryptedMediaClientImpl::requestMediaKeySystemAccess( GetMediaClient()->RecordRapporURL("Media.OriginUrl.EME", security_origin); - blink::WebString error_message; - if (!request.getSecurityOrigin().isPotentiallyTrustworthy(error_message)) { + if (!request.getSecurityOrigin().isPotentiallyTrustworthy()) { GetMediaClient()->RecordRapporURL("Media.OriginUrl.EME.Insecure", security_origin); } diff --git a/media/blink/webmediaplayer_util.cc b/media/blink/webmediaplayer_util.cc index 05342f0..5828e9c 100644 --- a/media/blink/webmediaplayer_util.cc +++ b/media/blink/webmediaplayer_util.cc @@ -132,8 +132,7 @@ void ReportMetrics(blink::WebMediaPlayer::LoadType load_type, // For MSE, also report usage by secure/insecure origin. if (load_type == blink::WebMediaPlayer::LoadTypeMediaSource) { - blink::WebString error_message; - if (security_origin.isPotentiallyTrustworthy(error_message)) { + if (security_origin.isPotentiallyTrustworthy()) { GetMediaClient()->RecordRapporURL("Media.OriginUrl.MSE.Secure", security_origin_url); } else { diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process index 8e21a48..d8139f8 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process +++ b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process @@ -102,9 +102,6 @@ http/tests/navigation/success200-frames-loadsame.html [ Failure ] http/tests/xmlhttprequest/origin-whitelisting-all.html [ Failure ] http/tests/xmlhttprequest/origin-whitelisting-ip-addresses.html [ Failure ] -# https://crbug.com/571079 - Document::isSecureContext() doesn't work with OOPIFs -http/tests/security/secureContexts/unauthenticated.html [ Failure ] - # TODO(alexmos,lukasza): Triage these failures and assign more specific bugs. # No repro (maybe flaky? maybe really fixed? maybe repros only in debug build?): diff --git a/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/authenticated.html b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/authenticated.html index 07a070f..2e7673c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/authenticated.html +++ b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/authenticated.html @@ -23,7 +23,7 @@ async_test(function (t) { var messages = 0; window.addEventListener("message", t.step_func(function (e) { - if (e.origin == get_host_info().AUTHENTICATED_ORIGIN) + if (e.origin == get_host_info().HTTPS_ORIGIN) assert_true(e.data.isSecureContext); if (e.origin == get_host_info().UNAUTHENTICATED_ORIGIN) assert_false(e.data.isSecureContext); @@ -37,7 +37,7 @@ document.body.appendChild(i1); var i2 = document.createElement("iframe"); - i2.src = get_host_info().AUTHENTICATED_ORIGIN + "/security/secureContexts/resources/post-securecontext-status.html"; + i2.src = get_host_info().HTTPS_ORIGIN + "/security/secureContexts/resources/post-securecontext-status.html"; document.body.appendChild(i2); }, "Frames are either secure or insecure."); } diff --git a/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/authenticated_sandbox.html b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/authenticated_sandbox.html new file mode 100644 index 0000000..f890461 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/authenticated_sandbox.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html> +<head> + <title>Authenticated origin with sandbox iframe is secure</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharness-helpers.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/get-host-info.js"></script> +</head> +<body> + <script> + if (window.location.origin != get_host_info().AUTHENTICATED_ORIGIN) { + window.location = get_host_info().AUTHENTICATED_ORIGIN + + window.location.pathname; + } else { + test(function () { + assert_equals(window.location.origin, get_host_info().AUTHENTICATED_ORIGIN, "Sanity check the test runner."); + assert_true(window.isSecureContext); + }, "authenticated origin is secure."); + + async_test(function (t) { + var messages = 0; + window.addEventListener("message", t.step_func(function (e) { + assert_true(e.data.isSecureContext); + messages++; + if (messages >= 2) + t.done(); + }), false); + + var i1 = document.createElement("iframe"); + i1.srcdoc = "<iframe src='" + get_host_info().HTTPS_REMOTE_ORIGIN + "/security/secureContexts/resources/post-securecontext-status.html" + "'></iframe>"; + i1.sandbox = "allow-scripts"; + document.body.appendChild(i1); + + var i2 = document.createElement("iframe"); + i2.src = "/security/secureContexts/resources/dynamically-sandbox-and-iframe-https.html"; + document.body.appendChild(i2); + }, "Frames inside sandboxed frames are secure"); + } + </script> +</body> +</html> diff --git a/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/authenticated_srcdoc.html b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/authenticated_srcdoc.html new file mode 100644 index 0000000..bc34fd8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/authenticated_srcdoc.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html> +<head> + <title>Authenticated origin with srcdoc iframe is secure</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharness-helpers.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/get-host-info.js"></script> +</head> +<body> + <script> + if (window.location.origin != get_host_info().AUTHENTICATED_ORIGIN) { + window.location = get_host_info().AUTHENTICATED_ORIGIN + + window.location.pathname; + } else { + test(function () { + assert_equals(window.location.origin, get_host_info().AUTHENTICATED_ORIGIN, "Sanity check the test runner."); + assert_true(window.isSecureContext); + }, "authenticated origin is secure."); + + async_test(function (t) { + var messages = 0; + window.addEventListener("message", t.step_func(function (e) { + assert_true(e.data.isSecureContext); + messages++; + if (messages >= 1) + t.done(); + }), false); + + var i1 = document.createElement("iframe"); + i1.srcdoc = "<iframe src='" + get_host_info().HTTPS_REMOTE_ORIGIN + "/security/secureContexts/resources/post-securecontext-status.html" + "'></iframe>"; + document.body.appendChild(i1); + }, "Frames inside sandboxed frames are secure"); + } + </script> +</body> +</html> diff --git a/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/resources/dynamically-sandbox-and-iframe-https.html b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/resources/dynamically-sandbox-and-iframe-https.html new file mode 100644 index 0000000..a982914 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/resources/dynamically-sandbox-and-iframe-https.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> + <title>Dynamically apply sandbox and include HTTPS iframe</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharness-helpers.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/get-host-info.js"></script> +</head> +<body> +</body> +<script> + window.addEventListener("message", function (e) { + var meta = document.createElement("meta"); + meta.httpEquiv = "Content-Security-Policy"; + meta.content = "sandbox allow-scripts"; + document.head.appendChild(meta); + e.source.postMessage("go", "*"); + }); + + var i = document.createElement("iframe"); + i.src = get_host_info().HTTPS_REMOTE_ORIGIN + "/security/secureContexts/resources/post-securecontext-status-on-msg.html" + document.body.appendChild(i); +</script> +</html> diff --git a/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/resources/post-securecontext-status-on-msg.html b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/resources/post-securecontext-status-on-msg.html new file mode 100644 index 0000000..995c6d11 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/resources/post-securecontext-status-on-msg.html @@ -0,0 +1,7 @@ +<script> +window.addEventListener("message", function () { + if (window.top && window.top != window) + window.top.postMessage({ "isSecureContext": window.isSecureContext }, "*"); +}); +window.parent.postMessage("add-csp", "*"); +</script> diff --git a/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/unauthenticated.html b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/unauthenticated.html index aa9bb05..7881099 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/unauthenticated.html +++ b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/unauthenticated.html @@ -28,11 +28,11 @@ }), false); var i1 = document.createElement("iframe"); - i1.src = get_host_info().UNAUTHENTICATED_ORIGIN + "/security/secureContexts/resources/post-securecontext-status.html"; + i1.src = get_host_info().HTTP_REMOTE_ORIGIN + "/security/secureContexts/resources/post-securecontext-status.html"; document.body.appendChild(i1); var i2 = document.createElement("iframe"); - i2.src = get_host_info().AUTHENTICATED_ORIGIN + "/security/secureContexts/resources/post-securecontext-status.html"; + i2.src = get_host_info().HTTPS_REMOTE_ORIGIN + "/security/secureContexts/resources/post-securecontext-status.html"; document.body.appendChild(i2); }, "Frames are insecure"); } diff --git a/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/unauthenticated_sandbox.html b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/unauthenticated_sandbox.html new file mode 100644 index 0000000..ac3aa132 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/unauthenticated_sandbox.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html> +<head> + <title>Unauthenticated origin with sandbox iframe is insecure</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharness-helpers.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/get-host-info.js"></script> +</head> +<body> + <script> + if (window.location.origin != get_host_info().UNAUTHENTICATED_ORIGIN) { + window.location = get_host_info().UNAUTHENTICATED_ORIGIN + + window.location.pathname; + } else { + test(function () { + assert_equals(window.location.origin, get_host_info().UNAUTHENTICATED_ORIGIN, "Sanity check the test runner."); + assert_false(window.isSecureContext); + }, "unauthenticated origin is insecure."); + + async_test(function (t) { + var messages = 0; + window.addEventListener("message", t.step_func(function (e) { + assert_false(e.data.isSecureContext); + messages++; + if (messages >= 3) + t.done(); + }), false); + + var i1 = document.createElement("iframe"); + i1.srcdoc = "<iframe src='" + get_host_info().HTTP_REMOTE_ORIGIN + "/security/secureContexts/resources/post-securecontext-status.html" + "'></iframe>"; + i1.sandbox = "allow-scripts"; + document.body.appendChild(i1); + + var i2 = document.createElement("iframe"); + i2.srcdoc = "<iframe src='" + get_host_info().HTTPS_REMOTE_ORIGIN + "/security/secureContexts/resources/post-securecontext-status.html" + "'></iframe>"; + i2.sandbox = "allow-scripts"; + document.body.appendChild(i2); + + var i3 = document.createElement("iframe"); + i3.src = "/security/secureContexts/resources/dynamically-sandbox-and-iframe-https.html"; + document.body.appendChild(i3); + }, "Frames inside sandboxed frames are insecure"); + } + </script> +</body> +</html> diff --git a/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/unauthenticated_srcdoc.html b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/unauthenticated_srcdoc.html new file mode 100644 index 0000000..094728f --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/secureContexts/unauthenticated_srcdoc.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<html> +<head> + <title>Unauthenticated origin with srcdoc iframe is insecure</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharness-helpers.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/get-host-info.js"></script> +</head> +<body> + <script> + if (window.location.origin != get_host_info().UNAUTHENTICATED_ORIGIN) { + window.location = get_host_info().UNAUTHENTICATED_ORIGIN + + window.location.pathname; + } else { + test(function () { + assert_equals(window.location.origin, get_host_info().UNAUTHENTICATED_ORIGIN, "Sanity check the test runner."); + assert_false(window.isSecureContext); + }, "unauthenticated origin is insecure."); + + async_test(function (t) { + var messages = 0; + window.addEventListener("message", t.step_func(function (e) { + assert_false(e.data.isSecureContext); + messages++; + if (messages >= 2) + t.done(); + }), false); + + var i1 = document.createElement("iframe"); + i1.srcdoc = "<iframe src='" + get_host_info().HTTP_REMOTE_ORIGIN + "/security/secureContexts/resources/post-securecontext-status.html" + "'></iframe>"; + document.body.appendChild(i1); + + var i2 = document.createElement("iframe"); + i2.srcdoc = "<iframe src='" + get_host_info().AUTHENTICATED_ORIGIN + "/security/secureContexts/resources/post-securecontext-status.html" + "'></iframe>"; + document.body.appendChild(i2); + }, "Frames inside srcdoc frames are insecure"); + } + </script> +</body> +</html> diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index 12c4f9f..cfb9c34 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp @@ -3425,35 +3425,20 @@ bool Document::isSecureContextImpl(String* errorMessage, const SecureContextChec // // In all cases, a frame must be potentially trustworthy in addition to // having an exception listed in order for the exception to be granted. - if (SecurityContext::isSandboxed(SandboxOrigin)) { - RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url()); - if (!isOriginPotentiallyTrustworthy(origin.get(), errorMessage)) - return false; - if (SchemeRegistry::schemeShouldBypassSecureContextCheck(origin->protocol())) - return true; - } else { - if (!isOriginPotentiallyTrustworthy(getSecurityOrigin(), errorMessage)) - return false; - if (SchemeRegistry::schemeShouldBypassSecureContextCheck(getSecurityOrigin()->protocol())) - return true; - } + if (!isOriginPotentiallyTrustworthy(getSecurityOrigin(), errorMessage)) + return false; + + if (SchemeRegistry::schemeShouldBypassSecureContextCheck(getSecurityOrigin()->protocol())) + return true; if (privilegeContextCheck == StandardSecureContextCheck) { - Document* context = parentDocument(); - while (context) { - // Skip to the next ancestor if it's a srcdoc. - if (!context->isSrcdocDocument()) { - if (context->securityContext().isSandboxed(SandboxOrigin)) { - // For a sandboxed origin, use the document's URL. - RefPtr<SecurityOrigin> origin = SecurityOrigin::create(context->url()); - if (!isOriginPotentiallyTrustworthy(origin.get(), errorMessage)) - return false; - } else { - if (!isOriginPotentiallyTrustworthy(context->getSecurityOrigin(), errorMessage)) - return false; - } - } - context = context->parentDocument(); + if (!m_frame) + return true; + Frame* parent = m_frame->tree().parent(); + while (parent) { + if (!isOriginPotentiallyTrustworthy(parent->securityContext()->getSecurityOrigin(), errorMessage)) + return false; + parent = parent->tree().parent(); } } return true; @@ -4980,10 +4965,14 @@ void Document::initSecurityContext(const DocumentInit& initializer) if (isSandboxed(SandboxOrigin)) { m_cookieURL = m_url; setSecurityOrigin(SecurityOrigin::createUnique()); - // If we're supposed to inherit our security origin from our owner, - // but we're also sandboxed, the only thing we inherit is the ability - // to load local resources. This lets about:blank iframes in file:// - // URL documents load images and other resources from the file system. + // If we're supposed to inherit our security origin from our + // owner, but we're also sandboxed, the only things we inherit are + // the origin's potential trustworthiness and the ability to + // load local resources. The latter lets about:blank iframes in + // file:// URL documents load images and other resources from + // the file system. + if (initializer.owner() && initializer.owner()->getSecurityOrigin()->isPotentiallyTrustworthy()) + getSecurityOrigin()->setUniqueOriginIsPotentiallyTrustworthy(true); if (initializer.owner() && initializer.owner()->getSecurityOrigin()->canLoadLocalResources()) getSecurityOrigin()->grantLoadLocalResources(); } else if (initializer.owner()) { @@ -5039,8 +5028,8 @@ void Document::initSecurityContext(const DocumentInit& initializer) setBaseURLOverride(initializer.parentBaseURL()); } - if (getSecurityOrigin()->hasSuborigin()) - enforceSuborigin(getSecurityOrigin()->suboriginName()); + if (getSecurityOrigin()->isUnique() && SecurityOrigin::create(m_url)->isPotentiallyTrustworthy()) + getSecurityOrigin()->setUniqueOriginIsPotentiallyTrustworthy(true); } void Document::initContentSecurityPolicy(PassRefPtrWillBeRawPtr<ContentSecurityPolicy> csp) @@ -5101,6 +5090,18 @@ bool Document::allowExecutingScripts(Node* node) return true; } +void Document::enforceSandboxFlags(SandboxFlags mask) +{ + RefPtr<SecurityOrigin> standInOrigin = getSecurityOrigin(); + applySandboxFlags(mask); + // Send a notification if the origin has been updated. + if (standInOrigin && !standInOrigin->isUnique() && getSecurityOrigin()->isUnique()) { + getSecurityOrigin()->setUniqueOriginIsPotentiallyTrustworthy(standInOrigin->isPotentiallyTrustworthy()); + if (frame()) + frame()->loader().client()->didUpdateToUniqueOrigin(); + } +} + void Document::updateSecurityOrigin(PassRefPtr<SecurityOrigin> origin) { setSecurityOrigin(origin); diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h index 960fd2d..efc719f 100644 --- a/third_party/WebKit/Source/core/dom/Document.h +++ b/third_party/WebKit/Source/core/dom/Document.h @@ -866,6 +866,8 @@ public: bool allowInlineEventHandlers(Node*, EventListener*, const String& contextURL, const WTF::OrdinalNumber& contextLine); bool allowExecutingScripts(Node*); + void enforceSandboxFlags(SandboxFlags mask) override; + void statePopped(PassRefPtr<SerializedScriptValue>); enum LoadEventProgress { diff --git a/third_party/WebKit/Source/core/dom/DocumentTest.cpp b/third_party/WebKit/Source/core/dom/DocumentTest.cpp index b83d53b..3ab50ae 100644 --- a/third_party/WebKit/Source/core/dom/DocumentTest.cpp +++ b/third_party/WebKit/Source/core/dom/DocumentTest.cpp @@ -37,6 +37,7 @@ #include "core/testing/DummyPageHolder.h" #include "platform/heap/Handle.h" #include "platform/weborigin/ReferrerPolicy.h" +#include "platform/weborigin/SchemeRegistry.h" #include "platform/weborigin/SecurityOrigin.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -353,4 +354,40 @@ TEST_F(DocumentTest, StyleVersion) EXPECT_NE(previousStyleVersion, document().styleVersion()); } +TEST_F(DocumentTest, EnforceSandboxFlags) +{ + RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromString("http://example.test"); + document().setSecurityOrigin(origin); + SandboxFlags mask = SandboxNavigation; + document().enforceSandboxFlags(mask); + EXPECT_EQ(origin, document().getSecurityOrigin()); + EXPECT_FALSE(document().getSecurityOrigin()->isPotentiallyTrustworthy()); + + mask |= SandboxOrigin; + document().enforceSandboxFlags(mask); + EXPECT_TRUE(document().getSecurityOrigin()->isUnique()); + EXPECT_FALSE(document().getSecurityOrigin()->isPotentiallyTrustworthy()); + + // A unique origin does not bypass secure context checks unless it + // is also potentially trustworthy. + SchemeRegistry::registerURLSchemeBypassingSecureContextCheck("very-special-scheme"); + origin = SecurityOrigin::createFromString("very-special-scheme://example.test"); + document().setSecurityOrigin(origin); + document().enforceSandboxFlags(mask); + EXPECT_TRUE(document().getSecurityOrigin()->isUnique()); + EXPECT_FALSE(document().getSecurityOrigin()->isPotentiallyTrustworthy()); + + SchemeRegistry::registerURLSchemeAsSecure("very-special-scheme"); + document().setSecurityOrigin(origin); + document().enforceSandboxFlags(mask); + EXPECT_TRUE(document().getSecurityOrigin()->isUnique()); + EXPECT_TRUE(document().getSecurityOrigin()->isPotentiallyTrustworthy()); + + origin = SecurityOrigin::createFromString("https://example.test"); + document().setSecurityOrigin(origin); + document().enforceSandboxFlags(mask); + EXPECT_TRUE(document().getSecurityOrigin()->isUnique()); + EXPECT_TRUE(document().getSecurityOrigin()->isPotentiallyTrustworthy()); +} + } // namespace blink diff --git a/third_party/WebKit/Source/core/dom/SecurityContext.cpp b/third_party/WebKit/Source/core/dom/SecurityContext.cpp index f830e2d..b0ed8c7 100644 --- a/third_party/WebKit/Source/core/dom/SecurityContext.cpp +++ b/third_party/WebKit/Source/core/dom/SecurityContext.cpp @@ -61,6 +61,11 @@ void SecurityContext::setContentSecurityPolicy(PassRefPtrWillBeRawPtr<ContentSec void SecurityContext::enforceSandboxFlags(SandboxFlags mask) { + applySandboxFlags(mask); +} + +void SecurityContext::applySandboxFlags(SandboxFlags mask) +{ m_sandboxFlags |= mask; if (isSandboxed(SandboxOrigin) && getSecurityOrigin() && !getSecurityOrigin()->isUnique()) { diff --git a/third_party/WebKit/Source/core/dom/SecurityContext.h b/third_party/WebKit/Source/core/dom/SecurityContext.h index b420c26..952e1cd 100644 --- a/third_party/WebKit/Source/core/dom/SecurityContext.h +++ b/third_party/WebKit/Source/core/dom/SecurityContext.h @@ -68,7 +68,7 @@ public: SandboxFlags getSandboxFlags() const { return m_sandboxFlags; } bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; } - void enforceSandboxFlags(SandboxFlags mask); + virtual void enforceSandboxFlags(SandboxFlags mask); void setAddressSpace(WebAddressSpace space) { m_addressSpace = space; } WebAddressSpace addressSpace() const { return m_addressSpace; } @@ -93,6 +93,8 @@ protected: void setContentSecurityPolicy(PassRefPtrWillBeRawPtr<ContentSecurityPolicy>); + void applySandboxFlags(SandboxFlags mask); + private: RefPtr<SecurityOrigin> m_securityOrigin; RefPtrWillBeMember<ContentSecurityPolicy> m_contentSecurityPolicy; diff --git a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h index 19ae3cf..34c16c7 100644 --- a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h +++ b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h @@ -206,6 +206,8 @@ public: virtual void didEnforceStrictMixedContentChecking() {} + virtual void didUpdateToUniqueOrigin() {} + virtual void didChangeSandboxFlags(Frame* childFrame, SandboxFlags) { } virtual void didChangeFrameOwnerProperties(HTMLFrameElementBase*) { } diff --git a/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp b/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp index 559b177..b2f4456 100644 --- a/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp +++ b/third_party/WebKit/Source/platform/exported/WebSecurityOrigin.cpp @@ -123,13 +123,10 @@ bool WebSecurityOrigin::canRequest(const WebURL& url) const return m_private->canRequest(url); } -bool WebSecurityOrigin::isPotentiallyTrustworthy(WebString& errorMessage) const +bool WebSecurityOrigin::isPotentiallyTrustworthy() const { ASSERT(m_private); - bool result = m_private->isPotentiallyTrustworthy(); - if (!result) - errorMessage = WTF::String(m_private->isPotentiallyTrustworthyErrorMessage()); - return result; + return m_private->isPotentiallyTrustworthy(); } WebString WebSecurityOrigin::toString() const diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp index 61fffb7..4cac0e8 100644 --- a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp +++ b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.cpp @@ -126,6 +126,7 @@ SecurityOrigin::SecurityOrigin(const KURL& url) , m_universalAccess(false) , m_domainWasSetInDOM(false) , m_blockLocalAccessFromLocalOrigin(false) + , m_isUniqueOriginPotentiallyTrustworthy(false) { // Suborigins are serialized into the host, so extract it if necessary. String suboriginName; @@ -154,6 +155,7 @@ SecurityOrigin::SecurityOrigin() , m_domainWasSetInDOM(false) , m_canLoadLocalResources(false) , m_blockLocalAccessFromLocalOrigin(false) + , m_isUniqueOriginPotentiallyTrustworthy(false) { } @@ -169,6 +171,7 @@ SecurityOrigin::SecurityOrigin(const SecurityOrigin* other) , m_domainWasSetInDOM(other->m_domainWasSetInDOM) , m_canLoadLocalResources(other->m_canLoadLocalResources) , m_blockLocalAccessFromLocalOrigin(other->m_blockLocalAccessFromLocalOrigin) + , m_isUniqueOriginPotentiallyTrustworthy(other->m_isUniqueOriginPotentiallyTrustworthy) { } @@ -356,6 +359,9 @@ bool SecurityOrigin::canDisplay(const KURL& url) const bool SecurityOrigin::isPotentiallyTrustworthy() const { ASSERT(m_protocol != "data"); + if (isUnique()) + return m_isUniqueOriginPotentiallyTrustworthy; + if (SchemeRegistry::shouldTreatURLSchemeAsSecure(m_protocol) || isLocal() || isLocalhost()) return true; @@ -551,4 +557,10 @@ void SecurityOrigin::transferPrivilegesFrom(PassOwnPtr<PrivilegeData> privilegeD m_blockLocalAccessFromLocalOrigin = privilegeData->m_blockLocalAccessFromLocalOrigin; } +void SecurityOrigin::setUniqueOriginIsPotentiallyTrustworthy(bool isUniqueOriginPotentiallyTrustworthy) +{ + ASSERT(!isUniqueOriginPotentiallyTrustworthy || isUnique()); + m_isUniqueOriginPotentiallyTrustworthy = isUniqueOriginPotentiallyTrustworthy; +} + } // namespace blink diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h index 4cdc68a..af13d6c 100644 --- a/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h +++ b/third_party/WebKit/Source/platform/weborigin/SecurityOrigin.h @@ -250,6 +250,8 @@ public: PassOwnPtr<PrivilegeData> createPrivilegeData() const; void transferPrivilegesFrom(PassOwnPtr<PrivilegeData>); + void setUniqueOriginIsPotentiallyTrustworthy(bool isUniqueOriginPotentiallyTrustworthy); + private: friend class SecurityOriginTest; FRIEND_TEST_ALL_PREFIXES(SecurityOriginTest, Suborigins); @@ -277,6 +279,7 @@ private: bool m_domainWasSetInDOM; bool m_canLoadLocalResources; bool m_blockLocalAccessFromLocalOrigin; + bool m_isUniqueOriginPotentiallyTrustworthy; }; } // namespace blink diff --git a/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp b/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp index c04fd58..c74840d 100644 --- a/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp +++ b/third_party/WebKit/Source/platform/weborigin/SecurityOriginTest.cpp @@ -163,6 +163,11 @@ TEST_F(SecurityOriginTest, IsPotentiallyTrustworthy) // Unique origins are not considered secure. RefPtr<SecurityOrigin> uniqueOrigin = SecurityOrigin::createUnique(); EXPECT_FALSE(uniqueOrigin->isPotentiallyTrustworthy()); + // ... unless they are specially marked as such. + uniqueOrigin->setUniqueOriginIsPotentiallyTrustworthy(true); + EXPECT_TRUE(uniqueOrigin->isPotentiallyTrustworthy()); + uniqueOrigin->setUniqueOriginIsPotentiallyTrustworthy(false); + EXPECT_FALSE(uniqueOrigin->isPotentiallyTrustworthy()); } TEST_F(SecurityOriginTest, IsSecure) diff --git a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp index 11da846..6a74bb2 100644 --- a/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp +++ b/third_party/WebKit/Source/web/FrameLoaderClientImpl.cpp @@ -914,6 +914,14 @@ void FrameLoaderClientImpl::didEnforceStrictMixedContentChecking() m_webFrame->client()->didEnforceStrictMixedContentChecking(); } +void FrameLoaderClientImpl::didUpdateToUniqueOrigin() +{ + if (!m_webFrame->client()) + return; + ASSERT(m_webFrame->getSecurityOrigin().isUnique()); + m_webFrame->client()->didUpdateToUniqueOrigin(m_webFrame->getSecurityOrigin().isPotentiallyTrustworthy()); +} + void FrameLoaderClientImpl::didChangeSandboxFlags(Frame* childFrame, SandboxFlags flags) { if (!m_webFrame->client()) diff --git a/third_party/WebKit/Source/web/FrameLoaderClientImpl.h b/third_party/WebKit/Source/web/FrameLoaderClientImpl.h index b8e6ef7..38bab18 100644 --- a/third_party/WebKit/Source/web/FrameLoaderClientImpl.h +++ b/third_party/WebKit/Source/web/FrameLoaderClientImpl.h @@ -150,6 +150,7 @@ public: void frameFocused() const override; void didChangeName(const String& name, const String& uniqueName) override; void didEnforceStrictMixedContentChecking() override; + void didUpdateToUniqueOrigin() override; void didChangeSandboxFlags(Frame* childFrame, SandboxFlags) override; void didChangeFrameOwnerProperties(HTMLFrameElementBase*) override; diff --git a/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp b/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp index bd52f81..6c6530b 100644 --- a/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp +++ b/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp @@ -696,6 +696,14 @@ void WebRemoteFrameImpl::setReplicatedShouldEnforceStrictMixedContentChecking(bo frame()->securityContext()->setShouldEnforceStrictMixedContentChecking(shouldEnforce); } +void WebRemoteFrameImpl::setReplicatedPotentiallyTrustworthyUniqueOrigin(bool isUniqueOriginPotentiallyTrustworthy) const +{ + ASSERT(frame()); + // If |isUniqueOriginPotentiallyTrustworthy| is true, then the origin must be unique. + ASSERT(!isUniqueOriginPotentiallyTrustworthy || frame()->securityContext()->getSecurityOrigin()->isUnique()); + frame()->securityContext()->getSecurityOrigin()->setUniqueOriginIsPotentiallyTrustworthy(isUniqueOriginPotentiallyTrustworthy); +} + void WebRemoteFrameImpl::DispatchLoadEventForFrameOwner() const { ASSERT(frame()->owner()->isLocal()); diff --git a/third_party/WebKit/Source/web/WebRemoteFrameImpl.h b/third_party/WebKit/Source/web/WebRemoteFrameImpl.h index 323b420..4a87c3a 100644 --- a/third_party/WebKit/Source/web/WebRemoteFrameImpl.h +++ b/third_party/WebKit/Source/web/WebRemoteFrameImpl.h @@ -163,6 +163,7 @@ public: void setReplicatedSandboxFlags(WebSandboxFlags) const override; void setReplicatedName(const WebString& name, const WebString& uniqueName) const override; void setReplicatedShouldEnforceStrictMixedContentChecking(bool) const override; + void setReplicatedPotentiallyTrustworthyUniqueOrigin(bool) const override; void DispatchLoadEventForFrameOwner() const override; void didStartLoading() override; diff --git a/third_party/WebKit/public/platform/WebSecurityOrigin.h b/third_party/WebKit/public/platform/WebSecurityOrigin.h index c4191bb..7fa1f2b 100644 --- a/third_party/WebKit/public/platform/WebSecurityOrigin.h +++ b/third_party/WebKit/public/platform/WebSecurityOrigin.h @@ -95,7 +95,7 @@ public: // machine or over the network from a // cryptographically-authenticated origin, as described in // https://w3c.github.io/webappsec/specs/powerfulfeatures/#is-origin-trustworthy. - BLINK_PLATFORM_EXPORT bool isPotentiallyTrustworthy(WebString& errorMessage) const; + BLINK_PLATFORM_EXPORT bool isPotentiallyTrustworthy() const; // Returns a string representation of the WebSecurityOrigin. The empty // WebSecurityOrigin is represented by "null". The representation of a diff --git a/third_party/WebKit/public/web/WebFrameClient.h b/third_party/WebKit/public/web/WebFrameClient.h index 4741cd8..2beb12e 100644 --- a/third_party/WebKit/public/web/WebFrameClient.h +++ b/third_party/WebKit/public/web/WebFrameClient.h @@ -182,6 +182,14 @@ public: // This frame has been set to enforce strict mixed content checking. virtual void didEnforceStrictMixedContentChecking() {} + // This frame has been updated to a unique origin, which should be + // considered potentially trustworthy if + // |isPotentiallyTrustworthyUniqueOrigin| is true. TODO(estark): + // this method only exists to support dynamic sandboxing via a CSP + // delivered in a <meta> tag. This is not supposed to be allowed per + // the CSP spec and should be ripped out. https://crbug.com/594645 + virtual void didUpdateToUniqueOrigin(bool isPotentiallyTrustworthyUniqueOrigin) {} + // The sandbox flags have changed for a child frame of this frame. virtual void didChangeSandboxFlags(WebFrame* childFrame, WebSandboxFlags flags) { } diff --git a/third_party/WebKit/public/web/WebRemoteFrame.h b/third_party/WebKit/public/web/WebRemoteFrame.h index 3cef63c..65638c4 100644 --- a/third_party/WebKit/public/web/WebRemoteFrame.h +++ b/third_party/WebKit/public/web/WebRemoteFrame.h @@ -42,6 +42,10 @@ public: // Set frame enforcement of strict mixed content checking replicated from another process. virtual void setReplicatedShouldEnforceStrictMixedContentChecking(bool) const = 0; + // Set the frame to a unique origin that is potentially trustworthy, + // replicated from another process. + virtual void setReplicatedPotentiallyTrustworthyUniqueOrigin(bool) const = 0; + virtual void DispatchLoadEventForFrameOwner() const = 0; virtual void didStartLoading() = 0; |