Commit f166971a authored by Karan Bhatia's avatar Karan Bhatia Committed by Commit Bot

Blink: Move isolated world CSP handling to the core layer.

This CL moves the isolated world CSP handling from DOMWrapperWorld (at the
platform/bindings/layer) to the IsolatedWorldCSP singleton instance (at the
bindings/core layer). The platform/bindings layer doesn't know the concept of a
CSP, hence move it to the bindings/core/ layer. Furthermore, DOMWrapperWorld is
per world, hence it shouldn't necessarily store isolated world specific data.

This is required to store ContentSecurityPolicy instances for isolated worlds to
add CSP support for the isolated worlds. This CL should have no behavior change.

BUG=896041

Change-Id: I0ac995dbae549379934bfadeed148d4ca91c8706
Reviewed-on: https://chromium-review.googlesource.com/c/1354567Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Karan Bhatia <karandeepb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612355}
parent d3949b63
include_rules = [ include_rules = [
"+base/logging.h",
"+base/memory/scoped_refptr.h", "+base/memory/scoped_refptr.h",
"+base/process/process_metrics.h", "+base/process/process_metrics.h",
"+gin/public", "+gin/public",
......
...@@ -70,6 +70,8 @@ bindings_core_v8_files = ...@@ -70,6 +70,8 @@ bindings_core_v8_files =
"core/v8/scheduled_action.h", "core/v8/scheduled_action.h",
"core/v8/script_controller.cc", "core/v8/script_controller.cc",
"core/v8/script_controller.h", "core/v8/script_controller.h",
"core/v8/isolated_world_csp.cc",
"core/v8/isolated_world_csp.h",
"core/v8/script_custom_element_definition.cc", "core/v8/script_custom_element_definition.cc",
"core/v8/script_custom_element_definition.h", "core/v8/script_custom_element_definition.h",
"core/v8/script_custom_element_definition_builder.cc", "core/v8/script_custom_element_definition_builder.cc",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h"
#include "base/logging.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/wtf.h"
namespace blink {
// static
IsolatedWorldCSP& IsolatedWorldCSP::Get() {
DCHECK(IsMainThread());
DEFINE_STATIC_LOCAL(IsolatedWorldCSP, g_isolated_world_csp, ());
return g_isolated_world_csp;
}
void IsolatedWorldCSP::SetContentSecurityPolicy(int world_id,
const String& policy) {
DCHECK(IsMainThread());
DCHECK(DOMWrapperWorld::IsIsolatedWorldId(world_id));
if (policy.IsEmpty())
csp_map_.erase(world_id);
else
csp_map_.Set(world_id, true);
}
bool IsolatedWorldCSP::HasContentSecurityPolicy(int world_id) const {
DCHECK(IsMainThread());
DCHECK(DOMWrapperWorld::IsIsolatedWorldId(world_id));
auto it = csp_map_.find(world_id);
return it != csp_map_.end() ? it->value : false;
}
IsolatedWorldCSP::IsolatedWorldCSP() = default;
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_ISOLATED_WORLD_CSP_H_
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_ISOLATED_WORLD_CSP_H_
#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
// A singleton storing content security policy for each isolated world.
class CORE_EXPORT IsolatedWorldCSP {
public:
static IsolatedWorldCSP& Get();
// Associated an isolated world with a Content Security Policy. Resources
// embedded into the main world's DOM from script executed in an isolated
// world should be restricted based on the isolated world's DOM, not the
// main world's.
//
// FIXME: Right now, resource injection simply bypasses the main world's
// DOM. More work is necessary to allow the isolated world's policy to be
// applied correctly.
void SetContentSecurityPolicy(int world_id, const String& policy);
bool HasContentSecurityPolicy(int world_id) const;
private:
IsolatedWorldCSP();
// Map from the isolated world |world_id| to a bool denoting if it has a CSP
// defined.
HashMap<int, bool> csp_map_;
DISALLOW_COPY_AND_ASSIGN(IsolatedWorldCSP);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_ISOLATED_WORLD_CSP_H_
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_application_cache_host.h" #include "third_party/blink/public/platform/web_application_cache_host.h"
#include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/core/dom/document_fragment.h" #include "third_party/blink/renderer/core/dom/document_fragment.h"
...@@ -980,17 +981,19 @@ TEST_F(DocumentTest, CanExecuteScriptsWithSandboxAndIsolatedWorld) { ...@@ -980,17 +981,19 @@ TEST_F(DocumentTest, CanExecuteScriptsWithSandboxAndIsolatedWorld) {
ScriptState* isolated_world_without_csp_script_state = ScriptState* isolated_world_without_csp_script_state =
ToScriptState(frame, *world_without_csp); ToScriptState(frame, *world_without_csp);
ASSERT_TRUE(world_without_csp->IsIsolatedWorld()); ASSERT_TRUE(world_without_csp->IsIsolatedWorld());
EXPECT_FALSE(world_without_csp->IsolatedWorldHasContentSecurityPolicy()); EXPECT_FALSE(IsolatedWorldCSP::Get().HasContentSecurityPolicy(
kIsolatedWorldWithoutCSPId));
constexpr int kIsolatedWorldWithCSPId = 2; constexpr int kIsolatedWorldWithCSPId = 2;
scoped_refptr<DOMWrapperWorld> world_with_csp = scoped_refptr<DOMWrapperWorld> world_with_csp =
DOMWrapperWorld::EnsureIsolatedWorld(isolate, kIsolatedWorldWithCSPId); DOMWrapperWorld::EnsureIsolatedWorld(isolate, kIsolatedWorldWithCSPId);
DOMWrapperWorld::SetIsolatedWorldContentSecurityPolicy( IsolatedWorldCSP::Get().SetContentSecurityPolicy(
kIsolatedWorldWithCSPId, String::FromUTF8("script-src *")); kIsolatedWorldWithCSPId, String::FromUTF8("script-src *"));
ScriptState* isolated_world_with_csp_script_state = ScriptState* isolated_world_with_csp_script_state =
ToScriptState(frame, *world_with_csp); ToScriptState(frame, *world_with_csp);
ASSERT_TRUE(world_with_csp->IsIsolatedWorld()); ASSERT_TRUE(world_with_csp->IsIsolatedWorld());
EXPECT_TRUE(world_with_csp->IsolatedWorldHasContentSecurityPolicy()); EXPECT_TRUE(IsolatedWorldCSP::Get().HasContentSecurityPolicy(
kIsolatedWorldWithCSPId));
{ {
// Since the page is sandboxed, main world script execution shouldn't be // Since the page is sandboxed, main world script execution shouldn't be
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h" #include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/document.h"
...@@ -1696,7 +1697,7 @@ bool ContentSecurityPolicy::ShouldBypassMainWorld( ...@@ -1696,7 +1697,7 @@ bool ContentSecurityPolicy::ShouldBypassMainWorld(
if (!world.IsIsolatedWorld()) if (!world.IsIsolatedWorld())
return false; return false;
return world.IsolatedWorldHasContentSecurityPolicy(); return IsolatedWorldCSP::Get().HasContentSecurityPolicy(world.GetWorldId());
} }
bool ContentSecurityPolicy::ShouldSendViolationReport( bool ContentSecurityPolicy::ShouldSendViolationReport(
......
...@@ -133,6 +133,7 @@ ...@@ -133,6 +133,7 @@
#include "third_party/blink/public/web/web_text_direction.h" #include "third_party/blink/public/web/web_text_direction.h"
#include "third_party/blink/public/web/web_tree_scope_type.h" #include "third_party/blink/public/web/web_tree_scope_type.h"
#include "third_party/blink/renderer/bindings/core/v8/binding_security.h" #include "third_party/blink/renderer/bindings/core/v8/binding_security.h"
#include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h"
#include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h" #include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h" #include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h" #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
...@@ -727,7 +728,7 @@ void WebLocalFrameImpl::SetIsolatedWorldContentSecurityPolicy( ...@@ -727,7 +728,7 @@ void WebLocalFrameImpl::SetIsolatedWorldContentSecurityPolicy(
int world_id, int world_id,
const WebString& policy) { const WebString& policy) {
DCHECK(GetFrame()); DCHECK(GetFrame());
DOMWrapperWorld::SetIsolatedWorldContentSecurityPolicy(world_id, policy); IsolatedWorldCSP::Get().SetContentSecurityPolicy(world_id, policy);
} }
void WebLocalFrameImpl::SetIsolatedWorldHumanReadableName( void WebLocalFrameImpl::SetIsolatedWorldHumanReadableName(
......
...@@ -54,11 +54,6 @@ static WorldMap& GetWorldMap() { ...@@ -54,11 +54,6 @@ static WorldMap& GetWorldMap() {
} }
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
static bool IsIsolatedWorldId(int world_id) {
return DOMWrapperWorld::kMainWorldId < world_id &&
world_id < DOMWrapperWorld::kDOMWrapperWorldIsolatedWorldIdLimit;
}
static bool IsMainWorldId(int world_id) { static bool IsMainWorldId(int world_id) {
return world_id == DOMWrapperWorld::kMainWorldId; return world_id == DOMWrapperWorld::kMainWorldId;
} }
...@@ -212,35 +207,6 @@ void DOMWrapperWorld::SetNonMainWorldHumanReadableName( ...@@ -212,35 +207,6 @@ void DOMWrapperWorld::SetNonMainWorldHumanReadableName(
IsolatedWorldHumanReadableNames().Set(world_id, human_readable_name); IsolatedWorldHumanReadableNames().Set(world_id, human_readable_name);
} }
typedef HashMap<int, bool> IsolatedWorldContentSecurityPolicyMap;
static IsolatedWorldContentSecurityPolicyMap&
IsolatedWorldContentSecurityPolicies() {
DCHECK(IsMainThread());
DEFINE_STATIC_LOCAL(IsolatedWorldContentSecurityPolicyMap, map, ());
return map;
}
bool DOMWrapperWorld::IsolatedWorldHasContentSecurityPolicy() {
DCHECK(this->IsIsolatedWorld());
IsolatedWorldContentSecurityPolicyMap& policies =
IsolatedWorldContentSecurityPolicies();
IsolatedWorldContentSecurityPolicyMap::iterator it =
policies.find(GetWorldId());
return it == policies.end() ? false : it->value;
}
void DOMWrapperWorld::SetIsolatedWorldContentSecurityPolicy(
int world_id,
const String& policy) {
#if DCHECK_IS_ON()
DCHECK(IsIsolatedWorldId(world_id));
#endif
if (!policy.IsEmpty())
IsolatedWorldContentSecurityPolicies().Set(world_id, true);
else
IsolatedWorldContentSecurityPolicies().erase(world_id);
}
void DOMWrapperWorld::RegisterDOMObjectHolderInternal( void DOMWrapperWorld::RegisterDOMObjectHolderInternal(
std::unique_ptr<DOMObjectHolderBase> holder_base) { std::unique_ptr<DOMObjectHolderBase> holder_base) {
DCHECK(!dom_object_holders_.Contains(holder_base.get())); DCHECK(!dom_object_holders_.Contains(holder_base.get()));
......
...@@ -79,6 +79,11 @@ class PLATFORM_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> { ...@@ -79,6 +79,11 @@ class PLATFORM_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
kWorker, kWorker,
}; };
static bool IsIsolatedWorldId(int world_id) {
return DOMWrapperWorld::kMainWorldId < world_id &&
world_id < DOMWrapperWorld::kDOMWrapperWorldIsolatedWorldIdLimit;
}
// Creates a world other than IsolatedWorld. Note this can return nullptr if // Creates a world other than IsolatedWorld. Note this can return nullptr if
// GenerateWorldIdForType fails to allocate a valid id. // GenerateWorldIdForType fails to allocate a valid id.
static scoped_refptr<DOMWrapperWorld> Create(v8::Isolate*, WorldType); static scoped_refptr<DOMWrapperWorld> Create(v8::Isolate*, WorldType);
...@@ -121,18 +126,6 @@ class PLATFORM_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> { ...@@ -121,18 +126,6 @@ class PLATFORM_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
scoped_refptr<SecurityOrigin>); scoped_refptr<SecurityOrigin>);
SecurityOrigin* IsolatedWorldSecurityOrigin(); SecurityOrigin* IsolatedWorldSecurityOrigin();
// Associated an isolated world with a Content Security Policy. Resources
// embedded into the main world's DOM from script executed in an isolated
// world should be restricted based on the isolated world's DOM, not the
// main world's.
//
// FIXME: Right now, resource injection simply bypasses the main world's
// DOM. More work is necessary to allow the isolated world's policy to be
// applied correctly.
static void SetIsolatedWorldContentSecurityPolicy(int world_id,
const String& policy);
bool IsolatedWorldHasContentSecurityPolicy();
static bool HasWrapperInAnyWorldInMainThread(ScriptWrappable*); static bool HasWrapperInAnyWorldInMainThread(ScriptWrappable*);
bool IsMainWorld() const { return world_type_ == WorldType::kMain; } bool IsMainWorld() const { return world_type_ == WorldType::kMain; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment