diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-09-06 14:06:53 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-09-14 15:24:27 +0000 |
commit | af4500d25e07e0931edcf0f497f9b0c7791a3318 (patch) | |
tree | 5152d3df5e6946e06b85c803491fb049f46b8bdb | |
parent | 9ffeaf4caa98ede92afe9de3750a82acc70c42ac (diff) |
[Backport] CVE-2018-16077
Prevent sandboxed documents from reusing the default window
Bug: 377995
Change-Id: I5350c62072b46544331e40361b9d606d9e533ce3
Reviewed-on: https://chromium-review.googlesource.com/983558
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
8 files changed, 49 insertions, 11 deletions
diff --git a/chromium/third_party/WebKit/Source/core/dom/Document.cpp b/chromium/third_party/WebKit/Source/core/dom/Document.cpp index 7a4260bd3cf..7314261eb5c 100644 --- a/chromium/third_party/WebKit/Source/core/dom/Document.cpp +++ b/chromium/third_party/WebKit/Source/core/dom/Document.cpp @@ -3533,7 +3533,10 @@ void Document::DispatchUnloadEvents() { bool keep_event_listeners = frame_->Loader().GetProvisionalDocumentLoader() && frame_->ShouldReuseDefaultView( - frame_->Loader().GetProvisionalDocumentLoader()->Url()); + frame_->Loader().GetProvisionalDocumentLoader()->Url(), + frame_->Loader() + .GetProvisionalDocumentLoader() + ->GetContentSecurityPolicy()); if (!keep_event_listeners) RemoveAllEventListenersRecursively(); } diff --git a/chromium/third_party/WebKit/Source/core/dom/SecurityContext.h b/chromium/third_party/WebKit/Source/core/dom/SecurityContext.h index 6bdafe29b73..f48a33ac5c6 100644 --- a/chromium/third_party/WebKit/Source/core/dom/SecurityContext.h +++ b/chromium/third_party/WebKit/Source/core/dom/SecurityContext.h @@ -72,7 +72,12 @@ class CORE_EXPORT SecurityContext : public GarbageCollectedMixin { virtual void DidUpdateSecurityOrigin() = 0; SandboxFlags GetSandboxFlags() const { return sandbox_flags_; } - bool IsSandboxed(SandboxFlags mask) const { return sandbox_flags_ & mask; } + bool IsSandboxed(SandboxFlags mask) const { + return IsSandboxed(mask, sandbox_flags_); + } + static bool IsSandboxed(SandboxFlags mask, SandboxFlags sandbox_flags) { + return sandbox_flags & mask; + } virtual void EnforceSandboxFlags(SandboxFlags mask); void SetAddressSpace(mojom::IPAddressSpace space) { address_space_ = space; } diff --git a/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp index 198244acb3e..5c0824f0e11 100644 --- a/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp +++ b/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp @@ -746,12 +746,24 @@ EphemeralRange LocalFrame::RangeForPoint(const IntPoint& frame_point) { return EphemeralRange(); } -bool LocalFrame::ShouldReuseDefaultView(const KURL& url) const { +bool LocalFrame::ShouldReuseDefaultView( + const KURL& url, + const ContentSecurityPolicy* csp) const { // Secure transitions can only happen when navigating from the initial empty // document. if (!Loader().StateMachine()->IsDisplayingInitialEmptyDocument()) return false; + // The Window object should only be re-used if it is same-origin. + // Since sandboxing turns the origin into an opaque origin it needs to also + // be considered when deciding whether to reuse it. + // Spec: + // https://html.spec.whatwg.org/multipage/browsing-the-web.html#initialise-the-document-object + if (csp && + SecurityContext::IsSandboxed(kSandboxOrigin, csp->GetSandboxMask())) { + return false; + } + return GetDocument()->IsSecureTransitionTo(url); } diff --git a/chromium/third_party/WebKit/Source/core/frame/LocalFrame.h b/chromium/third_party/WebKit/Source/core/frame/LocalFrame.h index d36b81dff58..72018c71f8a 100644 --- a/chromium/third_party/WebKit/Source/core/frame/LocalFrame.h +++ b/chromium/third_party/WebKit/Source/core/frame/LocalFrame.h @@ -214,7 +214,7 @@ class CORE_EXPORT LocalFrame final : public Frame, EphemeralRangeTemplate<EditingAlgorithm<NodeTraversal>> RangeForPoint( const IntPoint& frame_point); - bool ShouldReuseDefaultView(const KURL&) const; + bool ShouldReuseDefaultView(const KURL&, const ContentSecurityPolicy*) const; void RemoveSpellingMarkersUnderWords(const Vector<String>& words); bool ShouldThrottleRendering() const; diff --git a/chromium/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h b/chromium/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h index c562bdfbc79..4da2f742a1e 100644 --- a/chromium/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h +++ b/chromium/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h @@ -446,6 +446,12 @@ class CORE_EXPORT ContentSecurityPolicy // Returns the 'wasm-eval' source is supported. bool SupportsWasmEval() const { return supports_wasm_eval_; } + // Retrieves the parsed sandbox flags. A lot of the time the execution + // context will be used for all sandbox checks but there are situations + // (before installing the document that this CSP will bind to) when + // there is no execution context to enforce the sandbox flags. + SandboxFlags GetSandboxMask() const { return sandbox_mask_; } + private: FRIEND_TEST_ALL_PREFIXES(ContentSecurityPolicyTest, NonceInline); FRIEND_TEST_ALL_PREFIXES(ContentSecurityPolicyTest, NonceSinglePolicy); diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.cpp index 101aae156f7..2657e10838f 100644 --- a/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.cpp @@ -691,12 +691,13 @@ void DocumentLoader::CommitNavigation(const AtomicString& mime_type, if (!Document::ThreadedParsingEnabledForTesting()) parsing_policy = kForceSynchronousParsing; - InstallNewDocument(Url(), owner_document, - frame_->ShouldReuseDefaultView(Url()) - ? WebGlobalObjectReusePolicy::kUseExisting - : WebGlobalObjectReusePolicy::kCreateNew, - mime_type, encoding, InstallNewDocumentReason::kNavigation, - parsing_policy, overriding_url); + InstallNewDocument( + Url(), owner_document, + frame_->ShouldReuseDefaultView(Url(), GetContentSecurityPolicy()) + ? WebGlobalObjectReusePolicy::kUseExisting + : WebGlobalObjectReusePolicy::kCreateNew, + mime_type, encoding, InstallNewDocumentReason::kNavigation, + parsing_policy, overriding_url); parser_->SetDocumentWasLoadedAsPartOfNavigation(); frame_->GetDocument()->MaybeHandleHttpRefresh( response_.HttpHeaderField(HTTPNames::Refresh), diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.h b/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.h index e35807ba65a..a89f9579c57 100644 --- a/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.h +++ b/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.h @@ -240,6 +240,13 @@ class CORE_EXPORT DocumentLoader return devtools_navigation_token_; } + // Returns the currently stored content security policy, if this is called + // after the document has been installed it will return nullptr as the + // CSP belongs to the document at that point. + const ContentSecurityPolicy* GetContentSecurityPolicy() const { + return content_security_policy_.Get(); + } + protected: DocumentLoader(LocalFrame*, const ResourceRequest&, diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp index a30abc938b2..f0b1f6e9d63 100644 --- a/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp @@ -432,8 +432,12 @@ void FrameLoader::ReplaceDocumentWhileExecutingJavaScriptURL( // Compute this before clearing the frame, because it may need to inherit an // aliased security context. + // The document CSP is the correct one as it is used for CSP checks + // done previously before getting here: + // HTMLFormElement::ScheduleFormSubmission + // HTMLFrameElementBase::OpenURL WebGlobalObjectReusePolicy global_object_reuse_policy = - frame_->ShouldReuseDefaultView(url) + frame_->ShouldReuseDefaultView(url, document->GetContentSecurityPolicy()) ? WebGlobalObjectReusePolicy::kUseExisting : WebGlobalObjectReusePolicy::kCreateNew; |