mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-28 10:07:30 +09:00
Issue #2258 - Part 3: Allow sniffing with XCTO:nosniff + empty MIME type.
This moves the checking code back to NS_SniffContent and specifically checks requests for either: - Empty `Content-type` header, OR - A known JSON MIME type If present, sniffing is allowed despite `nosniff` because in the first case this is webmaster error (conflicting `nosniff` without MIME type would always fail, so sniff it), and in the second case we need this carveout or our json viewer will break.
This commit is contained in:
parent
cca20ae131
commit
707c3e3fa8
5 changed files with 31 additions and 35 deletions
|
|
@ -2489,13 +2489,6 @@ imgLoader::GetMIMETypeFromContent(nsIRequest* aRequest,
|
||||||
uint32_t aLength,
|
uint32_t aLength,
|
||||||
nsACString& aContentType)
|
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);
|
return GetMimeTypeFromContent((const char*)aContents, aLength, aContentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
#include "nsHttp.h"
|
#include "nsHttp.h"
|
||||||
|
#include "nsMimeTypes.h"
|
||||||
#include "nsIAsyncStreamCopier.h"
|
#include "nsIAsyncStreamCopier.h"
|
||||||
#include "nsIAuthPrompt.h"
|
#include "nsIAuthPrompt.h"
|
||||||
#include "nsIAuthPrompt2.h"
|
#include "nsIAuthPrompt2.h"
|
||||||
|
|
@ -2149,6 +2150,33 @@ NS_SniffContent(const char *aSnifferType, nsIRequest *aRequest,
|
||||||
return;
|
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;
|
nsCOMArray<nsIContentSniffer> sniffers;
|
||||||
cache->GetEntries(sniffers);
|
cache->GetEntries(sniffers);
|
||||||
for (int32_t i = 0; i < sniffers.Count(); ++i) {
|
for (int32_t i = 0; i < sniffers.Count(); ++i) {
|
||||||
|
|
@ -2157,8 +2185,9 @@ NS_SniffContent(const char *aSnifferType, nsIRequest *aRequest,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we get here, there's nothing more to be done, return with a truncated aSniffedType.
|
||||||
|
|
||||||
aSniffedType.Truncate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -1106,7 +1106,7 @@ ProcessXCTO(nsIURI* aURI, nsHttpResponseHead* aResponseHead, nsILoadInfo* aLoadI
|
||||||
policyType == nsIContentPolicy::TYPE_SUBDOCUMENT) {
|
policyType == nsIContentPolicy::TYPE_SUBDOCUMENT) {
|
||||||
// If the header XCTO nosniff is set for any browsing context, then
|
// If the header XCTO nosniff is set for any browsing context, then
|
||||||
// we set the skipContentSniffing flag on the Loadinfo. Within
|
// 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);
|
aLoadInfo->SetSkipContentSniffing(true);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -316,13 +316,6 @@ nsUnknownDecoder::GetMIMETypeFromContent(nsIRequest* aRequest,
|
||||||
nsACString& type)
|
nsACString& type)
|
||||||
{
|
{
|
||||||
// Note: This is only used by sniffer, therefore we do not need to lock anything here.
|
// 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));
|
mBuffer = const_cast<char*>(reinterpret_cast<const char*>(aData));
|
||||||
mBufferLen = aLength;
|
mBufferLen = aLength;
|
||||||
DetermineContentType(aRequest);
|
DetermineContentType(aRequest);
|
||||||
|
|
@ -353,11 +346,6 @@ bool nsUnknownDecoder::AllowSniffing(nsIRequest* aRequest)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
|
|
||||||
if (loadInfo->GetSkipContentSniffing()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isLocalFile = false;
|
bool isLocalFile = false;
|
||||||
if (NS_FAILED(uri->SchemeIs("file", &isLocalFile)) || isLocalFile) {
|
if (NS_FAILED(uri->SchemeIs("file", &isLocalFile)) || isLocalFile) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -405,13 +393,6 @@ void nsUnknownDecoder::DetermineContentType(nsIRequest* aRequest)
|
||||||
if (!mContentType.IsEmpty()) return;
|
if (!mContentType.IsEmpty()) return;
|
||||||
|
|
||||||
nsCOMPtr<nsIHttpChannel> channel(do_QueryInterface(aRequest));
|
nsCOMPtr<nsIHttpChannel> channel(do_QueryInterface(aRequest));
|
||||||
if (channel) {
|
|
||||||
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
|
|
||||||
if (loadInfo->GetSkipContentSniffing()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* testData = mBuffer;
|
const char* testData = mBuffer;
|
||||||
uint32_t testDataLen = mBufferLen;
|
uint32_t testDataLen = mBufferLen;
|
||||||
// Check if data are compressed.
|
// Check if data are compressed.
|
||||||
|
|
@ -583,9 +564,6 @@ bool nsUnknownDecoder::SniffURI(nsIRequest* aRequest)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
|
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
|
||||||
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
|
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
|
||||||
if (loadInfo->GetSkipContentSniffing()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1"));
|
nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1"));
|
||||||
if (mimeService) {
|
if (mimeService) {
|
||||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||||
|
|
|
||||||
|
|
@ -138,10 +138,6 @@ nsMediaSniffer::GetMIMETypeFromContent(nsIRequest* aRequest,
|
||||||
nsACString& aSniffedType) {
|
nsACString& aSniffedType) {
|
||||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
|
|
||||||
if (loadInfo->GetSkipContentSniffing()) {
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
}
|
|
||||||
nsLoadFlags loadFlags = 0;
|
nsLoadFlags loadFlags = 0;
|
||||||
channel->GetLoadFlags(&loadFlags);
|
channel->GetLoadFlags(&loadFlags);
|
||||||
if (!(loadFlags & nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE)) {
|
if (!(loadFlags & nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE)) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue