diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc | 159 |
1 files changed, 153 insertions, 6 deletions
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc b/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc index c82ca3efb48..07591f1ecb9 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc @@ -4,13 +4,121 @@ #include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h" +#include <utility> + #include "base/logging.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" +#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "third_party/blink/renderer/platform/wtf/wtf.h" namespace blink { +namespace { + +class IsolatedWorldCSPDelegate final + : public GarbageCollectedFinalized<IsolatedWorldCSPDelegate>, + public ContentSecurityPolicyDelegate { + USING_GARBAGE_COLLECTED_MIXIN(IsolatedWorldCSPDelegate); + + public: + IsolatedWorldCSPDelegate(Document& document, + scoped_refptr<SecurityOrigin> security_origin, + bool apply_policy) + : document_(&document), + security_origin_(std::move(security_origin)), + apply_policy_(apply_policy) { + DCHECK(security_origin_); + } + + void Trace(blink::Visitor* visitor) override { + visitor->Trace(document_); + ContentSecurityPolicyDelegate::Trace(visitor); + } + + const SecurityOrigin* GetSecurityOrigin() override { + return security_origin_.get(); + } + + const KURL& Url() const override { + // This is used to populate violation data's violation url. See + // https://w3c.github.io/webappsec-csp/#violation-url. + // TODO(crbug.com/916885): Figure out if we want to support violation + // reporting for isolated world CSPs. + DEFINE_STATIC_LOCAL(KURL, g_empty_url, ()); + return g_empty_url; + } + + // Isolated world CSPs don't support these directives: "sandbox", + // "treat-as-public-address", "trusted-types" and "upgrade-insecure-requests". + // These directives depend on ExecutionContext for their implementation and + // since isolated worlds don't have their own ExecutionContext, these are not + // supported. + void SetSandboxFlags(SandboxFlags) override {} + void SetAddressSpace(mojom::IPAddressSpace) override {} + void SetRequireTrustedTypes() override {} + void AddInsecureRequestPolicy(WebInsecureRequestPolicy) override {} + + // TODO(crbug.com/916885): Figure out if we want to support violation + // reporting for isolated world CSPs. + std::unique_ptr<SourceLocation> GetSourceLocation() override { + return nullptr; + } + base::Optional<uint16_t> GetStatusCode() override { return base::nullopt; } + String GetDocumentReferrer() override { return g_empty_string; } + void DispatchViolationEvent(const SecurityPolicyViolationEventInit&, + Element*) override { + DCHECK(apply_policy_); + } + void PostViolationReport(const SecurityPolicyViolationEventInit&, + const String& stringified_report, + bool is_frame_ancestors_violation, + const Vector<String>& report_endpoints, + bool use_reporting_api) override { + DCHECK(apply_policy_); + } + + void Count(WebFeature feature) override { + // Log the features used by isolated world CSPs on the underlying Document. + UseCounter::Count(document_, feature); + } + + void AddConsoleMessage(ConsoleMessage* console_message) override { + // Add console messages on the underlying Document. + document_->AddConsoleMessage(console_message); + } + + void DisableEval(const String& error_message) override { + // TODO(crbug.com/896041): Implement this. + NOTIMPLEMENTED(); + } + + void ReportBlockedScriptExecutionToInspector( + const String& directive_text) override { + // TODO(crbug.com/896041): Figure out if this needs to be implemented. + NOTIMPLEMENTED(); + } + + void DidAddContentSecurityPolicies( + const blink::WebVector<WebContentSecurityPolicy>&) override {} + + private: + const Member<Document> document_; + const scoped_refptr<SecurityOrigin> security_origin_; + + // Whether the 'IsolatedWorldCSP' feature is enabled, and we are applying the + // CSP provided by the isolated world. + const bool apply_policy_; +}; + +} // namespace + // static IsolatedWorldCSP& IsolatedWorldCSP::Get() { DCHECK(IsMainThread()); @@ -18,15 +126,23 @@ IsolatedWorldCSP& IsolatedWorldCSP::Get() { return g_isolated_world_csp; } -void IsolatedWorldCSP::SetContentSecurityPolicy(int world_id, - const String& policy) { +void IsolatedWorldCSP::SetContentSecurityPolicy( + int world_id, + const String& policy, + scoped_refptr<SecurityOrigin> self_origin) { DCHECK(IsMainThread()); DCHECK(DOMWrapperWorld::IsIsolatedWorldId(world_id)); - if (policy.IsEmpty()) + if (!policy) { csp_map_.erase(world_id); - else - csp_map_.Set(world_id, true); + return; + } + + DCHECK(self_origin); + PolicyInfo policy_info; + policy_info.policy = policy; + policy_info.self_origin = std::move(self_origin); + csp_map_.Set(world_id, policy_info); } bool IsolatedWorldCSP::HasContentSecurityPolicy(int world_id) const { @@ -34,7 +150,38 @@ bool IsolatedWorldCSP::HasContentSecurityPolicy(int world_id) const { DCHECK(DOMWrapperWorld::IsIsolatedWorldId(world_id)); auto it = csp_map_.find(world_id); - return it != csp_map_.end() ? it->value : false; + return it != csp_map_.end(); +} + +ContentSecurityPolicy* IsolatedWorldCSP::CreateIsolatedWorldCSP( + Document& document, + int world_id) { + DCHECK(IsMainThread()); + DCHECK(DOMWrapperWorld::IsIsolatedWorldId(world_id)); + + auto it = csp_map_.find(world_id); + if (it == csp_map_.end()) + return nullptr; + + const String& policy = it->value.policy; + scoped_refptr<SecurityOrigin> self_origin = it->value.self_origin; + + const bool apply_policy = RuntimeEnabledFeatures::IsolatedWorldCSPEnabled(); + + ContentSecurityPolicy* csp = ContentSecurityPolicy::Create(); + + IsolatedWorldCSPDelegate* delegate = + MakeGarbageCollected<IsolatedWorldCSPDelegate>( + document, std::move(self_origin), apply_policy); + csp->BindToDelegate(*delegate); + + if (apply_policy) { + csp->AddPolicyFromHeaderValue(policy, + kContentSecurityPolicyHeaderTypeEnforce, + kContentSecurityPolicyHeaderSourceHTTP); + } + + return csp; } IsolatedWorldCSP::IsolatedWorldCSP() = default; |