import from UXP: Issue #2258 - Part 3: Allow sniffing with XCTO:nosniff + empty MIME type. (707c3e3f)

This commit is contained in:
2025-08-18 10:28:00 +08:00
parent fb76747595
commit d1fd2e3b39
5 changed files with 31 additions and 35 deletions
-7
View File
@@ -2502,13 +2502,6 @@ imgLoader::GetMIMETypeFromContent(nsIRequest* aRequest,
uint32_t aLength,
nsACString& aContentType)
{
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
if (channel) {
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (loadInfo->GetSkipContentSniffing()) {
return NS_ERROR_NOT_AVAILABLE;
}
}
return GetMimeTypeFromContent((const char*)aContents, aLength, aContentType);
}
+30 -1
View File
@@ -18,6 +18,7 @@
#include "nsContentUtils.h"
#include "nsHashKeys.h"
#include "nsHttp.h"
#include "nsMimeTypes.h"
#include "nsIAsyncStreamCopier.h"
#include "nsIAuthPrompt.h"
#include "nsIAuthPrompt2.h"
@@ -2150,6 +2151,33 @@ NS_SniffContent(const char *aSnifferType, nsIRequest *aRequest,
return;
}
aSniffedType.Truncate();
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
if (channel) {
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (loadInfo->GetSkipContentSniffing()) {
// In case XCTO nosniff was present, we should skip sniffing here, but...
nsAutoCString currentContentType;
channel->GetContentType(currentContentType);
// We cannot skip sniffing if the current MIME type is a JSON file.
// The JSON-Viewer relies on its own sniffer to determine if it can render
// the page, so we need to make an exception if the Server provides a valid
// JSON MIME type (application/json, application/web-manifest or text/json).
// We also don't skip sniffing if the currently-known content type is empty,
// to deal with webmaster errors (nosniff is set but no content-type supplied)
// See Issue #2258.
if (!currentContentType.Equals(APPLICATION_JSON) &&
!currentContentType.Equals(APPLICATION_WEB_MANIFEST) &&
!currentContentType.Equals(TEXT_JSON) &&
!currentContentType.IsEmpty()) {
// Content type supplied and it's not a JSON type; honor XCTO:nosniff.
return;
}
}
}
// Iterate through the sniffers...
nsCOMArray<nsIContentSniffer> sniffers;
cache->GetEntries(sniffers);
for (int32_t i = 0; i < sniffers.Count(); ++i) {
@@ -2158,8 +2186,9 @@ NS_SniffContent(const char *aSnifferType, nsIRequest *aRequest,
return;
}
}
// If we get here, there's nothing more to be done, return with a truncated aSniffedType.
aSniffedType.Truncate();
}
bool
+1 -1
View File
@@ -1181,7 +1181,7 @@ ProcessXCTO(nsIURI* aURI, nsHttpResponseHead* aResponseHead, nsILoadInfo* aLoadI
policyType == nsIContentPolicy::TYPE_SUBDOCUMENT) {
// 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.
// NS_SniffContent we then bail early and do not do any sniffing.
aLoadInfo->SetSkipContentSniffing(true);
return NS_OK;
}
@@ -316,13 +316,6 @@ nsUnknownDecoder::GetMIMETypeFromContent(nsIRequest* aRequest,
nsACString& type)
{
// Note: This is only used by sniffer, therefore we do not need to lock anything here.
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
if (channel) {
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (loadInfo->GetSkipContentSniffing()) {
return NS_ERROR_NOT_AVAILABLE;
}
}
mBuffer = const_cast<char*>(reinterpret_cast<const char*>(aData));
mBufferLen = aLength;
DetermineContentType(aRequest);
@@ -353,11 +346,6 @@ bool nsUnknownDecoder::AllowSniffing(nsIRequest* aRequest)
return false;
}
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (loadInfo->GetSkipContentSniffing()) {
return false;
}
bool isLocalFile = false;
if (NS_FAILED(uri->SchemeIs("file", &isLocalFile)) || isLocalFile) {
return false;
@@ -405,13 +393,6 @@ void nsUnknownDecoder::DetermineContentType(nsIRequest* aRequest)
if (!mContentType.IsEmpty()) return;
nsCOMPtr<nsIHttpChannel> channel(do_QueryInterface(aRequest));
if (channel) {
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (loadInfo->GetSkipContentSniffing()) {
return;
}
}
const char* testData = mBuffer;
uint32_t testDataLen = mBufferLen;
// Check if data are compressed.
@@ -583,9 +564,6 @@ bool nsUnknownDecoder::SniffURI(nsIRequest* aRequest)
{
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (loadInfo->GetSkipContentSniffing()) {
return false;
}
nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1"));
if (mimeService) {
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
@@ -138,10 +138,6 @@ nsMediaSniffer::GetMIMETypeFromContent(nsIRequest* aRequest,
nsACString& aSniffedType) {
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
if (channel) {
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (loadInfo->GetSkipContentSniffing()) {
return NS_ERROR_NOT_AVAILABLE;
}
nsLoadFlags loadFlags = 0;
channel->GetLoadFlags(&loadFlags);
if (!(loadFlags & nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE)) {