diff options
author | Michal Klocek <michal.klocek@qt.io> | 2018-08-10 18:38:30 +0200 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2018-08-14 14:53:12 +0000 |
commit | 2b111a00fe9f063f7ecc3b34a9e2a4ef7b1a1112 (patch) | |
tree | a9b5a5e624ecc9da9b640d9d3cfa21456553e63e | |
parent | eb5360b24e4574fb768ef5c685e7e043bcdfff41 (diff) |
[Backport] CVE-2018-6164
M68: Disallow access to opaque CSS responses.
Bug: 848786
Reviewed-on: https://chromium-review.googlesource.com/1088335
Change-Id: Ic2bf8cfc9f21322cc7383b1dc2893222a79c80f3
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
8 files changed, 70 insertions, 16 deletions
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp b/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp index 65a9b71a120..43e38c9ed62 100644 --- a/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp +++ b/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp @@ -110,6 +110,7 @@ CSSStyleSheet* CSSStyleSheet::CreateInline(Node& owner_node, const WTF::TextEncoding& encoding) { CSSParserContext* parser_context = CSSParserContext::Create( owner_node.GetDocument(), owner_node.GetDocument().BaseURL(), + false /* is_opaque_response_from_service_worker */, owner_node.GetDocument().GetReferrerPolicy(), encoding); StyleSheetContents* sheet = StyleSheetContents::Create(base_url.GetString(), parser_context); @@ -248,6 +249,10 @@ void CSSStyleSheet::ClearOwnerNode() { } bool CSSStyleSheet::CanAccessRules() const { + // Opaque responses should never be accessible, mod DevTools. See comments for + // IsOpaqueResponseFromServiceWorker(). + if (contents_->IsOpaqueResponseFromServiceWorker()) + return false; if (is_inline_stylesheet_) return true; KURL base_url = contents_->BaseURL(); diff --git a/chromium/third_party/WebKit/Source/core/css/SelectorQuery.cpp b/chromium/third_party/WebKit/Source/core/css/SelectorQuery.cpp index 62cee6eff37..2c28f5ab15f 100644 --- a/chromium/third_party/WebKit/Source/core/css/SelectorQuery.cpp +++ b/chromium/third_party/WebKit/Source/core/css/SelectorQuery.cpp @@ -545,7 +545,9 @@ SelectorQuery* SelectorQueryCache::Add(const AtomicString& selectors, CSSSelectorList selector_list = CSSParser::ParseSelector( CSSParserContext::Create( - document, document.BaseURL(), document.GetReferrerPolicy(), + document, document.BaseURL(), + false /* is_opaque_response_from_service_worker */, + document.GetReferrerPolicy(), WTF::TextEncoding(), CSSParserContext::kStaticProfile), nullptr, selectors); diff --git a/chromium/third_party/WebKit/Source/core/css/StyleRuleImport.cpp b/chromium/third_party/WebKit/Source/core/css/StyleRuleImport.cpp index 40cf99a85bd..36d1140c3d8 100644 --- a/chromium/third_party/WebKit/Source/core/css/StyleRuleImport.cpp +++ b/chromium/third_party/WebKit/Source/core/css/StyleRuleImport.cpp @@ -80,6 +80,7 @@ void StyleRuleImport::NotifyFinished(Resource* resource) { } context = CSSParserContext::Create(context, cached_style_sheet->GetResponse().Url(), + cached_style_sheet->GetResponse().IsOpaqueResponseFromServiceWorker(), cached_style_sheet->GetReferrerPolicy(), cached_style_sheet->Encoding(), document); diff --git a/chromium/third_party/WebKit/Source/core/css/StyleSheetContents.h b/chromium/third_party/WebKit/Source/core/css/StyleSheetContents.h index 22710d269f7..5f30a292125 100644 --- a/chromium/third_party/WebKit/Source/core/css/StyleSheetContents.h +++ b/chromium/third_party/WebKit/Source/core/css/StyleSheetContents.h @@ -135,12 +135,34 @@ class CORE_EXPORT StyleSheetContents StyleRuleImport* OwnerRule() const { return owner_rule_; } void ClearOwnerRule() { owner_rule_ = nullptr; } - // Note that href is the URL that started the redirect chain that led to - // this style sheet. This property probably isn't useful for much except - // the JavaScript binding (which needs to use this value for security). + // The URL that started the redirect chain that led to this + // style sheet. This property probably isn't useful for much except the + // JavaScript binding (which needs to use this value for security). String OriginalURL() const { return original_url_; } + // The final request URL after redirects. WARNING: Be careful when + // using this for security checks. It can be different from the actual + // response URL if a service worker is involved. See + // IsOpaqueResponseFromServiceWorker(). const KURL& BaseURL() const { return parser_context_->BaseURL(); } + // True if a service worker intercepted the request for this style sheet and + // returned an opaque response. This context should NOT have access to the + // contents, regardless of BaseURL(). + // + // For example: + // 1. Page at a.com requests a.com/style.css. + // 2. Service worker responds with b.com/style.css (without CORS). + // 3. The BaseURL() is "a.com/style.css" but this context is should not have + // access to contents. + // + // You might ask why we don't change BaseURL() to be the actual response URL. + // In fact, the spec says we should! See crbug.com/553535. But we would still + // need this "is opaque" bit, since in step 2 above the service worker might + // have used CORS to get a non-opaque response from b.com. + bool IsOpaqueResponseFromServiceWorker() const { + return parser_context_->IsOpaqueResponseFromServiceWorker(); + } + unsigned RuleCount() const; StyleRuleBase* RuleAt(unsigned index) const; diff --git a/chromium/third_party/WebKit/Source/core/css/parser/CSSParserContext.cpp b/chromium/third_party/WebKit/Source/core/css/parser/CSSParserContext.cpp index 64131965fe3..85b628cdc5e 100644 --- a/chromium/third_party/WebKit/Source/core/css/parser/CSSParserContext.cpp +++ b/chromium/third_party/WebKit/Source/core/css/parser/CSSParserContext.cpp @@ -27,7 +27,8 @@ CSSParserContext* CSSParserContext::Create(const ExecutionContext& context) { policy_disposition = kCheckContentSecurityPolicy; return new CSSParserContext( - context.Url(), WTF::TextEncoding(), kHTMLStandardMode, kHTMLStandardMode, + context.Url(), false /* is_opaque_response_from_service_worker */, + WTF::TextEncoding(), kHTMLStandardMode, kHTMLStandardMode, kDynamicProfile, referrer, true, false, context.GetSecureContextMode(), policy_disposition, context.IsDocument() ? &ToDocument(context) : nullptr); @@ -54,7 +55,8 @@ CSSParserContext* CSSParserContext::Create( const CSSParserContext* other, const Document* use_counter_document) { return new CSSParserContext( - other->base_url_, other->charset_, other->mode_, other->match_mode_, + other->base_url_, other->is_opaque_response_from_service_worker_, + other->charset_, other->mode_, other->match_mode_, other->profile_, other->referrer_, other->is_html_document_, other->use_legacy_background_size_shorthand_behavior_, other->secure_context_mode_, other->should_check_content_security_policy_, @@ -65,11 +67,13 @@ CSSParserContext* CSSParserContext::Create( CSSParserContext* CSSParserContext::Create( const CSSParserContext* other, const KURL& base_url, + bool is_opaque_response_from_service_worker, ReferrerPolicy referrer_policy, const WTF::TextEncoding& charset, const Document* use_counter_document) { return new CSSParserContext( - base_url, charset, other->mode_, other->match_mode_, other->profile_, + base_url, is_opaque_response_from_service_worker, charset, other->mode_, + other->match_mode_, other->profile_, Referrer(base_url.StrippedForUseAsReferrer(), referrer_policy), other->is_html_document_, other->use_legacy_background_size_shorthand_behavior_, @@ -83,23 +87,26 @@ CSSParserContext* CSSParserContext::Create( SecureContextMode secure_context_mode, SelectorProfile profile, const Document* use_counter_document) { - return new CSSParserContext(KURL(), WTF::TextEncoding(), mode, mode, profile, - Referrer(), false, false, secure_context_mode, - kDoNotCheckContentSecurityPolicy, - use_counter_document); + return new CSSParserContext( + KURL(), false /* is_opaque_response_from_service_worker */, + WTF::TextEncoding(), mode, mode, profile, Referrer(), false, false, + secure_context_mode, kDoNotCheckContentSecurityPolicy, + use_counter_document); } // static CSSParserContext* CSSParserContext::Create(const Document& document) { - return CSSParserContext::Create(document, document.BaseURL(), - document.GetReferrerPolicy(), - WTF::TextEncoding(), kDynamicProfile); + return CSSParserContext::Create( + document, document.BaseURL(), + false /* is_opaque_response_from_service_worker */, + document.GetReferrerPolicy(), WTF::TextEncoding(), kDynamicProfile); } // static CSSParserContext* CSSParserContext::Create( const Document& document, const KURL& base_url_override, + bool is_opaque_response_from_service_worker, ReferrerPolicy referrer_policy_override, const WTF::TextEncoding& charset, SelectorProfile profile) { @@ -131,13 +138,15 @@ CSSParserContext* CSSParserContext::Create( policy_disposition = kCheckContentSecurityPolicy; return new CSSParserContext( - base_url_override, charset, mode, match_mode, profile, referrer, - document.IsHTMLDocument(), use_legacy_background_size_shorthand_behavior, + base_url_override, is_opaque_response_from_service_worker, charset, mode, + match_mode, profile, referrer, document.IsHTMLDocument(), + use_legacy_background_size_shorthand_behavior, document.GetSecureContextMode(), policy_disposition, &document); } CSSParserContext::CSSParserContext( const KURL& base_url, + bool is_opaque_response_from_service_worker, const WTF::TextEncoding& charset, CSSParserMode mode, CSSParserMode match_mode, @@ -149,6 +158,8 @@ CSSParserContext::CSSParserContext( ContentSecurityPolicyDisposition policy_disposition, const Document* use_counter_document) : base_url_(base_url), + is_opaque_response_from_service_worker_( + is_opaque_response_from_service_worker), charset_(charset), mode_(mode), match_mode_(match_mode), @@ -190,6 +201,10 @@ const CSSParserContext* StrictCSSParserContext( return context; } +bool CSSParserContext::IsOpaqueResponseFromServiceWorker() const { + return is_opaque_response_from_service_worker_; +} + bool CSSParserContext::IsSecureContext() const { return secure_context_mode_ == SecureContextMode::kSecureContext; } diff --git a/chromium/third_party/WebKit/Source/core/css/parser/CSSParserContext.h b/chromium/third_party/WebKit/Source/core/css/parser/CSSParserContext.h index ea2d8dacad7..70661580cd3 100644 --- a/chromium/third_party/WebKit/Source/core/css/parser/CSSParserContext.h +++ b/chromium/third_party/WebKit/Source/core/css/parser/CSSParserContext.h @@ -43,6 +43,7 @@ class CORE_EXPORT CSSParserContext static CSSParserContext* Create(const CSSParserContext* other, const KURL& base_url_override, + bool is_opaque_response_from_service_worker, ReferrerPolicy referrer_policy_override, const WTF::TextEncoding& charset_override, const Document* use_counter_document); @@ -56,6 +57,7 @@ class CORE_EXPORT CSSParserContext static CSSParserContext* Create( const Document&, const KURL& base_url_override, + bool is_opaque_response_from_service_worker, ReferrerPolicy referrer_policy_override, const WTF::TextEncoding& charset = WTF::TextEncoding(), SelectorProfile = kDynamicProfile); @@ -76,6 +78,9 @@ class CORE_EXPORT CSSParserContext bool IsDynamicProfile() const { return profile_ == kDynamicProfile; } bool IsStaticProfile() const { return profile_ == kStaticProfile; } + // See documentation in StyleSheetContents for this function. + bool IsOpaqueResponseFromServiceWorker() const; + bool IsSecureContext() const; // This quirk is to maintain compatibility with Android apps built on @@ -110,6 +115,7 @@ class CORE_EXPORT CSSParserContext private: CSSParserContext(const KURL& base_url, + bool is_opaque_response_from_service_worker, const WTF::TextEncoding& charset, CSSParserMode, CSSParserMode match_mode, @@ -122,6 +128,7 @@ class CORE_EXPORT CSSParserContext const Document* use_counter_document); KURL base_url_; + const bool is_opaque_response_from_service_worker_; WTF::TextEncoding charset_; CSSParserMode mode_; CSSParserMode match_mode_; diff --git a/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp b/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp index ee3b8ae55a5..da836527770 100644 --- a/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp +++ b/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp @@ -213,6 +213,7 @@ void ProcessingInstruction::NotifyFinished(Resource* resource) { CSSStyleSheetResource* style_resource = ToCSSStyleSheetResource(resource); CSSParserContext* parser_context = CSSParserContext::Create( GetDocument(), style_resource->GetResponse().Url(), + style_resource->GetResponse().IsOpaqueResponseFromServiceWorker(), style_resource->GetReferrerPolicy(), style_resource->Encoding()); StyleSheetContents* new_sheet = diff --git a/chromium/third_party/WebKit/Source/core/html/LinkStyle.cpp b/chromium/third_party/WebKit/Source/core/html/LinkStyle.cpp index 052b24ea218..65dfcefd891 100644 --- a/chromium/third_party/WebKit/Source/core/html/LinkStyle.cpp +++ b/chromium/third_party/WebKit/Source/core/html/LinkStyle.cpp @@ -93,6 +93,7 @@ void LinkStyle::NotifyFinished(Resource* resource) { CSSParserContext* parser_context = CSSParserContext::Create( GetDocument(), cached_style_sheet->GetResponse().Url(), + cached_style_sheet->GetResponse().IsOpaqueResponseFromServiceWorker(), cached_style_sheet->GetReferrerPolicy(), cached_style_sheet->Encoding()); if (StyleSheetContents* parsed_sheet = |