summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc
diff options
context:
space:
mode:
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.cc159
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;