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

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: address comments Created 4 years, 6 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
161 void set_deny_xframe_options(bool deny_xframe_options) { 166 void set_deny_xframe_options(bool deny_xframe_options) {
162 deny_xframe_options_ = deny_xframe_options; 167 deny_xframe_options_ = deny_xframe_options;
163 } 168 }
164 169
165 void set_send_content_type_header(bool send_content_type_header) { 170 void set_send_content_type_header(bool send_content_type_header) {
(...skipping 15 matching lines...) Expand all
181 // Helper for Start(), to let us start asynchronously. 186 // Helper for Start(), to let us start asynchronously.
182 // (This pattern is shared by most net::URLRequestJob implementations.) 187 // (This pattern is shared by most net::URLRequestJob implementations.)
183 void StartAsync(bool allowed); 188 void StartAsync(bool allowed);
184 189
185 // Called on the UI thread to check if this request is allowed. 190 // Called on the UI thread to check if this request is allowed.
186 static void CheckStoragePartitionMatches( 191 static void CheckStoragePartitionMatches(
187 int render_process_id, 192 int render_process_id,
188 const GURL& url, 193 const GURL& url,
189 const base::WeakPtr<URLRequestChromeJob>& job); 194 const base::WeakPtr<URLRequestChromeJob>& job);
190 195
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|. 196 // 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 197 // Separate from ReadRawData so we can handle async I/O. Returns the number of
196 // bytes read. 198 // bytes read.
197 int CompleteRead(net::IOBuffer* buf, int buf_size); 199 int CompleteRead(net::IOBuffer* buf, int buf_size);
198 200
199 // The actual data we're serving. NULL until it's been fetched. 201 // The actual data we're serving. NULL until it's been fetched.
200 scoped_refptr<base::RefCountedMemory> data_; 202 scoped_refptr<base::RefCountedMemory> data_;
201 // The current offset into the data that we're handing off to our 203 // The current offset into the data that we're handing off to our
202 // callers via the Read interfaces. 204 // callers via the Read interfaces.
203 int data_offset_; 205 int data_offset_;
204 206
205 // For async reads, we keep around a pointer to the buffer that 207 // For async reads, we keep around a pointer to the buffer that
206 // we're reading into. 208 // we're reading into.
207 scoped_refptr<net::IOBuffer> pending_buf_; 209 scoped_refptr<net::IOBuffer> pending_buf_;
208 int pending_buf_size_; 210 int pending_buf_size_;
209 std::string mime_type_; 211 std::string mime_type_;
210 212
211 // If true, set a header in the response to prevent it from being cached. 213 // If true, set a header in the response to prevent it from being cached.
212 bool allow_caching_; 214 bool allow_caching_;
213 215
214 // If true, set the Content Security Policy (CSP) header. 216 // If true, set the Content Security Policy (CSP) header.
215 bool add_content_security_policy_; 217 bool add_content_security_policy_;
216 218
217 // These are used with the CSP. 219 // These are used with the CSP.
220 std::string content_security_policy_script_source_;
218 std::string content_security_policy_object_source_; 221 std::string content_security_policy_object_source_;
219 std::string content_security_policy_frame_source_; 222 std::string content_security_policy_frame_source_;
220 223
221 // If true, sets the "X-Frame-Options: DENY" header. 224 // If true, sets the "X-Frame-Options: DENY" header.
222 bool deny_xframe_options_; 225 bool deny_xframe_options_;
223 226
224 // If true, sets the "Content-Type: <mime-type>" header. 227 // If true, sets the "Content-Type: <mime-type>" header.
225 bool send_content_type_header_; 228 bool send_content_type_header_;
226 229
227 // If not empty, "Access-Control-Allow-Origin:" is set to the value of this 230 // If not empty, "Access-Control-Allow-Origin:" is set to the value of this
(...skipping 13 matching lines...) Expand all
241 244
242 URLRequestChromeJob::URLRequestChromeJob(net::URLRequest* request, 245 URLRequestChromeJob::URLRequestChromeJob(net::URLRequest* request,
243 net::NetworkDelegate* network_delegate, 246 net::NetworkDelegate* network_delegate,
244 URLDataManagerBackend* backend, 247 URLDataManagerBackend* backend,
245 bool is_incognito) 248 bool is_incognito)
246 : net::URLRequestJob(request, network_delegate), 249 : net::URLRequestJob(request, network_delegate),
247 data_offset_(0), 250 data_offset_(0),
248 pending_buf_size_(0), 251 pending_buf_size_(0),
249 allow_caching_(true), 252 allow_caching_(true),
250 add_content_security_policy_(true), 253 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), 254 deny_xframe_options_(true),
254 send_content_type_header_(false), 255 send_content_type_header_(false),
255 is_incognito_(is_incognito), 256 is_incognito_(is_incognito),
256 backend_(backend), 257 backend_(backend),
257 weak_factory_(this) { 258 weak_factory_(this) {
258 DCHECK(backend); 259 DCHECK(backend);
259 } 260 }
260 261
261 URLRequestChromeJob::~URLRequestChromeJob() { 262 URLRequestChromeJob::~URLRequestChromeJob() {
262 CHECK(!backend_->HasPendingJob(this)); 263 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 320 // 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 321 // 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. 322 // indistiguishable from other error types. Instant relies on getting a 200.
322 info->headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK"); 323 info->headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
323 324
324 // Determine the least-privileged content security policy header, if any, 325 // 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 326 // that is compatible with a given WebUI URL, and append it to the existing
326 // response headers. 327 // response headers.
327 if (add_content_security_policy_) { 328 if (add_content_security_policy_) {
328 std::string base = kChromeURLContentSecurityPolicyHeaderBase; 329 std::string base = kChromeURLContentSecurityPolicyHeaderBase;
329 base.append(RequiresUnsafeEval() ? " 'unsafe-eval'; " : "; "); 330 base.append(content_security_policy_script_source_);
330 base.append(content_security_policy_object_source_); 331 base.append(content_security_policy_object_source_);
331 base.append(content_security_policy_frame_source_); 332 base.append(content_security_policy_frame_source_);
332 info->headers->AddHeader(base); 333 info->headers->AddHeader(base);
333 } 334 }
334 335
335 if (deny_xframe_options_) 336 if (deny_xframe_options_)
336 info->headers->AddHeader(kChromeURLXFrameOptionsHeader); 337 info->headers->AddHeader(kChromeURLXFrameOptionsHeader);
337 338
338 if (!allow_caching_) 339 if (!allow_caching_)
339 info->headers->AddHeader("Cache-Control: no-cache"); 340 info->headers->AddHeader("Cache-Control: no-cache");
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 void URLRequestChromeJob::StartAsync(bool allowed) { 432 void URLRequestChromeJob::StartAsync(bool allowed) {
432 if (!request_) 433 if (!request_)
433 return; 434 return;
434 435
435 if (!allowed || !backend_->StartRequest(request_, this)) { 436 if (!allowed || !backend_->StartRequest(request_, this)) {
436 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, 437 NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
437 net::ERR_INVALID_URL)); 438 net::ERR_INVALID_URL));
438 } 439 }
439 } 440 }
440 441
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 { 442 namespace {
448 443
449 // Gets mime type for data that is available from |source| by |path|. 444 // Gets mime type for data that is available from |source| by |path|.
450 // After that, notifies |job| that mime type is available. This method 445 // After that, notifies |job| that mime type is available. This method
451 // should be called on the UI thread, but notification is performed on 446 // should be called on the UI thread, but notification is performed on
452 // the IO thread. 447 // the IO thread.
453 void GetMimeTypeOnUI(URLDataSourceImpl* source, 448 void GetMimeTypeOnUI(URLDataSourceImpl* source,
454 const std::string& path, 449 const std::string& path,
455 const base::WeakPtr<URLRequestChromeJob>& job) { 450 const base::WeakPtr<URLRequestChromeJob>& job) {
456 DCHECK_CURRENTLY_ON(BrowserThread::UI); 451 DCHECK_CURRENTLY_ON(BrowserThread::UI);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 URLToRequestPath(request->url(), &path); 624 URLToRequestPath(request->url(), &path);
630 source->source()->WillServiceRequest(request, &path); 625 source->source()->WillServiceRequest(request, &path);
631 626
632 // Save this request so we know where to send the data. 627 // Save this request so we know where to send the data.
633 RequestID request_id = next_request_id_++; 628 RequestID request_id = next_request_id_++;
634 pending_requests_.insert(std::make_pair(request_id, job)); 629 pending_requests_.insert(std::make_pair(request_id, job));
635 630
636 job->set_allow_caching(source->source()->AllowCaching()); 631 job->set_allow_caching(source->source()->AllowCaching());
637 job->set_add_content_security_policy( 632 job->set_add_content_security_policy(
638 source->source()->ShouldAddContentSecurityPolicy()); 633 source->source()->ShouldAddContentSecurityPolicy());
634 job->set_content_security_policy_script_source(
635 source->source()->GetContentSecurityPolicyScriptSrc());
639 job->set_content_security_policy_object_source( 636 job->set_content_security_policy_object_source(
640 source->source()->GetContentSecurityPolicyObjectSrc()); 637 source->source()->GetContentSecurityPolicyObjectSrc());
641 job->set_content_security_policy_frame_source( 638 job->set_content_security_policy_frame_source(
642 source->source()->GetContentSecurityPolicyFrameSrc()); 639 source->source()->GetContentSecurityPolicyFrameSrc());
643 job->set_deny_xframe_options( 640 job->set_deny_xframe_options(
644 source->source()->ShouldDenyXFrameOptions()); 641 source->source()->ShouldDenyXFrameOptions());
645 job->set_send_content_type_header( 642 job->set_send_content_type_header(
646 source->source()->ShouldServeMimeTypeAsContentTypeHeader()); 643 source->source()->ShouldServeMimeTypeAsContentTypeHeader());
647 644
648 std::string origin = GetOriginHeaderValue(request); 645 std::string origin = GetOriginHeaderValue(request);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 800
804 } // namespace 801 } // namespace
805 802
806 net::URLRequestJobFactory::ProtocolHandler* 803 net::URLRequestJobFactory::ProtocolHandler*
807 CreateDevToolsProtocolHandler(content::ResourceContext* resource_context, 804 CreateDevToolsProtocolHandler(content::ResourceContext* resource_context,
808 bool is_incognito) { 805 bool is_incognito) {
809 return new DevToolsJobFactory(resource_context, is_incognito); 806 return new DevToolsJobFactory(resource_context, is_incognito);
810 } 807 }
811 808
812 } // namespace content 809 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698