mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-03 06:18:38 +09:00
moebius#223: Consider blocking top level window data: URIs (part 1/3 without tests)
https://github.com/MoonchildProductions/moebius/pull/223
This commit is contained in:
parent
08e2f9aaea
commit
712d19e1b7
22 changed files with 515 additions and 1 deletions
|
|
@ -1,13 +1,16 @@
|
|||
#include "nsContentSecurityManager.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsIOService.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCORSListenerProxy.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsMixedContentBlocker.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
|
|
@ -15,6 +18,66 @@ NS_IMPL_ISUPPORTS(nsContentSecurityManager,
|
|||
nsIContentSecurityManager,
|
||||
nsIChannelEventSink)
|
||||
|
||||
/* static */ bool
|
||||
nsContentSecurityManager::AllowTopLevelNavigationToDataURI(
|
||||
nsIURI* aURI,
|
||||
nsContentPolicyType aContentPolicyType,
|
||||
nsIPrincipal* aTriggeringPrincipal,
|
||||
bool aLoadFromExternal)
|
||||
{
|
||||
// Let's block all toplevel document navigations to a data: URI.
|
||||
// In all cases where the toplevel document is navigated to a
|
||||
// data: URI the triggeringPrincipal is a codeBasePrincipal, or
|
||||
// a NullPrincipal. In other cases, e.g. typing a data: URL into
|
||||
// the URL-Bar, the triggeringPrincipal is a SystemPrincipal;
|
||||
// we don't want to block those loads. Only exception, loads coming
|
||||
// from an external applicaton (e.g. Thunderbird) don't load
|
||||
// using a codeBasePrincipal, but we want to block those loads.
|
||||
if (!mozilla::net::nsIOService::BlockToplevelDataUriNavigations()) {
|
||||
return true;
|
||||
}
|
||||
if (aContentPolicyType != nsIContentPolicy::TYPE_DOCUMENT) {
|
||||
return true;
|
||||
}
|
||||
bool isDataURI =
|
||||
(NS_SUCCEEDED(aURI->SchemeIs("data", &isDataURI)) && isDataURI);
|
||||
if (!isDataURI) {
|
||||
return true;
|
||||
}
|
||||
// Whitelist data: images as long as they are not SVGs
|
||||
nsAutoCString filePath;
|
||||
aURI->GetFilePath(filePath);
|
||||
if (StringBeginsWith(filePath, NS_LITERAL_CSTRING("image/")) &&
|
||||
!StringBeginsWith(filePath, NS_LITERAL_CSTRING("image/svg+xml"))) {
|
||||
return true;
|
||||
}
|
||||
// Whitelist data: PDFs and JSON
|
||||
if (StringBeginsWith(filePath, NS_LITERAL_CSTRING("application/pdf")) ||
|
||||
StringBeginsWith(filePath, NS_LITERAL_CSTRING("application/json"))) {
|
||||
return true;
|
||||
}
|
||||
if (!aLoadFromExternal &&
|
||||
nsContentUtils::IsSystemPrincipal(aTriggeringPrincipal)) {
|
||||
return true;
|
||||
}
|
||||
nsAutoCString dataSpec;
|
||||
aURI->GetSpec(dataSpec);
|
||||
if (dataSpec.Length() > 50) {
|
||||
dataSpec.Truncate(50);
|
||||
dataSpec.AppendLiteral("...");
|
||||
}
|
||||
NS_ConvertUTF8toUTF16 specUTF16(NS_UnescapeURL(dataSpec));
|
||||
const char16_t* params[] = { specUTF16.get() };
|
||||
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
|
||||
NS_LITERAL_CSTRING("DATA_URI_BLOCKED"),
|
||||
// no doc available, log to browser console
|
||||
nullptr,
|
||||
nsContentUtils::eSECURITY_PROPERTIES,
|
||||
"BlockTopLevelDataURINavigation",
|
||||
params, ArrayLength(params));
|
||||
return false;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
ValidateSecurityFlags(nsILoadInfo* aLoadInfo)
|
||||
{
|
||||
|
|
@ -478,6 +541,27 @@ nsContentSecurityManager::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
|||
}
|
||||
}
|
||||
|
||||
// Redirecting to a toplevel data: URI is not allowed, hence we pass
|
||||
// a NullPrincipal as the TriggeringPrincipal to
|
||||
// AllowTopLevelNavigationToDataURI() which definitely blocks any
|
||||
// data: URI load.
|
||||
nsCOMPtr<nsILoadInfo> newLoadInfo = aNewChannel->GetLoadInfo();
|
||||
if (newLoadInfo) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIPrincipal> nullTriggeringPrincipal = nsNullPrincipal::Create();
|
||||
if (!nsContentSecurityManager::AllowTopLevelNavigationToDataURI(
|
||||
uri,
|
||||
newLoadInfo->GetExternalContentPolicyType(),
|
||||
nullTriggeringPrincipal,
|
||||
false)) {
|
||||
// logging to console happens within AllowTopLevelNavigationToDataURI
|
||||
aOldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
}
|
||||
|
||||
// Also verify that the redirecting server is allowed to redirect to the
|
||||
// given URI
|
||||
nsCOMPtr<nsIPrincipal> oldPrincipal;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue