diff --git a/services/network/public/cpp/header_util.cc b/services/network/public/cpp/header_util.cc index cabfb3121e1d3..b2706cdcd4f43 100644 --- a/services/network/public/cpp/header_util.cc +++ b/services/network/public/cpp/header_util.cc @@ -17,6 +17,7 @@ #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" +#include "net/http/http_util.h" #include "services/network/public/cpp/features.h" #include "services/network/public/mojom/url_response_head.mojom.h" #include "url/gurl.h" @@ -249,8 +250,15 @@ bool ShouldSniffContent(const GURL& url, response.headers->GetNormalizedHeader("x-content-type-options") .value_or(std::string()); } + // https://fetch.spec.whatwg.org/#determine-nosniff: split on commas and + // check whether the *first* token is "nosniff". A strict equality check on + // the normalized header would fail when the header is duplicated (the + // values are coalesced into "nosniff, nosniff"). + net::HttpUtil::ValuesIterator it(content_type_options, ',', + /*ignore_empty_values=*/false); bool sniffing_blocked = - base::EqualsCaseInsensitiveASCII(content_type_options, "nosniff"); + it.GetNext() && + base::EqualsCaseInsensitiveASCII(it.value(), "nosniff"); bool we_would_like_to_sniff = net::ShouldSniffMimeType(url, response.mime_type); diff --git a/third_party/blink/common/loader/mime_sniffing_throttle.cc b/third_party/blink/common/loader/mime_sniffing_throttle.cc index 08b82e6dcd2c2..2ab367e8aa61a 100644 --- a/third_party/blink/common/loader/mime_sniffing_throttle.cc +++ b/third_party/blink/common/loader/mime_sniffing_throttle.cc @@ -11,6 +11,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/mime_sniffer.h" #include "net/http/http_response_headers.h" +#include "net/http/http_util.h" #include "services/network/public/mojom/url_response_head.mojom.h" #include "third_party/blink/public/common/loader/mime_sniffing_url_loader.h" @@ -44,8 +45,12 @@ void MimeSniffingThrottle::WillProcessResponse( if (std::optional content_type_options = response_head->headers->GetNormalizedHeader( "x-content-type-options")) { + // https://fetch.spec.whatwg.org/#determine-nosniff + net::HttpUtil::ValuesIterator it(*content_type_options, ',', + /*ignore_empty_values=*/false); blocked_sniffing_mime = - base::EqualsCaseInsensitiveASCII(*content_type_options, "nosniff"); + it.GetNext() && + base::EqualsCaseInsensitiveASCII(it.value(), "nosniff"); } }