加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
CVE-2020-26958.patch 29.64 KB
一键复制 编辑 原始数据 按行查看 历史
wangxiao65 提交于 2021-01-07 15:15 . fix cves
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
# HG changeset patch
# User Andrew Sutherland <asutherland@asutherland.org>
# Date 1603887323 0
# Wed Oct 28 12:15:23 2020 +0000
# Node ID 6873589e0ede3c11bc48243be67c3d51e214873f
# Parent e6a1286e25b70d36a1e251fb056596181565d839
Bug 1669355 - Refactor MIME type warnings into base class. r=necko-reviewers,valentin
Differential Revision: https://phabricator.services.mozilla.com/D93906
diff -r e6a1286e25b7 -r 6873589e0ede netwerk/protocol/http/HttpBaseChannel.cpp
--- a/netwerk/protocol/http/HttpBaseChannel.cpp 2020-07-21 06:49:41.000000000 +0800
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp 2021-01-06 11:26:44.608483314 +0800
@@ -24,10 +24,12 @@
#include "mozilla/NullPrincipal.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPrefs_browser.h"
+#include "mozilla/StaticPrefs_security.h"
#include "mozilla/Telemetry.h"
#include "mozilla/Tokenizer.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
+#include "mozilla/dom/Document.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/PerformanceStorage.h"
#include "mozilla/dom/WindowGlobalParent.h"
@@ -2385,6 +2387,354 @@ nsresult HttpBaseChannel::ComputeCrossOr
return NS_OK;
}
+enum class Report { Error, Warning };
+
+// Helper Function to report messages to the console when the loaded
+// script had a wrong MIME type.
+void ReportMimeTypeMismatch(HttpBaseChannel* aChannel, const char* aMessageName,
+ nsIURI* aURI, const nsACString& aContentType,
+ Report report) {
+ NS_ConvertUTF8toUTF16 spec(aURI->GetSpecOrDefault());
+ NS_ConvertUTF8toUTF16 contentType(aContentType);
+
+ aChannel->LogMimeTypeMismatch(nsCString(aMessageName),
+ report == Report::Warning, spec, contentType);
+}
+
+// Check and potentially enforce X-Content-Type-Options: nosniff
+nsresult ProcessXCTO(HttpBaseChannel* aChannel, nsIURI* aURI,
+ nsHttpResponseHead* aResponseHead,
+ nsILoadInfo* aLoadInfo) {
+ if (!aURI || !aResponseHead || !aLoadInfo) {
+ // if there is no uri, no response head or no loadInfo, then there is
+ // nothing to do
+ return NS_OK;
+ }
+
+ // 1) Query the XCTO header and check if 'nosniff' is the first value.
+ nsAutoCString contentTypeOptionsHeader;
+ if (!aResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader)) {
+ // if failed to get XCTO header, then there is nothing to do.
+ return NS_OK;
+ }
+
+ // let's compare the header (ignoring case)
+ // e.g. "NoSniFF" -> "nosniff"
+ // if it's not 'nosniff' then there is nothing to do here
+ if (!contentTypeOptionsHeader.EqualsIgnoreCase("nosniff")) {
+ // since we are getting here, the XCTO header was sent;
+ // a non matching value most likely means a mistake happenend;
+ // e.g. sending 'nosnif' instead of 'nosniff', let's log a warning.
+ AutoTArray<nsString, 1> params;
+ CopyUTF8toUTF16(contentTypeOptionsHeader, *params.AppendElement());
+ RefPtr<dom::Document> doc;
+ aLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
+ nsContentUtils::ReportToConsole(
+ nsIScriptError::warningFlag, NS_LITERAL_CSTRING("XCTO"), doc,
+ nsContentUtils::eSECURITY_PROPERTIES, "XCTOHeaderValueMissing", params);
+ return NS_OK;
+ }
+
+ // 2) Query the content type from the channel
+ nsAutoCString contentType;
+ aResponseHead->ContentType(contentType);
+
+ // 3) Compare the expected MIME type with the actual type
+ if (aLoadInfo->GetExternalContentPolicyType() ==
+ nsIContentPolicy::TYPE_STYLESHEET) {
+ if (contentType.EqualsLiteral(TEXT_CSS)) {
+ return NS_OK;
+ }
+ ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
+ Report::Error);
+ return NS_ERROR_CORRUPTED_CONTENT;
+ }
+
+ if (aLoadInfo->GetExternalContentPolicyType() ==
+ nsIContentPolicy::TYPE_SCRIPT) {
+ if (nsContentUtils::IsJavascriptMIMEType(
+ NS_ConvertUTF8toUTF16(contentType))) {
+ return NS_OK;
+ }
+ ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
+ Report::Error);
+ return NS_ERROR_CORRUPTED_CONTENT;
+ }
+
+ auto policyType = aLoadInfo->GetExternalContentPolicyType();
+ if ((policyType == nsIContentPolicy::TYPE_DOCUMENT ||
+ policyType == nsIContentPolicy::TYPE_SUBDOCUMENT) &&
+ gHttpHandler->IsDocumentNosniffEnabled()) {
+ // If the header XCTO nosniff is set for any browsing context, then
+ // we set the skipContentSniffing flag on the Loadinfo. Within
+ // GetMIMETypeFromContent we then bail early and do not do any sniffing.
+ aLoadInfo->SetSkipContentSniffing(true);
+ return NS_OK;
+ }
+
+ return NS_OK;
+}
+
+// Ensure that a load of type script has correct MIME type
+nsresult EnsureMIMEOfScript(HttpBaseChannel* aChannel, nsIURI* aURI,
+ nsHttpResponseHead* aResponseHead,
+ nsILoadInfo* aLoadInfo) {
+ if (!aURI || !aResponseHead || !aLoadInfo) {
+ // if there is no uri, no response head or no loadInfo, then there is
+ // nothing to do
+ return NS_OK;
+ }
+
+ if (aLoadInfo->GetExternalContentPolicyType() !=
+ nsIContentPolicy::TYPE_SCRIPT) {
+ // if this is not a script load, then there is nothing to do
+ return NS_OK;
+ }
+
+ nsAutoCString contentType;
+ aResponseHead->ContentType(contentType);
+ NS_ConvertUTF8toUTF16 typeString(contentType);
+
+ if (nsContentUtils::IsJavascriptMIMEType(typeString)) {
+ // script load has type script
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::javaScript);
+ return NS_OK;
+ }
+
+ switch (aLoadInfo->InternalContentPolicyType()) {
+ case nsIContentPolicy::TYPE_SCRIPT:
+ case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
+ case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
+ case nsIContentPolicy::TYPE_INTERNAL_MODULE:
+ case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::script_load);
+ break;
+ case nsIContentPolicy::TYPE_INTERNAL_WORKER:
+ case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worker_load);
+ break;
+ case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::serviceworker_load);
+ break;
+ case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::importScript_load);
+ break;
+ case nsIContentPolicy::TYPE_INTERNAL_AUDIOWORKLET:
+ case nsIContentPolicy::TYPE_INTERNAL_PAINTWORKLET:
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worklet_load);
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("unexpected script type");
+ break;
+ }
+
+ bool isPrivateWin = aLoadInfo->GetOriginAttributes().mPrivateBrowsingId > 0;
+ bool isSameOrigin = false;
+ aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(aURI, isPrivateWin,
+ &isSameOrigin);
+ if (isSameOrigin) {
+ // same origin
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::same_origin);
+ } else {
+ bool cors = false;
+ nsAutoCString corsOrigin;
+ nsresult rv = aResponseHead->GetHeader(
+ nsHttp::ResolveAtom("Access-Control-Allow-Origin"), corsOrigin);
+ if (NS_SUCCEEDED(rv)) {
+ if (corsOrigin.Equals("*")) {
+ cors = true;
+ } else {
+ nsCOMPtr<nsIURI> corsOriginURI;
+ rv = NS_NewURI(getter_AddRefs(corsOriginURI), corsOrigin);
+ if (NS_SUCCEEDED(rv)) {
+ bool isPrivateWin =
+ aLoadInfo->GetOriginAttributes().mPrivateBrowsingId > 0;
+ bool isSameOrigin = false;
+ aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(
+ corsOriginURI, isPrivateWin, &isSameOrigin);
+ if (isSameOrigin) {
+ cors = true;
+ }
+ }
+ }
+ }
+ if (cors) {
+ // cors origin
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::CORS_origin);
+ } else {
+ // cross origin
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::cross_origin);
+ }
+ }
+
+ bool block = false;
+ if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("image/"))) {
+ // script load has type image
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::image);
+ block = true;
+ } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("audio/"))) {
+ // script load has type audio
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::audio);
+ block = true;
+ } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("video/"))) {
+ // script load has type video
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::video);
+ block = true;
+ } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/csv"))) {
+ // script load has type text/csv
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_csv);
+ block = true;
+ }
+
+ if (block) {
+ // Do not block the load if the feature is not enabled.
+ if (!StaticPrefs::security_block_script_with_wrong_mime()) {
+ return NS_OK;
+ }
+
+ ReportMimeTypeMismatch(aChannel, "BlockScriptWithWrongMimeType2", aURI,
+ contentType, Report::Error);
+ return NS_ERROR_CORRUPTED_CONTENT;
+ }
+
+ if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/plain"))) {
+ // script load has type text/plain
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_plain);
+ } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/xml"))) {
+ // script load has type text/xml
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_xml);
+ } else if (StringBeginsWith(contentType,
+ NS_LITERAL_CSTRING("application/octet-stream"))) {
+ // script load has type application/octet-stream
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_octet_stream);
+ } else if (StringBeginsWith(contentType,
+ NS_LITERAL_CSTRING("application/xml"))) {
+ // script load has type application/xml
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_xml);
+ } else if (StringBeginsWith(contentType,
+ NS_LITERAL_CSTRING("application/json"))) {
+ // script load has type application/json
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_json);
+ } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/json"))) {
+ // script load has type text/json
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_json);
+ } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/html"))) {
+ // script load has type text/html
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_html);
+ } else if (contentType.IsEmpty()) {
+ // script load has no type
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::empty);
+ } else {
+ // script load has unknown type
+ AccumulateCategorical(
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::unknown);
+ }
+
+ // We restrict importScripts() in worker code to JavaScript MIME types.
+ nsContentPolicyType internalType = aLoadInfo->InternalContentPolicyType();
+ if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS) {
+ // Do not block the load if the feature is not enabled.
+ if (!StaticPrefs::security_block_importScripts_with_wrong_mime()) {
+ return NS_OK;
+ }
+
+ ReportMimeTypeMismatch(aChannel, "BlockImportScriptsWithWrongMimeType",
+ aURI, contentType, Report::Error);
+ return NS_ERROR_CORRUPTED_CONTENT;
+ }
+
+ if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
+ internalType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER) {
+ // Do not block the load if the feature is not enabled.
+ if (!StaticPrefs::security_block_Worker_with_wrong_mime()) {
+ return NS_OK;
+ }
+
+ ReportMimeTypeMismatch(aChannel, "BlockWorkerWithWrongMimeType", aURI,
+ contentType, Report::Error);
+ return NS_ERROR_CORRUPTED_CONTENT;
+ }
+
+ // ES6 modules require a strict MIME type check.
+ if (internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE ||
+ internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD) {
+ ReportMimeTypeMismatch(aChannel, "BlockModuleWithWrongMimeType", aURI,
+ contentType, Report::Error);
+ return NS_ERROR_CORRUPTED_CONTENT;
+ }
+
+ return NS_OK;
+}
+
+// Warn when a load of type script uses a wrong MIME type and
+// wasn't blocked by EnsureMIMEOfScript or ProcessXCTO.
+void WarnWrongMIMEOfScript(HttpBaseChannel* aChannel, nsIURI* aURI,
+ nsHttpResponseHead* aResponseHead,
+ nsILoadInfo* aLoadInfo) {
+ if (!aURI || !aResponseHead || !aLoadInfo) {
+ // If there is no uri, no response head or no loadInfo, then there is
+ // nothing to do.
+ return;
+ }
+
+ if (aLoadInfo->GetExternalContentPolicyType() !=
+ nsIContentPolicy::TYPE_SCRIPT) {
+ // If this is not a script load, then there is nothing to do.
+ return;
+ }
+
+ bool succeeded;
+ MOZ_ALWAYS_SUCCEEDS(aChannel->GetRequestSucceeded(&succeeded));
+ if (!succeeded) {
+ // Do not warn for failed loads: HTTP error pages are usually in HTML.
+ return;
+ }
+
+ nsAutoCString contentType;
+ aResponseHead->ContentType(contentType);
+ NS_ConvertUTF8toUTF16 typeString(contentType);
+ if (!nsContentUtils::IsJavascriptMIMEType(typeString)) {
+ ReportMimeTypeMismatch(aChannel, "WarnScriptWithWrongMimeType", aURI,
+ contentType, Report::Warning);
+ }
+}
+
+nsresult HttpBaseChannel::ValidateMIMEType() {
+ nsresult rv = EnsureMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ rv = ProcessXCTO(this, mURI, mResponseHead.get(), mLoadInfo);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ WarnWrongMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
+ return NS_OK;
+}
+
NS_IMETHODIMP
HttpBaseChannel::SetCookie(const nsACString& aCookieHeader) {
if (mLoadFlags & LOAD_ANONYMOUS) return NS_OK;
diff -r e6a1286e25b7 -r 6873589e0ede netwerk/protocol/http/HttpBaseChannel.h
--- a/netwerk/protocol/http/HttpBaseChannel.h 2020-07-21 04:53:32.000000000 +0800
+++ b/netwerk/protocol/http/HttpBaseChannel.h 2021-01-06 10:53:17.326264473 +0800
@@ -610,6 +610,8 @@ class HttpBaseChannel : public nsHashPro
nsresult ComputeCrossOriginOpenerPolicyMismatch();
+ nsresult ValidateMIMEType();
+
friend class PrivateBrowsingChannel<HttpBaseChannel>;
friend class InterceptFailedOnStop;
diff -r e6a1286e25b7 -r 6873589e0ede netwerk/protocol/http/InterceptedHttpChannel.cpp
--- a/netwerk/protocol/http/InterceptedHttpChannel.cpp 2020-07-21 06:49:41.000000000 +0800
+++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp 2021-01-06 10:53:17.326264473 +0800
@@ -1046,6 +1046,12 @@ InterceptedHttpChannel::OnStartRequest(n
Cancel(mStatus);
}
+ rv = ValidateMIMEType();
+ if (NS_FAILED(rv)) {
+ mStatus = rv;
+ Cancel(mStatus);
+ }
+
mOnStartRequestCalled = true;
if (mListener) {
return mListener->OnStartRequest(this);
diff -r e6a1286e25b7 -r 6873589e0ede netwerk/protocol/http/nsHttpChannel.cpp
--- a/netwerk/protocol/http/nsHttpChannel.cpp 2021-01-06 10:53:17.330264533 +0800
+++ b/netwerk/protocol/http/nsHttpChannel.cpp 2021-01-06 11:10:19.257650688 +0800
@@ -1485,339 +1485,6 @@ HttpTrafficCategory nsHttpChannel::Creat
NS_UsePrivateBrowsing(this), isSystemPrincipal, isThirdParty, cos, tc);
}
-enum class Report { Error, Warning };
-
-// Helper Function to report messages to the console when the loaded
-// script had a wrong MIME type.
-void ReportMimeTypeMismatch(nsHttpChannel* aChannel, const char* aMessageName,
- nsIURI* aURI, const nsACString& aContentType,
- Report report) {
- NS_ConvertUTF8toUTF16 spec(aURI->GetSpecOrDefault());
- NS_ConvertUTF8toUTF16 contentType(aContentType);
-
- aChannel->LogMimeTypeMismatch(nsCString(aMessageName),
- report == Report::Warning, spec, contentType);
-}
-
-// Check and potentially enforce X-Content-Type-Options: nosniff
-nsresult ProcessXCTO(nsHttpChannel* aChannel, nsIURI* aURI,
- nsHttpResponseHead* aResponseHead,
- nsILoadInfo* aLoadInfo) {
- if (!aURI || !aResponseHead || !aLoadInfo) {
- // if there is no uri, no response head or no loadInfo, then there is
- // nothing to do
- return NS_OK;
- }
-
- // 1) Query the XCTO header and check if 'nosniff' is the first value.
- nsAutoCString contentTypeOptionsHeader;
- if (!aResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader)) {
- // if failed to get XCTO header, then there is nothing to do.
- return NS_OK;
- }
-
- // let's compare the header (ignoring case)
- // e.g. "NoSniFF" -> "nosniff"
- // if it's not 'nosniff' then there is nothing to do here
- if (!contentTypeOptionsHeader.EqualsIgnoreCase("nosniff")) {
- // since we are getting here, the XCTO header was sent;
- // a non matching value most likely means a mistake happenend;
- // e.g. sending 'nosnif' instead of 'nosniff', let's log a warning.
- AutoTArray<nsString, 1> params;
- CopyUTF8toUTF16(contentTypeOptionsHeader, *params.AppendElement());
- RefPtr<Document> doc;
- aLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
- nsContentUtils::ReportToConsole(
- nsIScriptError::warningFlag, NS_LITERAL_CSTRING("XCTO"), doc,
- nsContentUtils::eSECURITY_PROPERTIES, "XCTOHeaderValueMissing", params);
- return NS_OK;
- }
-
- // 2) Query the content type from the channel
- nsAutoCString contentType;
- aResponseHead->ContentType(contentType);
-
- // 3) Compare the expected MIME type with the actual type
- if (aLoadInfo->GetExternalContentPolicyType() ==
- nsIContentPolicy::TYPE_STYLESHEET) {
- if (contentType.EqualsLiteral(TEXT_CSS)) {
- return NS_OK;
- }
- ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
- Report::Error);
- return NS_ERROR_CORRUPTED_CONTENT;
- }
-
- if (aLoadInfo->GetExternalContentPolicyType() ==
- nsIContentPolicy::TYPE_SCRIPT) {
- if (nsContentUtils::IsJavascriptMIMEType(
- NS_ConvertUTF8toUTF16(contentType))) {
- return NS_OK;
- }
- ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
- Report::Error);
- return NS_ERROR_CORRUPTED_CONTENT;
- }
-
- auto policyType = aLoadInfo->GetExternalContentPolicyType();
- if ((policyType == nsIContentPolicy::TYPE_DOCUMENT ||
- policyType == nsIContentPolicy::TYPE_SUBDOCUMENT) &&
- gHttpHandler->IsDocumentNosniffEnabled()) {
- // If the header XCTO nosniff is set for any browsing context, then
- // we set the skipContentSniffing flag on the Loadinfo. Within
- // GetMIMETypeFromContent we then bail early and do not do any sniffing.
- aLoadInfo->SetSkipContentSniffing(true);
- return NS_OK;
- }
-
- return NS_OK;
-}
-
-// Ensure that a load of type script has correct MIME type
-nsresult EnsureMIMEOfScript(nsHttpChannel* aChannel, nsIURI* aURI,
- nsHttpResponseHead* aResponseHead,
- nsILoadInfo* aLoadInfo) {
- if (!aURI || !aResponseHead || !aLoadInfo) {
- // if there is no uri, no response head or no loadInfo, then there is
- // nothing to do
- return NS_OK;
- }
-
- if (aLoadInfo->GetExternalContentPolicyType() !=
- nsIContentPolicy::TYPE_SCRIPT) {
- // if this is not a script load, then there is nothing to do
- return NS_OK;
- }
-
- nsAutoCString contentType;
- aResponseHead->ContentType(contentType);
- NS_ConvertUTF8toUTF16 typeString(contentType);
-
- if (nsContentUtils::IsJavascriptMIMEType(typeString)) {
- // script load has type script
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::javaScript);
- return NS_OK;
- }
-
- switch (aLoadInfo->InternalContentPolicyType()) {
- case nsIContentPolicy::TYPE_SCRIPT:
- case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
- case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
- case nsIContentPolicy::TYPE_INTERNAL_MODULE:
- case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::script_load);
- break;
- case nsIContentPolicy::TYPE_INTERNAL_WORKER:
- case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worker_load);
- break;
- case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::serviceworker_load);
- break;
- case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::importScript_load);
- break;
- case nsIContentPolicy::TYPE_INTERNAL_AUDIOWORKLET:
- case nsIContentPolicy::TYPE_INTERNAL_PAINTWORKLET:
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worklet_load);
- break;
- default:
- MOZ_ASSERT_UNREACHABLE("unexpected script type");
- break;
- }
-
- bool isPrivateWin = aLoadInfo->GetOriginAttributes().mPrivateBrowsingId > 0;
- bool isSameOrigin = false;
- aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(aURI, isPrivateWin,
- &isSameOrigin);
- if (isSameOrigin) {
- // same origin
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::same_origin);
- } else {
- bool cors = false;
- nsAutoCString corsOrigin;
- nsresult rv = aResponseHead->GetHeader(
- nsHttp::ResolveAtom("Access-Control-Allow-Origin"), corsOrigin);
- if (NS_SUCCEEDED(rv)) {
- if (corsOrigin.Equals("*")) {
- cors = true;
- } else {
- nsCOMPtr<nsIURI> corsOriginURI;
- rv = NS_NewURI(getter_AddRefs(corsOriginURI), corsOrigin);
- if (NS_SUCCEEDED(rv)) {
- bool isPrivateWin =
- aLoadInfo->GetOriginAttributes().mPrivateBrowsingId > 0;
- bool isSameOrigin = false;
- aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(
- corsOriginURI, isPrivateWin, &isSameOrigin);
- if (isSameOrigin) {
- cors = true;
- }
- }
- }
- }
- if (cors) {
- // cors origin
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::CORS_origin);
- } else {
- // cross origin
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::cross_origin);
- }
- }
-
- bool block = false;
- if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("image/"))) {
- // script load has type image
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::image);
- block = true;
- } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("audio/"))) {
- // script load has type audio
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::audio);
- block = true;
- } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("video/"))) {
- // script load has type video
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::video);
- block = true;
- } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/csv"))) {
- // script load has type text/csv
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_csv);
- block = true;
- }
-
- if (block) {
- // Do not block the load if the feature is not enabled.
- if (!StaticPrefs::security_block_script_with_wrong_mime()) {
- return NS_OK;
- }
-
- ReportMimeTypeMismatch(aChannel, "BlockScriptWithWrongMimeType2", aURI,
- contentType, Report::Error);
- return NS_ERROR_CORRUPTED_CONTENT;
- }
-
- if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/plain"))) {
- // script load has type text/plain
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_plain);
- } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/xml"))) {
- // script load has type text/xml
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_xml);
- } else if (StringBeginsWith(contentType,
- NS_LITERAL_CSTRING("application/octet-stream"))) {
- // script load has type application/octet-stream
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_octet_stream);
- } else if (StringBeginsWith(contentType,
- NS_LITERAL_CSTRING("application/xml"))) {
- // script load has type application/xml
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_xml);
- } else if (StringBeginsWith(contentType,
- NS_LITERAL_CSTRING("application/json"))) {
- // script load has type application/json
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_json);
- } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/json"))) {
- // script load has type text/json
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_json);
- } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/html"))) {
- // script load has type text/html
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_html);
- } else if (contentType.IsEmpty()) {
- // script load has no type
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::empty);
- } else {
- // script load has unknown type
- AccumulateCategorical(
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::unknown);
- }
-
- // We restrict importScripts() in worker code to JavaScript MIME types.
- nsContentPolicyType internalType = aLoadInfo->InternalContentPolicyType();
- if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS) {
- // Do not block the load if the feature is not enabled.
- if (!StaticPrefs::security_block_importScripts_with_wrong_mime()) {
- return NS_OK;
- }
-
- ReportMimeTypeMismatch(aChannel, "BlockImportScriptsWithWrongMimeType",
- aURI, contentType, Report::Error);
- return NS_ERROR_CORRUPTED_CONTENT;
- }
-
- if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
- internalType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER) {
- // Do not block the load if the feature is not enabled.
- if (!StaticPrefs::security_block_Worker_with_wrong_mime()) {
- return NS_OK;
- }
-
- ReportMimeTypeMismatch(aChannel, "BlockWorkerWithWrongMimeType", aURI,
- contentType, Report::Error);
- return NS_ERROR_CORRUPTED_CONTENT;
- }
-
- // ES6 modules require a strict MIME type check.
- if (internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE ||
- internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD) {
- ReportMimeTypeMismatch(aChannel, "BlockModuleWithWrongMimeType", aURI,
- contentType, Report::Error);
- return NS_ERROR_CORRUPTED_CONTENT;
- }
-
- return NS_OK;
-}
-
-// Warn when a load of type script uses a wrong MIME type and
-// wasn't blocked by EnsureMIMEOfScript or ProcessXCTO.
-void WarnWrongMIMEOfScript(nsHttpChannel* aChannel, nsIURI* aURI,
- nsHttpResponseHead* aResponseHead,
- nsILoadInfo* aLoadInfo) {
- if (!aURI || !aResponseHead || !aLoadInfo) {
- // If there is no uri, no response head or no loadInfo, then there is
- // nothing to do.
- return;
- }
-
- if (aLoadInfo->GetExternalContentPolicyType() !=
- nsIContentPolicy::TYPE_SCRIPT) {
- // If this is not a script load, then there is nothing to do.
- return;
- }
-
- bool succeeded;
- MOZ_ALWAYS_SUCCEEDS(aChannel->GetRequestSucceeded(&succeeded));
- if (!succeeded) {
- // Do not warn for failed loads: HTTP error pages are usually in HTML.
- return;
- }
-
- nsAutoCString contentType;
- aResponseHead->ContentType(contentType);
- NS_ConvertUTF8toUTF16 typeString(contentType);
- if (!nsContentUtils::IsJavascriptMIMEType(typeString)) {
- ReportMimeTypeMismatch(aChannel, "WarnScriptWithWrongMimeType", aURI,
- contentType, Report::Warning);
- }
-}
-
void nsHttpChannel::SetCachedContentType() {
if (!mResponseHead) {
return;
@@ -1913,14 +1580,9 @@ nsresult nsHttpChannel::CallOnStartReque
mOnStartRequestCalled = true;
});
- nsresult rv = EnsureMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = ProcessXCTO(this, mURI, mResponseHead.get(), mLoadInfo);
+ nsresult rv = ValidateMIMEType();
NS_ENSURE_SUCCESS(rv, rv);
- WarnWrongMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
-
// Allow consumers to override our content type
if (mLoadFlags & LOAD_CALL_CONTENT_SNIFFERS) {
// NOTE: We can have both a txn pump and a cache pump when the cache
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化