769 lines
30 KiB
Diff
769 lines
30 KiB
Diff
|
|
# 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
|