Commit 792a165f authored by Eden Chuang's avatar Eden Chuang
Browse files

Bug 1753025 - Using correct principal to create channel for NavigationPreload....

Bug 1753025 - Using correct principal to create channel for NavigationPreload. r=dom-worker-reviewers,jesup

Currently using the pricinpal of InternalRequest to create the channel for NavigationPreload.
However, it is not a correct principal and makes NavigationPreload stop with channel security checking.
Instead of using the principal of InternalRequest, this patch uses the loadingPrincipal of InterceptedHttpChannel to create the channel.

Differential Revision: https://phabricator.services.mozilla.com/D137594
parent 552a9e76
Loading
Loading
Loading
Loading
+40 −38
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include "nsNetUtil.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/dom/FetchService.h"
@@ -32,32 +33,30 @@ nsresult FetchService::FetchInstance::Initialize(nsIChannel* aChannel) {
  MOZ_ASSERT(XRE_IsParentProcess());
  MOZ_ASSERT(NS_IsMainThread());

  // Setup principal form InternalRequest
  const mozilla::UniquePtr<mozilla::ipc::PrincipalInfo>& principalInfo =
      mRequest->GetPrincipalInfo();
  MOZ_ASSERT(principalInfo);
  auto principalOrErr = PrincipalInfoToPrincipal(*principalInfo);
  if (NS_WARN_IF(principalOrErr.isErr())) {
    return principalOrErr.unwrapErr();
  }
  mPrincipal = principalOrErr.unwrap();

  // Get needed information for FetchDriver from passed-in channel.
  if (aChannel) {
    nsresult rv;
    nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
    MOZ_ASSERT(loadInfo);

    // Principal in the InternalRequest should be the same with the triggering
    // principal in the LoadInfo
    nsCOMPtr<nsIPrincipal> triggeringPrincipal;
    rv = loadInfo->GetTriggeringPrincipal(getter_AddRefs(triggeringPrincipal));
    rv = loadInfo->GetLoadingPrincipal(getter_AddRefs(mPrincipal));
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
    if (!mPrincipal->Equals(triggeringPrincipal)) {

    // Top level document load has no loadingPrincipal, try to use channel's URI
    if (!mPrincipal) {
      nsCOMPtr<nsIURI> channelURI;
      rv = aChannel->GetURI(getter_AddRefs(channelURI));
      if (NS_WARN_IF(NS_FAILED(rv))) {
        return rv;
      }
      mPrincipal = BasePrincipal::CreateContentPrincipal(
          channelURI, loadInfo->GetOriginAttributes());
      if (!mPrincipal) {
        return NS_ERROR_UNEXPECTED;
      }
    }

    // Get loadGroup from channel
    rv = aChannel->GetLoadGroup(getter_AddRefs(mLoadGroup));
@@ -130,6 +129,9 @@ void FetchService::FetchInstance::Cancel() {
  if (mFetchDriver) {
    mFetchDriver->RunAbortAlgorithm();
  }

  mResponsePromiseHolder.ResolveIfExists(
      InternalResponse::NetworkError(NS_ERROR_DOM_ABORT_ERR), __func__);
}

void FetchService::FetchInstance::OnResponseEnd(
@@ -142,6 +144,7 @@ void FetchService::FetchInstance::OnResponseEnd(

void FetchService::FetchInstance::OnResponseAvailableInternal(
    SafeRefPtr<InternalResponse> aResponse) {
  if (!mResponsePromiseHolder.IsEmpty()) {
    // Remove the FetchInstance from FetchInstanceTable
    RefPtr<FetchServiceResponsePromise> responsePromise =
        mResponsePromiseHolder.Ensure(__func__);
@@ -150,7 +153,7 @@ void FetchService::FetchInstance::OnResponseAvailableInternal(
    auto entry = fetchService->mFetchInstanceTable.Lookup(responsePromise);
    MOZ_ASSERT(entry);
    entry.Remove();

  }
  // Resolve the FetchServiceResponsePromise
  mResponsePromiseHolder.ResolveIfExists(std::move(aResponse), __func__);
}
@@ -210,12 +213,10 @@ RefPtr<FetchServiceResponsePromise> FetchService::Fetch(
  // Call FetchInstance::Fetch() to start an asynchronous fetching.
  RefPtr<FetchServiceResponsePromise> responsePromise = fetch->Fetch();

  if (!responsePromise->IsResolved()) {
    // Insert the created FetchInstance into FetchInstanceTable.
  // TODO: the FetchInstance should be removed from FetchInstanceTable, once the
  //       fetching finishes or be aborted. This should be implemented in
  //       following patches when implementing FetchDriverObserver on
  //       FetchInstance
  if (!mFetchInstanceTable.WithEntryHandle(responsePromise, [&](auto&& entry) {
    if (!mFetchInstanceTable.WithEntryHandle(responsePromise,
                                             [&](auto&& entry) {
                                               if (entry.HasEntry()) {
                                                 return false;
                                               }
@@ -224,6 +225,7 @@ RefPtr<FetchServiceResponsePromise> FetchService::Fetch(
                                             })) {
      return NetworkErrorResponse(NS_ERROR_UNEXPECTED);
    }
  }
  return responsePromise;
}

+1 −12
Original line number Diff line number Diff line
prefs: [dom.serviceWorkers.navigationPreload.enabled:true]
[navigation-headers.https.html]
  expected:
    if fission and (os == "linux") and not debug: [OK, TIMEOUT]
  [GET Navigation, same-origin with navpreload service worker sets correct origin and referer headers.]
    expected: FAIL

  [POST Navigation, same-site with passthrough service worker sets correct origin and referer headers.]
    expected: FAIL

  [GET Navigation, same-site with navpreload service worker sets correct origin and referer headers.]
    expected: FAIL

  [POST Navigation, cross-site with passthrough service worker sets correct origin and referer headers.]
    expected: FAIL

  [GET Navigation, cross-site with navpreload service worker sets correct origin and referer headers.]
    expected: FAIL

  [GET Navigation, same-origin with passthrough service worker sets correct sec-fetch headers.]
    expected: FAIL

  [POST Navigation, same-origin with passthrough service worker sets correct sec-fetch headers.]
    expected: FAIL

  [GET Navigation, same-origin with navpreload service worker sets correct sec-fetch headers.]
    expected: FAIL

  [GET Navigation, same-site with passthrough service worker sets correct sec-fetch headers.]
    expected: FAIL