Skip to content

Commit

Permalink
Bug 1905843, prevent unexpected use of result site origin, r=nika
Browse files Browse the repository at this point in the history
  • Loading branch information
Olli Pettay authored and Olli Pettay committed Sep 17, 2024
1 parent fd62692 commit ecd90ac
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 2 deletions.
2 changes: 0 additions & 2 deletions caps/nsScriptSecurityManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,6 @@ class nsScriptSecurityManager final : public nsIScriptSecurityManager {
bool aFromPrivateWindow,
uint64_t aInnerWindowID = 0);

static uint32_t HashPrincipalByOrigin(nsIPrincipal* aPrincipal);

static bool GetStrictFileOriginPolicy() { return sStrictFileOriginPolicy; }

void DeactivateDomainPolicy();
Expand Down
67 changes: 67 additions & 0 deletions dom/security/nsContentSecurityManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "nsNetUtil.h"
#include "nsReadableUtils.h"
#include "nsSandboxFlags.h"
#include "nsScriptSecurityManager.h"
#include "nsIXPConnect.h"

#include "mozilla/BasePrincipal.h"
Expand Down Expand Up @@ -1427,6 +1428,9 @@ nsresult nsContentSecurityManager::doContentSecurityCheck(
rv = CheckAllowLoadByTriggeringRemoteType(aChannel);
NS_ENSURE_SUCCESS(rv, rv);

rv = CheckForIncoherentResultPrincipal(aChannel);
NS_ENSURE_SUCCESS(rv, rv);

// if dealing with a redirected channel then we have already installed
// streamlistener and redirect proxies and so we are done.
if (loadInfo->GetInitialSecurityCheckDone()) {
Expand Down Expand Up @@ -1709,3 +1713,66 @@ nsContentSecurityManager::PerformSecurityCheck(
inAndOutListener.forget(outStreamListener);
return NS_OK;
}

nsresult nsContentSecurityManager::CheckForIncoherentResultPrincipal(
nsIChannel* aChannel) {
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
ExtContentPolicyType contentPolicyType =
loadInfo->GetExternalContentPolicyType();
if (contentPolicyType != ExtContentPolicyType::TYPE_DOCUMENT &&
contentPolicyType != ExtContentPolicyType::TYPE_SUBDOCUMENT &&
contentPolicyType != ExtContentPolicyType::TYPE_OBJECT) {
return NS_OK;
}

nsCOMPtr<nsIPrincipal> resultOrPrecursor;
nsresult rv = nsScriptSecurityManager::GetScriptSecurityManager()
->GetChannelResultPrincipalIfNotSandboxed(
aChannel, getter_AddRefs(resultOrPrecursor));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(resultOrPrecursor);

if (nsCOMPtr<nsIPrincipal> precursor =
resultOrPrecursor->GetPrecursorPrincipal()) {
resultOrPrecursor = precursor;
}

if (!resultOrPrecursor->GetIsContentPrincipal()) {
return NS_OK;
}

nsAutoCString resultSiteOriginNoSuffix;
rv = resultOrPrecursor->GetSiteOriginNoSuffix(resultSiteOriginNoSuffix);
NS_ENSURE_SUCCESS(rv, rv);

nsCOMPtr<nsIURI> resultSiteOriginURI;
NS_NewURI(getter_AddRefs(resultSiteOriginURI), resultSiteOriginNoSuffix);
NS_ENSURE_STATE(resultSiteOriginURI);

nsCOMPtr<nsIURI> channelURI;
aChannel->GetURI(getter_AddRefs(channelURI));
NS_ENSURE_STATE(channelURI);

nsCOMPtr<nsIPrincipal> channelUriPrincipal =
BasePrincipal::CreateContentPrincipal(channelURI, {});
NS_ENSURE_STATE(channelUriPrincipal);

nsAutoCString channelUriSiteOrigin;
rv = channelUriPrincipal->GetSiteOriginNoSuffix(channelUriSiteOrigin);
NS_ENSURE_SUCCESS(rv, rv);

nsCOMPtr<nsIURI> channelSiteOriginURI;
NS_NewURI(getter_AddRefs(channelSiteOriginURI), channelUriSiteOrigin);
NS_ENSURE_STATE(channelSiteOriginURI);

if (nsScriptSecurityManager::IsHttpOrHttpsAndCrossOrigin(
resultSiteOriginURI, channelSiteOriginURI) ||
(!net::SchemeIsHTTP(resultSiteOriginURI) &&
!net::SchemeIsHTTPS(resultSiteOriginURI) &&
(net::SchemeIsHTTP(channelSiteOriginURI) ||
net::SchemeIsHTTPS(channelSiteOriginURI)))) {
return NS_ERROR_CONTENT_BLOCKED;
}

return NS_OK;
}
1 change: 1 addition & 0 deletions dom/security/nsContentSecurityManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class nsContentSecurityManager : public nsIContentSecurityManager,
static nsresult CheckAllowLoadInPrivilegedAboutContext(nsIChannel* aChannel);
static nsresult CheckChannelHasProtocolSecurityFlag(nsIChannel* aChannel);
static bool CrossOriginEmbedderPolicyAllowsCredentials(nsIChannel* aChannel);
static nsresult CheckForIncoherentResultPrincipal(nsIChannel* aChannel);

virtual ~nsContentSecurityManager() = default;
};
Expand Down

0 comments on commit ecd90ac

Please sign in to comment.