LCOV - code coverage report
Current view: top level - caps - BasePrincipal.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 113 212 53.3 %
Date: 2017-07-14 16:53:18 Functions: 23 35 65.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=2 sw=2 et tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/BasePrincipal.h"
       8             : 
       9             : #include "nsDocShell.h"
      10             : #ifdef MOZ_CRASHREPORTER
      11             : #include "nsExceptionHandler.h"
      12             : #endif
      13             : #include "nsIAddonPolicyService.h"
      14             : #include "nsIContentSecurityPolicy.h"
      15             : #include "nsIObjectInputStream.h"
      16             : #include "nsIObjectOutputStream.h"
      17             : #include "nsIStandardURL.h"
      18             : 
      19             : #include "ContentPrincipal.h"
      20             : #include "nsNetUtil.h"
      21             : #include "nsIURIWithPrincipal.h"
      22             : #include "NullPrincipal.h"
      23             : #include "nsScriptSecurityManager.h"
      24             : #include "nsServiceManagerUtils.h"
      25             : 
      26             : #include "mozilla/dom/ChromeUtils.h"
      27             : #include "mozilla/dom/CSPDictionariesBinding.h"
      28             : #include "mozilla/dom/ToJSValue.h"
      29             : 
      30             : namespace mozilla {
      31             : 
      32         343 : BasePrincipal::BasePrincipal(PrincipalKind aKind)
      33             :   : mKind(aKind)
      34             :   , mHasExplicitDomain(false)
      35         343 :   , mInitialized(false)
      36         343 : {}
      37             : 
      38         177 : BasePrincipal::~BasePrincipal()
      39         177 : {}
      40             : 
      41             : NS_IMETHODIMP
      42          29 : BasePrincipal::GetOrigin(nsACString& aOrigin)
      43             : {
      44          29 :   MOZ_ASSERT(mInitialized);
      45             : 
      46          29 :   nsresult rv = GetOriginNoSuffix(aOrigin);
      47          29 :   NS_ENSURE_SUCCESS(rv, rv);
      48             : 
      49          58 :   nsAutoCString suffix;
      50          29 :   rv = GetOriginSuffix(suffix);
      51          29 :   NS_ENSURE_SUCCESS(rv, rv);
      52          29 :   aOrigin.Append(suffix);
      53          29 :   return NS_OK;
      54             : }
      55             : 
      56             : NS_IMETHODIMP
      57          84 : BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin)
      58             : {
      59          84 :   MOZ_ASSERT(mInitialized);
      60          84 :   return mOriginNoSuffix->ToUTF8String(aOrigin);
      61             : }
      62             : 
      63             : bool
      64        2513 : BasePrincipal::Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration)
      65             : {
      66        2513 :   MOZ_ASSERT(aOther);
      67        2513 :   MOZ_ASSERT_IF(Kind() == eCodebasePrincipal, mOriginSuffix);
      68             : 
      69             :   // Expanded principals handle origin attributes for each of their
      70             :   // sub-principals individually, null principals do only simple checks for
      71             :   // pointer equality, and system principals are immune to origin attributes
      72             :   // checks, so only do this check for codebase principals.
      73        2597 :   if (Kind() == eCodebasePrincipal &&
      74          84 :       mOriginSuffix != Cast(aOther)->mOriginSuffix) {
      75           0 :     return false;
      76             :   }
      77             : 
      78        2513 :   return SubsumesInternal(aOther, aConsideration);
      79             : }
      80             : 
      81             : NS_IMETHODIMP
      82          85 : BasePrincipal::Equals(nsIPrincipal *aOther, bool *aResult)
      83             : {
      84          85 :   NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
      85             : 
      86          85 :   *aResult = FastEquals(aOther);
      87             : 
      88          85 :   return NS_OK;
      89             : }
      90             : 
      91             : NS_IMETHODIMP
      92           0 : BasePrincipal::EqualsConsideringDomain(nsIPrincipal *aOther, bool *aResult)
      93             : {
      94           0 :   NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
      95             : 
      96           0 :   *aResult = FastEqualsConsideringDomain(aOther);
      97             : 
      98           0 :   return NS_OK;
      99             : }
     100             : 
     101             : NS_IMETHODIMP
     102         112 : BasePrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
     103             : {
     104         112 :   NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
     105             : 
     106         112 :   *aResult = FastSubsumes(aOther);
     107             : 
     108         112 :   return NS_OK;
     109             : }
     110             : 
     111             : NS_IMETHODIMP
     112         636 : BasePrincipal::SubsumesConsideringDomain(nsIPrincipal *aOther, bool *aResult)
     113             : {
     114         636 :   NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
     115             : 
     116         636 :   *aResult = FastSubsumesConsideringDomain(aOther);
     117             : 
     118         636 :   return NS_OK;
     119             : }
     120             : 
     121             : NS_IMETHODIMP
     122           0 : BasePrincipal::SubsumesConsideringDomainIgnoringFPD(nsIPrincipal *aOther,
     123             :                                                     bool *aResult)
     124             : {
     125           0 :   NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
     126             : 
     127           0 :   *aResult = FastSubsumesConsideringDomainIgnoringFPD(aOther);
     128             : 
     129           0 :   return NS_OK;
     130             : }
     131             : 
     132             : NS_IMETHODIMP
     133          48 : BasePrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrincipal)
     134             : {
     135             :   // Check the internal method first, which allows us to quickly approve loads
     136             :   // for the System Principal.
     137          48 :   if (MayLoadInternal(aURI)) {
     138          46 :     return NS_OK;
     139             :   }
     140             : 
     141             :   nsresult rv;
     142           2 :   if (aAllowIfInheritsPrincipal) {
     143             :     // If the caller specified to allow loads of URIs that inherit
     144             :     // our principal, allow the load if this URI inherits its principal.
     145             :     bool doesInheritSecurityContext;
     146             :     rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
     147           0 :                              &doesInheritSecurityContext);
     148           0 :     if (NS_SUCCEEDED(rv) && doesInheritSecurityContext) {
     149           0 :       return NS_OK;
     150             :     }
     151             :   }
     152             : 
     153             :   bool fetchableByAnyone;
     154           2 :   rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE, &fetchableByAnyone);
     155           2 :   if (NS_SUCCEEDED(rv) && fetchableByAnyone) {
     156           0 :     return NS_OK;
     157             :   }
     158             : 
     159           2 :   if (aReport) {
     160           0 :     nsCOMPtr<nsIURI> prinURI;
     161           0 :     rv = GetURI(getter_AddRefs(prinURI));
     162           0 :     if (NS_SUCCEEDED(rv) && prinURI) {
     163           0 :       nsScriptSecurityManager::ReportError(nullptr, NS_LITERAL_STRING("CheckSameOriginError"), prinURI, aURI);
     164             :     }
     165             :   }
     166             : 
     167           2 :   return NS_ERROR_DOM_BAD_URI;
     168             : }
     169             : 
     170             : NS_IMETHODIMP
     171          42 : BasePrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
     172             : {
     173          42 :   NS_IF_ADDREF(*aCsp = mCSP);
     174          42 :   return NS_OK;
     175             : }
     176             : 
     177             : NS_IMETHODIMP
     178           0 : BasePrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
     179             : {
     180             :   // Never destroy an existing CSP on the principal.
     181             :   // This method should only be called in rare cases.
     182             : 
     183           0 :   MOZ_ASSERT(!mCSP, "do not destroy an existing CSP");
     184           0 :   if (mCSP) {
     185           0 :     return NS_ERROR_ALREADY_INITIALIZED;
     186             :   }
     187             : 
     188           0 :   mCSP = aCsp;
     189           0 :   return NS_OK;
     190             : }
     191             : 
     192             : NS_IMETHODIMP
     193           0 : BasePrincipal::EnsureCSP(nsIDOMDocument* aDocument,
     194             :                          nsIContentSecurityPolicy** aCSP)
     195             : {
     196           0 :   if (mCSP) {
     197             :     // if there is a CSP already associated with this principal
     198             :     // then just return that - do not overwrite it!!!
     199           0 :     NS_IF_ADDREF(*aCSP = mCSP);
     200           0 :     return NS_OK;
     201             :   }
     202             : 
     203           0 :   nsresult rv = NS_OK;
     204           0 :   mCSP = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
     205           0 :   NS_ENSURE_SUCCESS(rv, rv);
     206             : 
     207             :   // Store the request context for violation reports
     208           0 :   rv = aDocument ? mCSP->SetRequestContext(aDocument, nullptr)
     209           0 :                  : mCSP->SetRequestContext(nullptr, this);
     210           0 :   NS_ENSURE_SUCCESS(rv, rv);
     211           0 :   NS_IF_ADDREF(*aCSP = mCSP);
     212           0 :   return NS_OK;
     213             : }
     214             : 
     215             : NS_IMETHODIMP
     216           6 : BasePrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP)
     217             : {
     218           6 :   NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
     219           6 :   return NS_OK;
     220             : }
     221             : 
     222             : NS_IMETHODIMP
     223           0 : BasePrincipal::EnsurePreloadCSP(nsIDOMDocument* aDocument,
     224             :                                 nsIContentSecurityPolicy** aPreloadCSP)
     225             : {
     226           0 :   if (mPreloadCSP) {
     227             :     // if there is a speculative CSP already associated with this principal
     228             :     // then just return that - do not overwrite it!!!
     229           0 :     NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
     230           0 :     return NS_OK;
     231             :   }
     232             : 
     233           0 :   nsresult rv = NS_OK;
     234           0 :   mPreloadCSP = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
     235           0 :   NS_ENSURE_SUCCESS(rv, rv);
     236             : 
     237             :   // Store the request context for violation reports
     238           0 :   rv = aDocument ? mPreloadCSP->SetRequestContext(aDocument, nullptr)
     239           0 :                  : mPreloadCSP->SetRequestContext(nullptr, this);
     240           0 :   NS_ENSURE_SUCCESS(rv, rv);
     241           0 :   NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
     242           0 :   return NS_OK;
     243             : }
     244             : 
     245             : NS_IMETHODIMP
     246           0 : BasePrincipal::GetCspJSON(nsAString& outCSPinJSON)
     247             : {
     248           0 :   outCSPinJSON.Truncate();
     249           0 :   dom::CSPPolicies jsonPolicies;
     250             : 
     251           0 :   if (!mCSP) {
     252           0 :     jsonPolicies.ToJSON(outCSPinJSON);
     253           0 :     return NS_OK;
     254             :   }
     255           0 :   return mCSP->ToJSON(outCSPinJSON);
     256             : }
     257             : 
     258             : NS_IMETHODIMP
     259         139 : BasePrincipal::GetIsNullPrincipal(bool* aResult)
     260             : {
     261         139 :   *aResult = Kind() == eNullPrincipal;
     262         139 :   return NS_OK;
     263             : }
     264             : 
     265             : NS_IMETHODIMP
     266           8 : BasePrincipal::GetIsCodebasePrincipal(bool* aResult)
     267             : {
     268           8 :   *aResult = Kind() == eCodebasePrincipal;
     269           8 :   return NS_OK;
     270             : }
     271             : 
     272             : NS_IMETHODIMP
     273           0 : BasePrincipal::GetIsExpandedPrincipal(bool* aResult)
     274             : {
     275           0 :   *aResult = Kind() == eExpandedPrincipal;
     276           0 :   return NS_OK;
     277             : }
     278             : 
     279             : NS_IMETHODIMP
     280         116 : BasePrincipal::GetIsSystemPrincipal(bool* aResult)
     281             : {
     282         116 :   *aResult = Kind() == eSystemPrincipal;
     283         116 :   return NS_OK;
     284             : }
     285             : 
     286             : NS_IMETHODIMP
     287           0 : BasePrincipal::GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
     288             : {
     289           0 :   if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
     290           0 :     return NS_ERROR_FAILURE;
     291             :   }
     292           0 :   return NS_OK;
     293             : }
     294             : 
     295             : NS_IMETHODIMP
     296          59 : BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes)
     297             : {
     298          59 :   MOZ_ASSERT(mOriginSuffix);
     299          59 :   return mOriginSuffix->ToUTF8String(aOriginAttributes);
     300             : }
     301             : 
     302             : NS_IMETHODIMP
     303          25 : BasePrincipal::GetAppId(uint32_t* aAppId)
     304             : {
     305          25 :   if (AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
     306           0 :     MOZ_ASSERT(false);
     307             :     *aAppId = nsIScriptSecurityManager::NO_APP_ID;
     308             :     return NS_OK;
     309             :   }
     310             : 
     311          25 :   *aAppId = AppId();
     312          25 :   return NS_OK;
     313             : }
     314             : 
     315             : NS_IMETHODIMP
     316           0 : BasePrincipal::GetUserContextId(uint32_t* aUserContextId)
     317             : {
     318           0 :   *aUserContextId = UserContextId();
     319           0 :   return NS_OK;
     320             : }
     321             : 
     322             : NS_IMETHODIMP
     323           4 : BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId)
     324             : {
     325           4 :   *aPrivateBrowsingId = PrivateBrowsingId();
     326           4 :   return NS_OK;
     327             : }
     328             : 
     329             : NS_IMETHODIMP
     330          23 : BasePrincipal::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement)
     331             : {
     332          23 :   *aIsInIsolatedMozBrowserElement = IsInIsolatedMozBrowserElement();
     333          23 :   return NS_OK;
     334             : }
     335             : 
     336             : bool
     337           0 : BasePrincipal::AddonHasPermission(const nsAString& aPerm)
     338             : {
     339           0 :   nsAutoString addonId;
     340           0 :   NS_ENSURE_SUCCESS(GetAddonId(addonId), false);
     341             : 
     342           0 :   if (addonId.IsEmpty()) {
     343           0 :     return false;
     344             :   }
     345             : 
     346             :   nsCOMPtr<nsIAddonPolicyService> aps =
     347           0 :     do_GetService("@mozilla.org/addons/policy-service;1");
     348           0 :   NS_ENSURE_TRUE(aps, false);
     349             : 
     350           0 :   bool retval = false;
     351           0 :   nsresult rv = aps->AddonHasPermission(addonId, aPerm, &retval);
     352           0 :   NS_ENSURE_SUCCESS(rv, false);
     353           0 :   return retval;
     354             : }
     355             : 
     356             : already_AddRefed<BasePrincipal>
     357         205 : BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI,
     358             :                                        const OriginAttributes& aAttrs)
     359             : {
     360         205 :   MOZ_ASSERT(aURI);
     361             : 
     362         410 :   nsAutoCString originNoSuffix;
     363             :   nsresult rv =
     364         205 :     ContentPrincipal::GenerateOriginNoSuffixFromURI(aURI, originNoSuffix);
     365         205 :   if (NS_FAILED(rv)) {
     366             :     // If the generation of the origin fails, we still want to have a valid
     367             :     // principal. Better to return a null principal here.
     368           7 :     return NullPrincipal::Create(aAttrs);
     369             :   }
     370             : 
     371         198 :   return CreateCodebasePrincipal(aURI, aAttrs, originNoSuffix);
     372             : }
     373             : 
     374             : already_AddRefed<BasePrincipal>
     375         198 : BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI,
     376             :                                        const OriginAttributes& aAttrs,
     377             :                                        const nsACString& aOriginNoSuffix)
     378             : {
     379         198 :   MOZ_ASSERT(aURI);
     380         198 :   MOZ_ASSERT(!aOriginNoSuffix.IsEmpty());
     381             : 
     382             :   // If the URI is supposed to inherit the security context of whoever loads it,
     383             :   // we shouldn't make a codebase principal for it.
     384             :   bool inheritsPrincipal;
     385             :   nsresult rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
     386         198 :                                     &inheritsPrincipal);
     387         198 :   if (NS_FAILED(rv) || inheritsPrincipal) {
     388           0 :     return NullPrincipal::Create(aAttrs);
     389             :   }
     390             : 
     391             :   // Check whether the URI knows what its principal is supposed to be.
     392         396 :   nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
     393         198 :   if (uriPrinc) {
     394           0 :     nsCOMPtr<nsIPrincipal> principal;
     395           0 :     uriPrinc->GetPrincipal(getter_AddRefs(principal));
     396           0 :     if (!principal) {
     397           0 :       return NullPrincipal::Create(aAttrs);
     398             :     }
     399           0 :     RefPtr<BasePrincipal> concrete = Cast(principal);
     400           0 :     return concrete.forget();
     401             :   }
     402             : 
     403             :   // Mint a codebase principal.
     404         396 :   RefPtr<ContentPrincipal> codebase = new ContentPrincipal();
     405         198 :   rv = codebase->Init(aURI, aAttrs, aOriginNoSuffix);
     406         198 :   NS_ENSURE_SUCCESS(rv, nullptr);
     407         198 :   return codebase.forget();
     408             : }
     409             : 
     410             : already_AddRefed<BasePrincipal>
     411           0 : BasePrincipal::CreateCodebasePrincipal(const nsACString& aOrigin)
     412             : {
     413           0 :   MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING("[")),
     414             :              "CreateCodebasePrincipal does not support System and Expanded principals");
     415             : 
     416           0 :   MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":")),
     417             :              "CreateCodebasePrincipal does not support NullPrincipal");
     418             : 
     419           0 :   nsAutoCString originNoSuffix;
     420           0 :   mozilla::OriginAttributes attrs;
     421           0 :   if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
     422           0 :     return nullptr;
     423             :   }
     424             : 
     425           0 :   nsCOMPtr<nsIURI> uri;
     426           0 :   nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
     427           0 :   NS_ENSURE_SUCCESS(rv, nullptr);
     428             : 
     429           0 :   return BasePrincipal::CreateCodebasePrincipal(uri, attrs);
     430             : }
     431             : 
     432             : already_AddRefed<BasePrincipal>
     433          14 : BasePrincipal::CloneStrippingUserContextIdAndFirstPartyDomain()
     434             : {
     435          28 :   OriginAttributes attrs = OriginAttributesRef();
     436             :   attrs.StripAttributes(OriginAttributes::STRIP_USER_CONTEXT_ID |
     437          14 :                         OriginAttributes::STRIP_FIRST_PARTY_DOMAIN);
     438             : 
     439          28 :   nsAutoCString originNoSuffix;
     440          14 :   nsresult rv = GetOriginNoSuffix(originNoSuffix);
     441          14 :   NS_ENSURE_SUCCESS(rv, nullptr);
     442             : 
     443          28 :   nsCOMPtr<nsIURI> uri;
     444          14 :   rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
     445          14 :   NS_ENSURE_SUCCESS(rv, nullptr);
     446             : 
     447          14 :   return BasePrincipal::CreateCodebasePrincipal(uri, attrs);
     448             : }
     449             : 
     450             : bool
     451           5 : BasePrincipal::AddonAllowsLoad(nsIURI* aURI, bool aExplicit /* = false */)
     452             : {
     453          10 :   nsAutoString addonId;
     454           5 :   NS_ENSURE_SUCCESS(GetAddonId(addonId), false);
     455             : 
     456           5 :   if (addonId.IsEmpty()) {
     457           5 :     return false;
     458             :   }
     459             : 
     460           0 :   nsCOMPtr<nsIAddonPolicyService> aps = do_GetService("@mozilla.org/addons/policy-service;1");
     461           0 :   NS_ENSURE_TRUE(aps, false);
     462             : 
     463           0 :   bool allowed = false;
     464           0 :   nsresult rv = aps->AddonMayLoadURI(addonId, aURI, aExplicit, &allowed);
     465           0 :   return NS_SUCCEEDED(rv) && allowed;
     466             : }
     467             : 
     468             : void
     469         343 : BasePrincipal::FinishInit(const nsACString& aOriginNoSuffix,
     470             :                           const OriginAttributes& aOriginAttributes)
     471             : {
     472         343 :   mInitialized = true;
     473         343 :   mOriginAttributes = aOriginAttributes;
     474             : 
     475             :   // First compute the origin suffix since it's infallible.
     476         686 :   nsAutoCString originSuffix;
     477         343 :   mOriginAttributes.CreateSuffix(originSuffix);
     478         343 :   mOriginSuffix = NS_Atomize(originSuffix);
     479             : 
     480         343 :   MOZ_ASSERT(!aOriginNoSuffix.IsEmpty());
     481         343 :   mOriginNoSuffix = NS_Atomize(aOriginNoSuffix);
     482         343 : }
     483             : 
     484             : } // namespace mozilla

Generated by: LCOV version 1.13