Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(516)

Side by Side Diff: content/browser/webui/url_data_manager_backend.cc

Issue 2003963004: Enable CSP on more WebUI pages (Closed) Base URL: https://chromium.googlesource.com/a/chromium/src.git@master
Patch Set: revert devtools, fix comments, split methods Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/webui/url_data_manager_backend.h" 5 #include "content/browser/webui/url_data_manager_backend.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 #include "net/url_request/url_request_error_job.h" 46 #include "net/url_request/url_request_error_job.h"
47 #include "net/url_request/url_request_job.h" 47 #include "net/url_request/url_request_job.h"
48 #include "net/url_request/url_request_job_factory.h" 48 #include "net/url_request/url_request_job_factory.h"
49 #include "url/url_util.h" 49 #include "url/url_util.h"
50 50
51 namespace content { 51 namespace content {
52 52
53 namespace { 53 namespace {
54 54
55 const char kChromeURLContentSecurityPolicyHeaderBase[] = 55 const char kChromeURLContentSecurityPolicyHeaderBase[] =
56 "Content-Security-Policy: script-src chrome://resources 'self'"; 56 "Content-Security-Policy: ";
57 57
58 const char kChromeURLXFrameOptionsHeader[] = "X-Frame-Options: DENY"; 58 const char kChromeURLXFrameOptionsHeader[] = "X-Frame-Options: DENY";
59 static const char kNetworkErrorKey[] = "netError"; 59 static const char kNetworkErrorKey[] = "netError";
60 60
61 bool SchemeIsInSchemes(const std::string& scheme, 61 bool SchemeIsInSchemes(const std::string& scheme,
62 const std::vector<std::string>& schemes) { 62 const std::vector<std::string>& schemes) {
63 return std::find(schemes.begin(), schemes.end(), scheme) != schemes.end(); 63 return std::find(schemes.begin(), schemes.end(), scheme) != schemes.end();
64 } 64 }
65 65
66 // Returns whether |url| passes some sanity checks and is a valid GURL. 66 // Returns whether |url| passes some sanity checks and is a valid GURL.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 146
147 void set_add_content_security_policy(bool add_content_security_policy) { 147 void set_add_content_security_policy(bool add_content_security_policy) {
148 add_content_security_policy_ = add_content_security_policy; 148 add_content_security_policy_ = add_content_security_policy;
149 } 149 }
150 150
151 void set_content_security_policy_object_source( 151 void set_content_security_policy_object_source(
152 const std::string& data) { 152 const std::string& data) {
153 content_security_policy_object_source_ = data; 153 content_security_policy_object_source_ = data;
154 } 154 }
155 155
156 void set_content_security_policy_script_source(
157 const std::string& data) {
158 content_security_policy_script_source_ = data;
159 }
160
156 void set_content_security_policy_frame_source( 161 void set_content_security_policy_frame_source(
157 const std::string& data) { 162 const std::string& data) {
158 content_security_policy_frame_source_ = data; 163 content_security_policy_frame_source_ = data;
159 } 164 }
160 165
166 void set_content_security_policy_style_source(
167 const std::string& data) {
168 content_security_policy_style_source_ = data;
169 }
170
171 void set_content_security_policy_image_source(
172 const std::string& data) {
173 content_security_policy_image_source_ = data;
174 }
175
161 void set_deny_xframe_options(bool deny_xframe_options) { 176 void set_deny_xframe_options(bool deny_xframe_options) {
162 deny_xframe_options_ = deny_xframe_options; 177 deny_xframe_options_ = deny_xframe_options;
163 } 178 }
164 179
165 void set_send_content_type_header(bool send_content_type_header) { 180 void set_send_content_type_header(bool send_content_type_header) {
166 send_content_type_header_ = send_content_type_header; 181 send_content_type_header_ = send_content_type_header;
167 } 182 }
168 183
169 void set_access_control_allow_origin(const std::string& value) { 184 void set_access_control_allow_origin(const std::string& value) {
170 access_control_allow_origin_ = value; 185 access_control_allow_origin_ = value;
(...skipping 10 matching lines...) Expand all
181 // Helper for Start(), to let us start asynchronously. 196 // Helper for Start(), to let us start asynchronously.
182 // (This pattern is shared by most net::URLRequestJob implementations.) 197 // (This pattern is shared by most net::URLRequestJob implementations.)
183 void StartAsync(bool allowed); 198 void StartAsync(bool allowed);
184 199
185 // Called on the UI thread to check if this request is allowed. 200 // Called on the UI thread to check if this request is allowed.
186 static void CheckStoragePartitionMatches( 201 static void CheckStoragePartitionMatches(
187 int render_process_id, 202 int render_process_id,
188 const GURL& url, 203 const GURL& url,
189 const base::WeakPtr<URLRequestChromeJob>& job); 204 const base::WeakPtr<URLRequestChromeJob>& job);
190 205
191 // Specific resources require unsafe-eval in the Content Security Policy.
192 bool RequiresUnsafeEval() const;
193
194 // Do the actual copy from data_ (the data we're serving) into |buf|. 206 // Do the actual copy from data_ (the data we're serving) into |buf|.
195 // Separate from ReadRawData so we can handle async I/O. Returns the number of 207 // Separate from ReadRawData so we can handle async I/O. Returns the number of
196 // bytes read. 208 // bytes read.
197 int CompleteRead(net::IOBuffer* buf, int buf_size); 209 int CompleteRead(net::IOBuffer* buf, int buf_size);
198 210
199 // The actual data we're serving. NULL until it's been fetched. 211 // The actual data we're serving. NULL until it's been fetched.
200 scoped_refptr<base::RefCountedMemory> data_; 212 scoped_refptr<base::RefCountedMemory> data_;
201 // The current offset into the data that we're handing off to our 213 // The current offset into the data that we're handing off to our
202 // callers via the Read interfaces. 214 // callers via the Read interfaces.
203 int data_offset_; 215 int data_offset_;
204 216
205 // For async reads, we keep around a pointer to the buffer that 217 // For async reads, we keep around a pointer to the buffer that
206 // we're reading into. 218 // we're reading into.
207 scoped_refptr<net::IOBuffer> pending_buf_; 219 scoped_refptr<net::IOBuffer> pending_buf_;
208 int pending_buf_size_; 220 int pending_buf_size_;
209 std::string mime_type_; 221 std::string mime_type_;
210 222
211 // If true, set a header in the response to prevent it from being cached. 223 // If true, set a header in the response to prevent it from being cached.
212 bool allow_caching_; 224 bool allow_caching_;
213 225
214 // If true, set the Content Security Policy (CSP) header. 226 // If true, set the Content Security Policy (CSP) header.
215 bool add_content_security_policy_; 227 bool add_content_security_policy_;
216 228
217 // These are used with the CSP. 229 // These are used with the CSP.
230 std::string content_security_policy_script_source_;
218 std::string content_security_policy_object_source_; 231 std::string content_security_policy_object_source_;
219 std::string content_security_policy_frame_source_; 232 std::string content_security_policy_frame_source_;
233 std::string content_security_policy_style_source_;
234 std::string content_security_policy_image_source_;
220 235
221 // If true, sets the "X-Frame-Options: DENY" header. 236 // If true, sets the "X-Frame-Options: DENY" header.
222 bool deny_xframe_options_; 237 bool deny_xframe_options_;
223 238
224 // If true, sets the "Content-Type: <mime-type>" header. 239 // If true, sets the "Content-Type: <mime-type>" header.
225 bool send_content_type_header_; 240 bool send_content_type_header_;
226 241
227 // If not empty, "Access-Control-Allow-Origin:" is set to the value of this 242 // If not empty, "Access-Control-Allow-Origin:" is set to the value of this
228 // string. 243 // string.
229 std::string access_control_allow_origin_; 244 std::string access_control_allow_origin_;
(...skipping 11 matching lines...) Expand all
241 256
242 URLRequestChromeJob::URLRequestChromeJob(net::URLRequest* request, 257 URLRequestChromeJob::URLRequestChromeJob(net::URLRequest* request,
243 net::NetworkDelegate* network_delegate, 258 net::NetworkDelegate* network_delegate,
244 URLDataManagerBackend* backend, 259 URLDataManagerBackend* backend,
245 bool is_incognito) 260 bool is_incognito)
246 : net::URLRequestJob(request, network_delegate), 261 : net::URLRequestJob(request, network_delegate),
247 data_offset_(0), 262 data_offset_(0),
248 pending_buf_size_(0), 263 pending_buf_size_(0),
249 allow_caching_(true), 264 allow_caching_(true),
250 add_content_security_policy_(true), 265 add_content_security_policy_(true),
251 content_security_policy_object_source_("object-src 'none';"),
252 content_security_policy_frame_source_("frame-src 'none';"),
253 deny_xframe_options_(true), 266 deny_xframe_options_(true),
254 send_content_type_header_(false), 267 send_content_type_header_(false),
255 is_incognito_(is_incognito), 268 is_incognito_(is_incognito),
256 backend_(backend), 269 backend_(backend),
257 weak_factory_(this) { 270 weak_factory_(this) {
258 DCHECK(backend); 271 DCHECK(backend);
259 } 272 }
260 273
261 URLRequestChromeJob::~URLRequestChromeJob() { 274 URLRequestChromeJob::~URLRequestChromeJob() {
262 CHECK(!backend_->HasPendingJob(this)); 275 CHECK(!backend_->HasPendingJob(this));
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 // Set the headers so that requests serviced by ChromeURLDataManager return a 332 // Set the headers so that requests serviced by ChromeURLDataManager return a
320 // status code of 200. Without this they return a 0, which makes the status 333 // status code of 200. Without this they return a 0, which makes the status
321 // indistiguishable from other error types. Instant relies on getting a 200. 334 // indistiguishable from other error types. Instant relies on getting a 200.
322 info->headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK"); 335 info->headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
323 336
324 // Determine the least-privileged content security policy header, if any, 337 // Determine the least-privileged content security policy header, if any,
325 // that is compatible with a given WebUI URL, and append it to the existing 338 // that is compatible with a given WebUI URL, and append it to the existing
326 // response headers. 339 // response headers.
327 if (add_content_security_policy_) { 340 if (add_content_security_policy_) {
328 std::string base = kChromeURLContentSecurityPolicyHeaderBase; 341 std::string base = kChromeURLContentSecurityPolicyHeaderBase;
329 base.append(RequiresUnsafeEval() ? " 'unsafe-eval'; " : "; "); 342 base.append(content_security_policy_script_source_);
330 base.append(content_security_policy_object_source_); 343 base.append(content_security_policy_object_source_);
331 base.append(content_security_policy_frame_source_); 344 base.append(content_security_policy_frame_source_);
345 base.append(content_security_policy_style_source_);
346 base.append(content_security_policy_image_source_);
332 info->headers->AddHeader(base); 347 info->headers->AddHeader(base);
333 } 348 }
334 349
335 if (deny_xframe_options_) 350 if (deny_xframe_options_)
336 info->headers->AddHeader(kChromeURLXFrameOptionsHeader); 351 info->headers->AddHeader(kChromeURLXFrameOptionsHeader);
337 352
338 if (!allow_caching_) 353 if (!allow_caching_)
339 info->headers->AddHeader("Cache-Control: no-cache"); 354 info->headers->AddHeader("Cache-Control: no-cache");
340 355
341 if (send_content_type_header_ && !mime_type_.empty()) { 356 if (send_content_type_header_ && !mime_type_.empty()) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 void URLRequestChromeJob::StartAsync(bool allowed) { 446 void URLRequestChromeJob::StartAsync(bool allowed) {
432 if (!request_) 447 if (!request_)
433 return; 448 return;
434 449
435 if (!allowed || !backend_->StartRequest(request_, this)) { 450 if (!allowed || !backend_->StartRequest(request_, this)) {
436 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, 451 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
437 net::ERR_INVALID_URL)); 452 net::ERR_INVALID_URL));
438 } 453 }
439 } 454 }
440 455
441 // TODO(tsepez,mfoltz): Refine this method when tests have been fixed to not use
442 // eval()/new Function(). http://crbug.com/525224
443 bool URLRequestChromeJob::RequiresUnsafeEval() const {
444 return true;
445 }
446
447 namespace { 456 namespace {
448 457
449 // Gets mime type for data that is available from |source| by |path|. 458 // Gets mime type for data that is available from |source| by |path|.
450 // After that, notifies |job| that mime type is available. This method 459 // After that, notifies |job| that mime type is available. This method
451 // should be called on the UI thread, but notification is performed on 460 // should be called on the UI thread, but notification is performed on
452 // the IO thread. 461 // the IO thread.
453 void GetMimeTypeOnUI(URLDataSourceImpl* source, 462 void GetMimeTypeOnUI(URLDataSourceImpl* source,
454 const std::string& path, 463 const std::string& path,
455 const base::WeakPtr<URLRequestChromeJob>& job) { 464 const base::WeakPtr<URLRequestChromeJob>& job) {
456 DCHECK_CURRENTLY_ON(BrowserThread::UI); 465 DCHECK_CURRENTLY_ON(BrowserThread::UI);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 URLToRequestPath(request->url(), &path); 638 URLToRequestPath(request->url(), &path);
630 source->source()->WillServiceRequest(request, &path); 639 source->source()->WillServiceRequest(request, &path);
631 640
632 // Save this request so we know where to send the data. 641 // Save this request so we know where to send the data.
633 RequestID request_id = next_request_id_++; 642 RequestID request_id = next_request_id_++;
634 pending_requests_.insert(std::make_pair(request_id, job)); 643 pending_requests_.insert(std::make_pair(request_id, job));
635 644
636 job->set_allow_caching(source->source()->AllowCaching()); 645 job->set_allow_caching(source->source()->AllowCaching());
637 job->set_add_content_security_policy( 646 job->set_add_content_security_policy(
638 source->source()->ShouldAddContentSecurityPolicy()); 647 source->source()->ShouldAddContentSecurityPolicy());
648 job->set_content_security_policy_script_source(
649 source->source()->GetContentSecurityPolicyScriptSrc());
639 job->set_content_security_policy_object_source( 650 job->set_content_security_policy_object_source(
640 source->source()->GetContentSecurityPolicyObjectSrc()); 651 source->source()->GetContentSecurityPolicyObjectSrc());
641 job->set_content_security_policy_frame_source( 652 job->set_content_security_policy_frame_source(
642 source->source()->GetContentSecurityPolicyFrameSrc()); 653 source->source()->GetContentSecurityPolicyFrameSrc());
654 job->set_content_security_policy_style_source(
655 source->source()->GetContentSecurityPolicyStyleSrc());
656 job->set_content_security_policy_image_source(
657 source->source()->GetContentSecurityPolicyImgSrc());
643 job->set_deny_xframe_options( 658 job->set_deny_xframe_options(
644 source->source()->ShouldDenyXFrameOptions()); 659 source->source()->ShouldDenyXFrameOptions());
645 job->set_send_content_type_header( 660 job->set_send_content_type_header(
646 source->source()->ShouldServeMimeTypeAsContentTypeHeader()); 661 source->source()->ShouldServeMimeTypeAsContentTypeHeader());
647 662
648 std::string origin = GetOriginHeaderValue(request); 663 std::string origin = GetOriginHeaderValue(request);
649 if (!origin.empty()) { 664 if (!origin.empty()) {
650 std::string header = 665 std::string header =
651 source->source()->GetAccessControlAllowOriginForOrigin(origin); 666 source->source()->GetAccessControlAllowOriginForOrigin(origin);
652 DCHECK(header.empty() || header == origin || header == "*" || 667 DCHECK(header.empty() || header == origin || header == "*" ||
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 818
804 } // namespace 819 } // namespace
805 820
806 net::URLRequestJobFactory::ProtocolHandler* 821 net::URLRequestJobFactory::ProtocolHandler*
807 CreateDevToolsProtocolHandler(content::ResourceContext* resource_context, 822 CreateDevToolsProtocolHandler(content::ResourceContext* resource_context,
808 bool is_incognito) { 823 bool is_incognito) {
809 return new DevToolsJobFactory(resource_context, is_incognito); 824 return new DevToolsJobFactory(resource_context, is_incognito);
810 } 825 }
811 826
812 } // namespace content 827 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698