LCOV - code coverage report
Current view: top level - dom/base - nsDataDocumentContentPolicy.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 19 57 33.3 %
Date: 2017-07-14 16:53:18 Functions: 4 6 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 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             : /*
       8             :  * Content policy implementation that prevents all loads of images,
       9             :  * subframes, etc from documents loaded as data (eg documents loaded
      10             :  * via XMLHttpRequest).
      11             :  */
      12             : 
      13             : #include "nsContentUtils.h"
      14             : #include "nsDataDocumentContentPolicy.h"
      15             : #include "nsNetUtil.h"
      16             : #include "nsIProtocolHandler.h"
      17             : #include "nsScriptSecurityManager.h"
      18             : #include "nsIDocument.h"
      19             : #include "nsINode.h"
      20             : #include "nsIDOMWindow.h"
      21             : #include "nsIURI.h"
      22             : 
      23          24 : NS_IMPL_ISUPPORTS(nsDataDocumentContentPolicy, nsIContentPolicy)
      24             : 
      25             : // Helper method for ShouldLoad()
      26             : // Checks a URI for the given flags.  Returns true if the URI has the flags,
      27             : // and false if not (or if we weren't able to tell).
      28             : static bool
      29           0 : HasFlags(nsIURI* aURI, uint32_t aURIFlags)
      30             : {
      31             :   bool hasFlags;
      32           0 :   nsresult rv = NS_URIChainHasFlags(aURI, aURIFlags, &hasFlags);
      33           0 :   return NS_SUCCEEDED(rv) && hasFlags;
      34             : }
      35             : 
      36             : // If you change DataDocumentContentPolicy, make sure to check that
      37             : // CHECK_PRINCIPAL_AND_DATA in nsContentPolicyUtils is still valid.
      38             : // nsContentPolicyUtils may not pass all the parameters to ShouldLoad.
      39             : NS_IMETHODIMP
      40          23 : nsDataDocumentContentPolicy::ShouldLoad(uint32_t aContentType,
      41             :                                         nsIURI *aContentLocation,
      42             :                                         nsIURI *aRequestingLocation,
      43             :                                         nsISupports *aRequestingContext,
      44             :                                         const nsACString &aMimeGuess,
      45             :                                         nsISupports *aExtra,
      46             :                                         nsIPrincipal *aRequestPrincipal,
      47             :                                         int16_t *aDecision)
      48             : {
      49          23 :   MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
      50             :              "We should only see external content policy types here.");
      51             : 
      52          23 :   *aDecision = nsIContentPolicy::ACCEPT;
      53             :   // Look for the document.  In most cases, aRequestingContext is a node.
      54          46 :   nsCOMPtr<nsIDocument> doc;
      55          46 :   nsCOMPtr<nsINode> node = do_QueryInterface(aRequestingContext);
      56          23 :   if (node) {
      57          13 :     doc = node->OwnerDoc();
      58             :   } else {
      59          20 :     if (nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(aRequestingContext)) {
      60           2 :       doc = window->GetDoc();
      61             :     }
      62             :   }
      63             : 
      64             :   // DTDs are always OK to load
      65          23 :   if (!doc || aContentType == nsIContentPolicy::TYPE_DTD) {
      66           8 :     return NS_OK;
      67             :   }
      68             : 
      69             :   // Nothing else is OK to load for data documents
      70          15 :   if (doc->IsLoadedAsData()) {
      71             :     // ...but let static (print/print preview) documents to load fonts.
      72           0 :     if (!doc->IsStaticDocument() || aContentType != nsIContentPolicy::TYPE_FONT) {
      73           0 :       *aDecision = nsIContentPolicy::REJECT_TYPE;
      74           0 :       return NS_OK;
      75             :     }
      76             :   }
      77             : 
      78          15 :   nsIDocument* docToCheckForImage = doc->GetDisplayDocument();
      79          15 :   if (!docToCheckForImage) {
      80          15 :     docToCheckForImage = doc;
      81             :   }
      82             : 
      83          15 :   if (docToCheckForImage->IsBeingUsedAsImage()) {
      84             :     // We only allow SVG images to load content from URIs that are local and
      85             :     // also satisfy one of the following conditions:
      86             :     //  - URI inherits security context, e.g. data URIs
      87             :     //   OR
      88             :     //  - URI loadable by subsumers, e.g. blob URIs
      89             :     // Any URI that doesn't meet these requirements will be rejected below.
      90           0 :     if (!(HasFlags(aContentLocation,
      91             :                    nsIProtocolHandler::URI_IS_LOCAL_RESOURCE) &&
      92           0 :           (HasFlags(aContentLocation,
      93           0 :                     nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT) ||
      94           0 :            HasFlags(aContentLocation,
      95             :                     nsIProtocolHandler::URI_LOADABLE_BY_SUBSUMERS)))) {
      96           0 :       *aDecision = nsIContentPolicy::REJECT_TYPE;
      97             : 
      98             :       // Report error, if we can.
      99           0 :       if (node) {
     100           0 :         nsIPrincipal* requestingPrincipal = node->NodePrincipal();
     101           0 :         RefPtr<nsIURI> principalURI;
     102             :         nsresult rv =
     103           0 :           requestingPrincipal->GetURI(getter_AddRefs(principalURI));
     104           0 :         if (NS_SUCCEEDED(rv) && principalURI) {
     105           0 :           nsScriptSecurityManager::ReportError(
     106           0 :             nullptr, NS_LITERAL_STRING("ExternalDataError"), principalURI,
     107           0 :             aContentLocation);
     108             :         }
     109             :       }
     110           0 :     } else if ((aContentType == nsIContentPolicy::TYPE_IMAGE ||
     111           0 :                 aContentType == nsIContentPolicy::TYPE_IMAGESET) &&
     112           0 :                doc->GetDocumentURI()) {
     113             :       // Check for (& disallow) recursive image-loads
     114             :       bool isRecursiveLoad;
     115           0 :       nsresult rv = aContentLocation->EqualsExceptRef(doc->GetDocumentURI(),
     116           0 :                                                       &isRecursiveLoad);
     117           0 :       if (NS_FAILED(rv) || isRecursiveLoad) {
     118           0 :         NS_WARNING("Refusing to recursively load image");
     119           0 :         *aDecision = nsIContentPolicy::REJECT_TYPE;
     120             :       }
     121             :     }
     122           0 :     return NS_OK;
     123             :   }
     124             : 
     125             :   // Allow all loads for non-resource documents
     126          15 :   if (!doc->IsResourceDoc()) {
     127          15 :     return NS_OK;
     128             :   }
     129             : 
     130             :   // For resource documents, blacklist some load types
     131           0 :   if (aContentType == nsIContentPolicy::TYPE_OBJECT ||
     132           0 :       aContentType == nsIContentPolicy::TYPE_DOCUMENT ||
     133           0 :       aContentType == nsIContentPolicy::TYPE_SUBDOCUMENT ||
     134           0 :       aContentType == nsIContentPolicy::TYPE_SCRIPT ||
     135           0 :       aContentType == nsIContentPolicy::TYPE_XSLT ||
     136           0 :       aContentType == nsIContentPolicy::TYPE_FETCH ||
     137             :       aContentType == nsIContentPolicy::TYPE_WEB_MANIFEST) {
     138           0 :     *aDecision = nsIContentPolicy::REJECT_TYPE;
     139             :   }
     140             : 
     141             :   // If you add more restrictions here, make sure to check that
     142             :   // CHECK_PRINCIPAL_AND_DATA in nsContentPolicyUtils is still valid.
     143             :   // nsContentPolicyUtils may not pass all the parameters to ShouldLoad
     144             : 
     145           0 :   return NS_OK;
     146             : }
     147             : 
     148             : NS_IMETHODIMP
     149           0 : nsDataDocumentContentPolicy::ShouldProcess(uint32_t aContentType,
     150             :                                            nsIURI *aContentLocation,
     151             :                                            nsIURI *aRequestingLocation,
     152             :                                            nsISupports *aRequestingContext,
     153             :                                            const nsACString &aMimeGuess,
     154             :                                            nsISupports *aExtra,
     155             :                                            nsIPrincipal *aRequestPrincipal,
     156             :                                            int16_t *aDecision)
     157             : {
     158             :   return ShouldLoad(aContentType, aContentLocation, aRequestingLocation,
     159             :                     aRequestingContext, aMimeGuess, aExtra, aRequestPrincipal,
     160           0 :                     aDecision);
     161             : }

Generated by: LCOV version 1.13