Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/clients/manager/ClientValidation.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
#include "ClientValidation.h"
8
9
#include "ClientPrefs.h"
10
#include "mozilla/net/MozURL.h"
11
12
namespace mozilla {
13
namespace dom {
14
15
using mozilla::ipc::ContentPrincipalInfo;
16
using mozilla::ipc::PrincipalInfo;
17
using mozilla::net::MozURL;
18
19
bool
20
ClientIsValidPrincipalInfo(const PrincipalInfo& aPrincipalInfo)
21
0
{
22
0
  // Ideally we would verify that the source process has permission to
23
0
  // create a window or worker with the given principal, but we don't
24
0
  // currently have any such restriction in place.  Instead, at least
25
0
  // verify the PrincipalInfo is an expected type and has a parsable
26
0
  // origin/spec.
27
0
  switch (aPrincipalInfo.type()) {
28
0
    // Any system and null principal is acceptable.
29
0
    case PrincipalInfo::TSystemPrincipalInfo:
30
0
    case PrincipalInfo::TNullPrincipalInfo:
31
0
    {
32
0
      return true;
33
0
    }
34
0
35
0
    // Validate content principals to ensure that the origin and spec are sane.
36
0
    case PrincipalInfo::TContentPrincipalInfo:
37
0
    {
38
0
      const ContentPrincipalInfo& content =
39
0
       aPrincipalInfo.get_ContentPrincipalInfo();
40
0
41
0
      // Verify the principal spec parses.
42
0
      RefPtr<MozURL> specURL;
43
0
      nsresult rv = MozURL::Init(getter_AddRefs(specURL), content.spec());
44
0
      NS_ENSURE_SUCCESS(rv, false);
45
0
46
0
      // Verify the principal originNoSuffix parses.
47
0
      RefPtr<MozURL> originURL;
48
0
      rv = MozURL::Init(getter_AddRefs(originURL), content.originNoSuffix());
49
0
      NS_ENSURE_SUCCESS(rv, false);
50
0
51
0
      nsAutoCString originOrigin;
52
0
      originURL->Origin(originOrigin);
53
0
54
0
      nsAutoCString specOrigin;
55
0
      specURL->Origin(specOrigin);
56
0
57
0
      // For now require Clients to have a principal where both its
58
0
      // originNoSuffix and spec have the same origin.  This will
59
0
      // exclude a variety of unusual combinations within the browser
60
0
      // but its adequate for the features need to support right now.
61
0
      // If necessary we could expand this function to handle more
62
0
      // cases in the future.
63
0
      return specOrigin == originOrigin;
64
0
    }
65
0
    default:
66
0
    {
67
0
      break;
68
0
    }
69
0
  }
70
0
71
0
  // Windows and workers should not have expanded URLs, etc.
72
0
  return false;
73
0
}
74
75
bool
76
ClientIsValidCreationURL(const PrincipalInfo& aPrincipalInfo,
77
                         const nsACString& aURL)
78
0
{
79
0
  RefPtr<MozURL> url;
80
0
  nsresult rv = MozURL::Init(getter_AddRefs(url), aURL);
81
0
  NS_ENSURE_SUCCESS(rv, false);
82
0
83
0
  switch (aPrincipalInfo.type()) {
84
0
    case PrincipalInfo::TContentPrincipalInfo:
85
0
    {
86
0
      // Any origin can create an about:blank or about:srcdoc Client.
87
0
      if (aURL.LowerCaseEqualsLiteral("about:blank") ||
88
0
          aURL.LowerCaseEqualsLiteral("about:srcdoc")) {
89
0
        return true;
90
0
      }
91
0
92
0
      const ContentPrincipalInfo& content =
93
0
        aPrincipalInfo.get_ContentPrincipalInfo();
94
0
95
0
      // Parse the principal origin URL as well.  This ensures any MozURL
96
0
      // parser issues effect both URLs equally.
97
0
      RefPtr<MozURL> principalURL;
98
0
      rv = MozURL::Init(getter_AddRefs(principalURL), content.originNoSuffix());
99
0
      NS_ENSURE_SUCCESS(rv, false);
100
0
101
0
      nsAutoCString origin;
102
0
      url->Origin(origin);
103
0
104
0
      nsAutoCString principalOrigin;
105
0
      principalURL->Origin(principalOrigin);
106
0
107
0
      // The vast majority of sites should simply result in the same principal
108
0
      // and URL origin.
109
0
      if (principalOrigin == origin) {
110
0
        return true;
111
0
      }
112
0
113
0
      nsDependentCSubstring scheme = url->Scheme();
114
0
115
0
      // Generally any origin can also open javascript: windows and workers.
116
0
      if (scheme.LowerCaseEqualsLiteral("javascript")) {
117
0
        return true;
118
0
      }
119
0
120
0
      // We have some tests that use data: URL windows without an opaque
121
0
      // origin.  This should only happen when a pref is set.
122
0
      if (!ClientPrefsGetDataURLUniqueOpaqueOrigin() &&
123
0
          scheme.LowerCaseEqualsLiteral("data")) {
124
0
        return true;
125
0
      }
126
0
127
0
      // Otherwise don't support this URL type in the clients sub-system for
128
0
      // now.  This will exclude a variety of internal browser clients, but
129
0
      // currently we don't need to support those.  This function can be
130
0
      // expanded to handle more cases as necessary.
131
0
      return false;
132
0
    }
133
0
    case PrincipalInfo::TSystemPrincipalInfo:
134
0
    {
135
0
      nsDependentCSubstring scheme = url->Scheme();
136
0
137
0
      // While many types of documents can be created with a system principal,
138
0
      // there are only a few that can reasonably become windows.  We attempt
139
0
      // to validate the list of known cases here with a simple scheme check.
140
0
      return scheme.LowerCaseEqualsLiteral("about") ||
141
0
             scheme.LowerCaseEqualsLiteral("chrome") ||
142
0
             scheme.LowerCaseEqualsLiteral("resource") ||
143
0
             scheme.LowerCaseEqualsLiteral("blob") ||
144
0
             scheme.LowerCaseEqualsLiteral("javascript") ||
145
0
             scheme.LowerCaseEqualsLiteral("view-source") ||
146
0
147
0
             (!ClientPrefsGetDataURLUniqueOpaqueOrigin() &&
148
0
              scheme.LowerCaseEqualsLiteral("data"));
149
0
    }
150
0
    case PrincipalInfo::TNullPrincipalInfo:
151
0
    {
152
0
      // A wide variety of clients can have a null principal.  For example,
153
0
      // sandboxed iframes can have a normal content URL.  For now allow
154
0
      // any parsable URL for null principals.  This is relatively safe since
155
0
      // null principals have unique origins and won't most ClientManagerService
156
0
      // queries anyway.
157
0
      return true;
158
0
    }
159
0
    default:
160
0
    {
161
0
      break;
162
0
    }
163
0
  }
164
0
165
0
  // Clients (windows/workers) should never have an expanded principal type.
166
0
  return false;
167
0
}
168
169
} // namespace dom
170
} // namespace mozilla