1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/url_loader_factory_params_helper.h"
6
7 #include "base/command_line.h"
8 #include "base/optional.h"
9 #include "content/browser/child_process_security_policy_impl.h"
10 #include "content/browser/frame_host/render_frame_host_impl.h"
11 #include "content/browser/site_instance_impl.h"
12 #include "content/public/browser/content_browser_client.h"
13 #include "content/public/browser/render_process_host.h"
14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/common/content_client.h"
16 #include "content/public/common/content_switches.h"
17 #include "content/public/common/url_constants.h"
18 #include "content/public/common/web_preferences.h"
19 #include "services/network/public/mojom/cross_origin_embedder_policy.mojom.h"
20 #include "services/network/public/mojom/network_context.mojom.h"
21
22 namespace content {
23
24 namespace {
25
26 // Helper used by the public URLLoaderFactoryParamsHelper::Create... methods.
27 //
28 // |origin| is the origin that will use the URLLoaderFactory.
29 // |origin| is typically the same as the origin in
30 // network::ResourceRequest::request_initiator, except when
31 // |is_for_isolated_world|. See also the doc comment for
32 // extensions::URLLoaderFactoryManager::CreateFactory.
33 //
34 // TODO(kinuko, lukasza): https://crbug.com/891872: Make
35 // |request_initiator_site_lock| non-optional, once
36 // URLLoaderFactoryParamsHelper::CreateForRendererProcess is removed.
CreateParams(RenderProcessHost * process,const url::Origin & origin,const base::Optional<url::Origin> & request_initiator_site_lock,const base::Optional<url::Origin> & top_frame_origin,bool is_trusted,const base::Optional<base::UnguessableToken> & top_frame_token,const base::Optional<net::NetworkIsolationKey> & network_isolation_key,network::mojom::ClientSecurityStatePtr client_security_state,mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter> coep_reporter,bool allow_universal_access_from_file_urls,bool is_for_isolated_world)37 network::mojom::URLLoaderFactoryParamsPtr CreateParams(
38 RenderProcessHost* process,
39 const url::Origin& origin,
40 const base::Optional<url::Origin>& request_initiator_site_lock,
41 const base::Optional<url::Origin>& top_frame_origin,
42 bool is_trusted,
43 const base::Optional<base::UnguessableToken>& top_frame_token,
44 const base::Optional<net::NetworkIsolationKey>& network_isolation_key,
45 network::mojom::ClientSecurityStatePtr client_security_state,
46 mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter>
47 coep_reporter,
48 bool allow_universal_access_from_file_urls,
49 bool is_for_isolated_world) {
50 DCHECK(process);
51
52 // "chrome-guest://..." is never used as a main or isolated world origin.
53 DCHECK_NE(kGuestScheme, origin.scheme());
54 DCHECK(!request_initiator_site_lock.has_value() ||
55 request_initiator_site_lock->scheme() != kGuestScheme);
56
57 network::mojom::URLLoaderFactoryParamsPtr params =
58 network::mojom::URLLoaderFactoryParams::New();
59
60 params->process_id = process->GetID();
61 params->request_initiator_site_lock = request_initiator_site_lock;
62 params->top_frame_origin = top_frame_origin;
63
64 params->is_trusted = is_trusted;
65 params->top_frame_id = top_frame_token;
66 params->network_isolation_key = network_isolation_key;
67
68 params->disable_web_security =
69 base::CommandLine::ForCurrentProcess()->HasSwitch(
70 switches::kDisableWebSecurity);
71 params->client_security_state = std::move(client_security_state);
72 params->coep_reporter = std::move(coep_reporter);
73
74 if (params->disable_web_security) {
75 // --disable-web-security also disables Cross-Origin Read Blocking (CORB).
76 params->is_corb_enabled = false;
77 } else if (allow_universal_access_from_file_urls &&
78 origin.scheme() == url::kFileScheme) {
79 // allow_universal_access_from_file_urls disables CORB (via
80 // |is_corb_enabled|) and CORS (via |disable_web_security|) for requests
81 // made from a file: |origin|.
82 params->is_corb_enabled = false;
83 params->disable_web_security = true;
84 } else {
85 params->is_corb_enabled = true;
86 }
87
88 GetContentClient()->browser()->OverrideURLLoaderFactoryParams(
89 process->GetBrowserContext(), origin, is_for_isolated_world,
90 params.get());
91
92 return params;
93 }
94
95 } // namespace
96
97 // static
98 network::mojom::URLLoaderFactoryParamsPtr
CreateForFrame(RenderFrameHostImpl * frame,const url::Origin & frame_origin,network::mojom::ClientSecurityStatePtr client_security_state,mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter> coep_reporter,RenderProcessHost * process)99 URLLoaderFactoryParamsHelper::CreateForFrame(
100 RenderFrameHostImpl* frame,
101 const url::Origin& frame_origin,
102 network::mojom::ClientSecurityStatePtr client_security_state,
103 mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter>
104 coep_reporter,
105 RenderProcessHost* process) {
106 return CreateParams(
107 process,
108 frame_origin, // origin
109 frame_origin, // request_initiator_site_lock
110 // top_frame_origin
111 frame->ComputeTopFrameOrigin(frame_origin),
112 false, // is_trusted
113 frame->GetTopFrameToken(), frame->GetNetworkIsolationKey(),
114 std::move(client_security_state), std::move(coep_reporter),
115 frame->GetRenderViewHost()
116 ->GetWebkitPreferences()
117 .allow_universal_access_from_file_urls,
118 false); // is_for_isolated_world
119 }
120
121 // static
122 network::mojom::URLLoaderFactoryParamsPtr
CreateForIsolatedWorld(RenderFrameHostImpl * frame,const url::Origin & isolated_world_origin,const url::Origin & main_world_origin,network::mojom::ClientSecurityStatePtr client_security_state)123 URLLoaderFactoryParamsHelper::CreateForIsolatedWorld(
124 RenderFrameHostImpl* frame,
125 const url::Origin& isolated_world_origin,
126 const url::Origin& main_world_origin,
127 network::mojom::ClientSecurityStatePtr client_security_state) {
128 return CreateParams(frame->GetProcess(),
129 isolated_world_origin, // origin
130 main_world_origin, // request_initiator_site_lock
131 base::nullopt, // top_frame_origin
132 false, // is_trusted
133 frame->GetTopFrameToken(),
134 frame->GetNetworkIsolationKey(),
135 std::move(client_security_state),
136 mojo::NullRemote(), // coep_reporter
137 frame->GetRenderViewHost()
138 ->GetWebkitPreferences()
139 .allow_universal_access_from_file_urls,
140 true); // is_for_isolated_world
141 }
142
143 network::mojom::URLLoaderFactoryParamsPtr
CreateForPrefetch(RenderFrameHostImpl * frame,network::mojom::ClientSecurityStatePtr client_security_state)144 URLLoaderFactoryParamsHelper::CreateForPrefetch(
145 RenderFrameHostImpl* frame,
146 network::mojom::ClientSecurityStatePtr client_security_state) {
147 // The factory client |is_trusted| to control the |network_isolation_key| in
148 // each separate request (rather than forcing the client to use the key
149 // specified in URLLoaderFactoryParams).
150 const url::Origin& frame_origin = frame->GetLastCommittedOrigin();
151 return CreateParams(frame->GetProcess(),
152 frame_origin, // origin
153 frame_origin, // request_initiator_site_lock
154 // top_frame_origin
155 frame->ComputeTopFrameOrigin(frame_origin),
156 true, // is_trusted
157 frame->GetTopFrameToken(),
158 base::nullopt, // network_isolation_key
159 std::move(client_security_state),
160 mojo::NullRemote(), // coep_reporter
161 frame->GetRenderViewHost()
162 ->GetWebkitPreferences()
163 .allow_universal_access_from_file_urls,
164 false); // is_for_isolated_world
165 }
166
167 // static
168 network::mojom::URLLoaderFactoryParamsPtr
CreateForWorker(RenderProcessHost * process,const url::Origin & request_initiator,const net::NetworkIsolationKey & network_isolation_key,mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter> coep_reporter)169 URLLoaderFactoryParamsHelper::CreateForWorker(
170 RenderProcessHost* process,
171 const url::Origin& request_initiator,
172 const net::NetworkIsolationKey& network_isolation_key,
173 mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter>
174 coep_reporter) {
175 return CreateParams(process,
176 request_initiator, // origin
177 request_initiator, // request_initiator_site_lock
178 base::nullopt, // top_frame_origin
179 false, // is_trusted
180 base::nullopt, // top_frame_token
181 network_isolation_key,
182 nullptr, // client_security_state
183 std::move(coep_reporter),
184 false, // allow_universal_access_from_file_urls
185 false); // is_for_isolated_world
186 }
187
188 // static
189 network::mojom::URLLoaderFactoryParamsPtr
CreateForRendererProcess(RenderProcessHost * process)190 URLLoaderFactoryParamsHelper::CreateForRendererProcess(
191 RenderProcessHost* process) {
192 // Attempt to use the process lock as |request_initiator_site_lock|.
193 base::Optional<url::Origin> request_initiator_site_lock;
194 auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
195 GURL process_lock = policy->GetOriginLock(process->GetID());
196 if (process_lock.is_valid()) {
197 request_initiator_site_lock =
198 SiteInstanceImpl::GetRequestInitiatorSiteLock(process_lock);
199 }
200
201 // Since this function is about to get deprecated (crbug.com/891872), it
202 // should be fine to not add support for network isolation thus sending empty
203 // key.
204 //
205 // We may not be able to allow powerful APIs such as memory measurement APIs
206 // (see https://crbug.com/887967) without removing this call.
207 base::Optional<net::NetworkIsolationKey> network_isolation_key =
208 base::nullopt;
209 base::Optional<base::UnguessableToken> top_frame_token = base::nullopt;
210
211 return CreateParams(
212 process,
213 url::Origin(), // origin
214 request_initiator_site_lock, // request_initiator_site_lock
215 base::nullopt, // top_frame_origin
216 false, // is_trusted
217 top_frame_token, network_isolation_key,
218 nullptr, // client_security_state
219 mojo::NullRemote(), // coep_reporter
220 false, // allow_universal_access_from_file_urls
221 false); // is_for_isolated_world
222 }
223
224 } // namespace content
225