Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/base/nsDataDocumentContentPolicy.cpp
Line
Count
Source (jump to first uncovered line)
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
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
HasFlags(nsIURI* aURI, uint32_t aURIFlags)
30
0
{
31
0
  bool hasFlags;
32
0
  nsresult rv = NS_URIChainHasFlags(aURI, aURIFlags, &hasFlags);
33
0
  return NS_SUCCEEDED(rv) && hasFlags;
34
0
}
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
nsDataDocumentContentPolicy::ShouldLoad(nsIURI *aContentLocation,
41
                                        nsILoadInfo* aLoadInfo,
42
                                        const nsACString &aMimeGuess,
43
                                        int16_t *aDecision)
44
0
{
45
0
  uint32_t contentType = aLoadInfo->GetExternalContentPolicyType();
46
0
  nsCOMPtr<nsISupports> requestingContext = aLoadInfo->GetLoadingContext();
47
0
48
0
  MOZ_ASSERT(contentType == nsContentUtils::InternalContentPolicyTypeToExternal(contentType),
49
0
             "We should only see external content policy types here.");
50
0
51
0
  *aDecision = nsIContentPolicy::ACCEPT;
52
0
  // Look for the document.  In most cases, requestingContext is a node.
53
0
  nsCOMPtr<nsIDocument> doc;
54
0
  nsCOMPtr<nsINode> node = do_QueryInterface(requestingContext);
55
0
  if (node) {
56
0
    doc = node->OwnerDoc();
57
0
  } else {
58
0
    if (nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(requestingContext)) {
59
0
      doc = window->GetDoc();
60
0
    }
61
0
  }
62
0
63
0
  // DTDs are always OK to load
64
0
  if (!doc || contentType == nsIContentPolicy::TYPE_DTD) {
65
0
    return NS_OK;
66
0
  }
67
0
68
0
  // Nothing else is OK to load for data documents
69
0
  if (doc->IsLoadedAsData()) {
70
0
    // ...but let static (print/print preview) documents to load fonts.
71
0
    if (!doc->IsStaticDocument() || contentType != nsIContentPolicy::TYPE_FONT) {
72
0
      *aDecision = nsIContentPolicy::REJECT_TYPE;
73
0
      return NS_OK;
74
0
    }
75
0
  }
76
0
77
0
  nsIDocument* docToCheckForImage = doc->GetDisplayDocument();
78
0
  if (!docToCheckForImage) {
79
0
    docToCheckForImage = doc;
80
0
  }
81
0
82
0
  if (docToCheckForImage->IsBeingUsedAsImage()) {
83
0
    // We only allow SVG images to load content from URIs that are local and
84
0
    // also satisfy one of the following conditions:
85
0
    //  - URI inherits security context, e.g. data URIs
86
0
    //   OR
87
0
    //  - URI loadable by subsumers, e.g. blob URIs
88
0
    // Any URI that doesn't meet these requirements will be rejected below.
89
0
    if (!(HasFlags(aContentLocation,
90
0
                   nsIProtocolHandler::URI_IS_LOCAL_RESOURCE) &&
91
0
          (HasFlags(aContentLocation,
92
0
                    nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT) ||
93
0
           HasFlags(aContentLocation,
94
0
                    nsIProtocolHandler::URI_LOADABLE_BY_SUBSUMERS)))) {
95
0
      *aDecision = nsIContentPolicy::REJECT_TYPE;
96
0
97
0
      // Report error, if we can.
98
0
      if (node) {
99
0
        nsIPrincipal* requestingPrincipal = node->NodePrincipal();
100
0
        RefPtr<nsIURI> principalURI;
101
0
        nsresult rv =
102
0
          requestingPrincipal->GetURI(getter_AddRefs(principalURI));
103
0
        if (NS_SUCCEEDED(rv) && principalURI) {
104
0
          nsScriptSecurityManager::ReportError(
105
0
            "ExternalDataError", principalURI, aContentLocation,
106
0
            requestingPrincipal->OriginAttributesRef().mPrivateBrowsingId > 0);
107
0
        }
108
0
      }
109
0
    } else if ((contentType == nsIContentPolicy::TYPE_IMAGE ||
110
0
                contentType == nsIContentPolicy::TYPE_IMAGESET) &&
111
0
               doc->GetDocumentURI()) {
112
0
      // Check for (& disallow) recursive image-loads
113
0
      bool isRecursiveLoad;
114
0
      nsresult rv = aContentLocation->EqualsExceptRef(doc->GetDocumentURI(),
115
0
                                                      &isRecursiveLoad);
116
0
      if (NS_FAILED(rv) || isRecursiveLoad) {
117
0
        NS_WARNING("Refusing to recursively load image");
118
0
        *aDecision = nsIContentPolicy::REJECT_TYPE;
119
0
      }
120
0
    }
121
0
    return NS_OK;
122
0
  }
123
0
124
0
  // Allow all loads for non-resource documents
125
0
  if (!doc->IsResourceDoc()) {
126
0
    return NS_OK;
127
0
  }
128
0
129
0
  // For resource documents, blacklist some load types
130
0
  if (contentType == nsIContentPolicy::TYPE_OBJECT ||
131
0
      contentType == nsIContentPolicy::TYPE_DOCUMENT ||
132
0
      contentType == nsIContentPolicy::TYPE_SUBDOCUMENT ||
133
0
      contentType == nsIContentPolicy::TYPE_SCRIPT ||
134
0
      contentType == nsIContentPolicy::TYPE_XSLT ||
135
0
      contentType == nsIContentPolicy::TYPE_FETCH ||
136
0
      contentType == nsIContentPolicy::TYPE_WEB_MANIFEST) {
137
0
    *aDecision = nsIContentPolicy::REJECT_TYPE;
138
0
  }
139
0
140
0
  // If you add more restrictions here, make sure to check that
141
0
  // CHECK_PRINCIPAL_AND_DATA in nsContentPolicyUtils is still valid.
142
0
  // nsContentPolicyUtils may not pass all the parameters to ShouldLoad
143
0
144
0
  return NS_OK;
145
0
}
146
147
NS_IMETHODIMP
148
nsDataDocumentContentPolicy::ShouldProcess(nsIURI *aContentLocation,
149
                                           nsILoadInfo *aLoadInfo,
150
                                           const nsACString &aMimeGuess,
151
                                           int16_t *aDecision)
152
0
{
153
0
  return ShouldLoad(aContentLocation, aLoadInfo, aMimeGuess, aDecision);
154
0
}