Commit ff34791a authored by Nate Chapin's avatar Nate Chapin Committed by Commit Bot

Always provide documents a ContentSecurityPolicy

Currently, for some non-attached Documents, we skip providing CSP.
There doesn't seem to be any specific reason for this, or pattern for
when we do or don't provide it.

This has the added benefit of fixing a corner case where we can end
up inspecting a CSP that was not completely initialized.

Bug: 1067034
Test: http/tests/security/contentSecurityPolicy/csp-violation-in-detached-document.html
Change-Id: Ic8f30cc24469618b967f1c8325f7cf144b8cb876
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2209621
Commit-Queue: Nate Chapin <japhet@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#772317}
parent d3124385
...@@ -838,6 +838,12 @@ Document::Document(const DocumentInit& initializer, ...@@ -838,6 +838,12 @@ Document::Document(const DocumentInit& initializer,
PoliciesInitialized(initializer); PoliciesInitialized(initializer);
InitDNSPrefetch(); InitDNSPrefetch();
// Documents associated with a dom_window_ need to BindContentSecurityPolicy()
// later, because they depend on state that isn't fully initialized until this
// constructor exits.
if (!dom_window_ && GetExecutionContext())
BindContentSecurityPolicy();
InstanceCounters::IncrementCounter(InstanceCounters::kDocumentCounter); InstanceCounters::IncrementCounter(InstanceCounters::kDocumentCounter);
lifecycle_.AdvanceTo(DocumentLifecycle::kInactive); lifecycle_.AdvanceTo(DocumentLifecycle::kInactive);
......
...@@ -377,14 +377,8 @@ DocumentInit& DocumentInit::WithContentSecurityPolicy( ...@@ -377,14 +377,8 @@ DocumentInit& DocumentInit::WithContentSecurityPolicy(
return *this; return *this;
} }
DocumentInit& DocumentInit::WithContentSecurityPolicyFromExecutionContext() {
content_security_policy_from_context_ = true;
return *this;
}
ContentSecurityPolicy* DocumentInit::GetContentSecurityPolicy() const { ContentSecurityPolicy* DocumentInit::GetContentSecurityPolicy() const {
DCHECK(!(content_security_policy_ && content_security_policy_from_context_)); if (execution_context_) {
if (execution_context_ && content_security_policy_from_context_) {
// Return a copy of the context documents' CSP. The return value will be // Return a copy of the context documents' CSP. The return value will be
// modified, so this must be a copy. // modified, so this must be a copy.
ContentSecurityPolicy* csp = MakeGarbageCollected<ContentSecurityPolicy>(); ContentSecurityPolicy* csp = MakeGarbageCollected<ContentSecurityPolicy>();
......
...@@ -173,7 +173,6 @@ class CORE_EXPORT DocumentInit final { ...@@ -173,7 +173,6 @@ class CORE_EXPORT DocumentInit final {
DocumentInit& WithSandboxFlags(network::mojom::blink::WebSandboxFlags flags); DocumentInit& WithSandboxFlags(network::mojom::blink::WebSandboxFlags flags);
DocumentInit& WithContentSecurityPolicy(ContentSecurityPolicy* policy); DocumentInit& WithContentSecurityPolicy(ContentSecurityPolicy* policy);
DocumentInit& WithContentSecurityPolicyFromExecutionContext();
ContentSecurityPolicy* GetContentSecurityPolicy() const; ContentSecurityPolicy* GetContentSecurityPolicy() const;
DocumentInit& WithFramePolicy( DocumentInit& WithFramePolicy(
...@@ -265,7 +264,6 @@ class CORE_EXPORT DocumentInit final { ...@@ -265,7 +264,6 @@ class CORE_EXPORT DocumentInit final {
// Loader's CSP // Loader's CSP
ContentSecurityPolicy* content_security_policy_ = nullptr; ContentSecurityPolicy* content_security_policy_ = nullptr;
bool content_security_policy_from_context_ = false;
network::mojom::IPAddressSpace ip_address_space_ = network::mojom::IPAddressSpace ip_address_space_ =
network::mojom::IPAddressSpace::kUnknown; network::mojom::IPAddressSpace::kUnknown;
......
...@@ -191,8 +191,7 @@ Document* DOMImplementation::createHTMLDocument(const String& title) { ...@@ -191,8 +191,7 @@ Document* DOMImplementation::createHTMLDocument(const String& title) {
DocumentInit::Create() DocumentInit::Create()
.WithExecutionContext(window) .WithExecutionContext(window)
.WithOwnerDocument(window->document()) .WithOwnerDocument(window->document())
.WithRegistrationContext(document_->RegistrationContext()) .WithRegistrationContext(document_->RegistrationContext());
.WithContentSecurityPolicyFromExecutionContext();
auto* d = MakeGarbageCollected<HTMLDocument>(init); auto* d = MakeGarbageCollected<HTMLDocument>(init);
d->open(); d->open();
d->write("<!doctype html><html><head></head><body></body></html>"); d->write("<!doctype html><html><head></head><body></body></html>");
......
...@@ -29,13 +29,12 @@ ...@@ -29,13 +29,12 @@
namespace blink { namespace blink {
Document* DOMParser::parseFromString(const String& str, const String& type) { Document* DOMParser::parseFromString(const String& str, const String& type) {
Document* doc = DOMImplementation::createDocument( Document* doc =
DocumentInit::Create() DOMImplementation::createDocument(DocumentInit::Create()
.WithURL(GetDocument()->Url()) .WithURL(GetDocument()->Url())
.WithTypeFrom(type) .WithTypeFrom(type)
.WithExecutionContext(window_) .WithExecutionContext(window_)
.WithOwnerDocument(GetDocument()) .WithOwnerDocument(GetDocument()));
.WithContentSecurityPolicyFromExecutionContext());
doc->SetContent(str); doc->SetContent(str);
doc->SetMimeType(AtomicString(type)); doc->SetMimeType(AtomicString(type));
return doc; return doc;
......
...@@ -357,8 +357,7 @@ void XMLHttpRequest::InitResponseDocument() { ...@@ -357,8 +357,7 @@ void XMLHttpRequest::InitResponseDocument() {
DocumentInit init = DocumentInit::Create() DocumentInit init = DocumentInit::Create()
.WithExecutionContext(GetExecutionContext()) .WithExecutionContext(GetExecutionContext())
.WithOwnerDocument(GetDocument()) .WithOwnerDocument(GetDocument())
.WithURL(response_.ResponseUrl()) .WithURL(response_.ResponseUrl());
.WithContentSecurityPolicyFromExecutionContext();
if (is_html) if (is_html)
response_document_ = MakeGarbageCollected<HTMLDocument>(init); response_document_ = MakeGarbageCollected<HTMLDocument>(init);
else else
......
CONSOLE ERROR: Refused to send form data to 'about:blank' because it violates the following Content Security Policy directive: "form-action 'self'".
CONSOLE ERROR: Refused to send form data to 'about:blank' because it violates the following Content Security Policy directive: "form-action 'self'".
CONSOLE ERROR: Refused to send form data to 'about:blank' because it violates the following Content Security Policy directive: "form-action 'self'".
PASS if no crash
<html>
<head>
<meta content="form-action 'self';" http-equiv=Content-Security-Policy>
</head>
<body>
<iframe id="i" name="i"></iframe>
<form action="about:blank" target="i"></form>
<script>
if (window.testRunner)
testRunner.dumpAsText();
document.forms[0].submit();
document.body.appendChild(document.head);
new Document().prepend(document.body);
document.documentElement.appendChild(document.createTextNode("PASS if no crash"));
</script></html>
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