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

Side by Side Diff: content/browser/child_process_security_policy_impl.cc

Issue 2385553002: Revert of Lock down the registration of blob:chrome-extension:// URLs (Closed)
Patch Set: Created 4 years, 2 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/child_process_security_policy_impl.h" 5 #include "content/browser/child_process_security_policy_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 void RevokeReadRawCookies() { 195 void RevokeReadRawCookies() {
196 can_read_raw_cookies_ = false; 196 can_read_raw_cookies_ = false;
197 } 197 }
198 198
199 void GrantPermissionForMidiSysEx() { 199 void GrantPermissionForMidiSysEx() {
200 can_send_midi_sysex_ = true; 200 can_send_midi_sysex_ = true;
201 } 201 }
202 202
203 // Determine whether permission has been granted to commit |url|. 203 // Determine whether permission has been granted to commit |url|.
204 bool CanCommitURL(const GURL& url) { 204 bool CanCommitURL(const GURL& url) {
205 DCHECK(!url.SchemeIsBlob() && !url.SchemeIsFileSystem())
206 << "inner_url extraction should be done already.";
207 // Having permission to a scheme implies permission to all of its URLs. 205 // Having permission to a scheme implies permission to all of its URLs.
208 SchemeMap::const_iterator scheme_judgment( 206 SchemeMap::const_iterator scheme_judgment(
209 scheme_policy_.find(url.scheme())); 207 scheme_policy_.find(url.scheme()));
210 if (scheme_judgment != scheme_policy_.end()) 208 if (scheme_judgment != scheme_policy_.end())
211 return scheme_judgment->second; 209 return scheme_judgment->second;
212 210
213 // Otherwise, check for permission for specific origin. 211 // Otherwise, check for permission for specific origin.
214 if (base::ContainsKey(origin_set_, url::Origin(url))) 212 if (base::ContainsKey(origin_set_, url::Origin(url)))
215 return true; 213 return true;
216 214
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 DISALLOW_COPY_AND_ASSIGN(SecurityState); 319 DISALLOW_COPY_AND_ASSIGN(SecurityState);
322 }; 320 };
323 321
324 ChildProcessSecurityPolicyImpl::ChildProcessSecurityPolicyImpl() { 322 ChildProcessSecurityPolicyImpl::ChildProcessSecurityPolicyImpl() {
325 // We know about these schemes and believe them to be safe. 323 // We know about these schemes and believe them to be safe.
326 RegisterWebSafeScheme(url::kHttpScheme); 324 RegisterWebSafeScheme(url::kHttpScheme);
327 RegisterWebSafeScheme(url::kHttpsScheme); 325 RegisterWebSafeScheme(url::kHttpsScheme);
328 RegisterWebSafeScheme(url::kFtpScheme); 326 RegisterWebSafeScheme(url::kFtpScheme);
329 RegisterWebSafeScheme(url::kDataScheme); 327 RegisterWebSafeScheme(url::kDataScheme);
330 RegisterWebSafeScheme("feed"); 328 RegisterWebSafeScheme("feed");
331
332 // TODO(nick): https://crbug.com/651534 blob: and filesystem: schemes embed
333 // other origins, so we should not treat them as web safe. Remove callers of
334 // IsWebSafeScheme(), and then eliminate the next two lines.
335 RegisterWebSafeScheme(url::kBlobScheme); 329 RegisterWebSafeScheme(url::kBlobScheme);
336 RegisterWebSafeScheme(url::kFileSystemScheme); 330 RegisterWebSafeScheme(url::kFileSystemScheme);
337 331
338 // We know about the following pseudo schemes and treat them specially. 332 // We know about the following pseudo schemes and treat them specially.
339 RegisterPseudoScheme(url::kAboutScheme); 333 RegisterPseudoScheme(url::kAboutScheme);
340 RegisterPseudoScheme(url::kJavaScriptScheme); 334 RegisterPseudoScheme(url::kJavaScriptScheme);
341 RegisterPseudoScheme(kViewSourceScheme); 335 RegisterPseudoScheme(kViewSourceScheme);
342 RegisterPseudoScheme(kHttpSuboriginScheme); 336 RegisterPseudoScheme(kHttpSuboriginScheme);
343 RegisterPseudoScheme(kHttpsSuboriginScheme); 337 RegisterPseudoScheme(kHttpsSuboriginScheme);
344 } 338 }
345 339
346 ChildProcessSecurityPolicyImpl::~ChildProcessSecurityPolicyImpl() { 340 ChildProcessSecurityPolicyImpl::~ChildProcessSecurityPolicyImpl() {
341 web_safe_schemes_.clear();
342 pseudo_schemes_.clear();
343 security_state_.clear();
347 } 344 }
348 345
349 // static 346 // static
350 ChildProcessSecurityPolicy* ChildProcessSecurityPolicy::GetInstance() { 347 ChildProcessSecurityPolicy* ChildProcessSecurityPolicy::GetInstance() {
351 return ChildProcessSecurityPolicyImpl::GetInstance(); 348 return ChildProcessSecurityPolicyImpl::GetInstance();
352 } 349 }
353 350
354 ChildProcessSecurityPolicyImpl* ChildProcessSecurityPolicyImpl::GetInstance() { 351 ChildProcessSecurityPolicyImpl* ChildProcessSecurityPolicyImpl::GetInstance() {
355 return base::Singleton<ChildProcessSecurityPolicyImpl>::get(); 352 return base::Singleton<ChildProcessSecurityPolicyImpl>::get();
356 } 353 }
(...skipping 12 matching lines...) Expand all
369 366
370 void ChildProcessSecurityPolicyImpl::Remove(int child_id) { 367 void ChildProcessSecurityPolicyImpl::Remove(int child_id) {
371 base::AutoLock lock(lock_); 368 base::AutoLock lock(lock_);
372 security_state_.erase(child_id); 369 security_state_.erase(child_id);
373 worker_map_.erase(child_id); 370 worker_map_.erase(child_id);
374 } 371 }
375 372
376 void ChildProcessSecurityPolicyImpl::RegisterWebSafeScheme( 373 void ChildProcessSecurityPolicyImpl::RegisterWebSafeScheme(
377 const std::string& scheme) { 374 const std::string& scheme) {
378 base::AutoLock lock(lock_); 375 base::AutoLock lock(lock_);
379 DCHECK_EQ(0U, schemes_okay_to_request_in_any_process_.count(scheme)) 376 DCHECK_EQ(0U, web_safe_schemes_.count(scheme)) << "Add schemes at most once.";
380 << "Add schemes at most once.";
381 DCHECK_EQ(0U, pseudo_schemes_.count(scheme)) 377 DCHECK_EQ(0U, pseudo_schemes_.count(scheme))
382 << "Web-safe implies not pseudo."; 378 << "Web-safe implies not pseudo.";
383 379
384 schemes_okay_to_request_in_any_process_.insert(scheme); 380 web_safe_schemes_.insert(scheme);
385 schemes_okay_to_commit_in_any_process_.insert(scheme);
386 }
387
388 void ChildProcessSecurityPolicyImpl::RegisterWebSafeIsolatedScheme(
389 const std::string& scheme,
390 bool always_allow_in_origin_headers) {
391 base::AutoLock lock(lock_);
392 DCHECK_EQ(0U, schemes_okay_to_request_in_any_process_.count(scheme))
393 << "Add schemes at most once.";
394 DCHECK_EQ(0U, pseudo_schemes_.count(scheme))
395 << "Web-safe implies not pseudo.";
396
397 schemes_okay_to_request_in_any_process_.insert(scheme);
398 if (always_allow_in_origin_headers)
399 schemes_okay_to_appear_as_origin_headers_.insert(scheme);
400 } 381 }
401 382
402 bool ChildProcessSecurityPolicyImpl::IsWebSafeScheme( 383 bool ChildProcessSecurityPolicyImpl::IsWebSafeScheme(
403 const std::string& scheme) { 384 const std::string& scheme) {
404 base::AutoLock lock(lock_); 385 base::AutoLock lock(lock_);
405 386
406 return base::ContainsKey(schemes_okay_to_request_in_any_process_, scheme); 387 return base::ContainsKey(web_safe_schemes_, scheme);
407 } 388 }
408 389
409 void ChildProcessSecurityPolicyImpl::RegisterPseudoScheme( 390 void ChildProcessSecurityPolicyImpl::RegisterPseudoScheme(
410 const std::string& scheme) { 391 const std::string& scheme) {
411 base::AutoLock lock(lock_); 392 base::AutoLock lock(lock_);
412 DCHECK_EQ(0U, pseudo_schemes_.count(scheme)) << "Add schemes at most once."; 393 DCHECK_EQ(0U, pseudo_schemes_.count(scheme)) << "Add schemes at most once.";
413 DCHECK_EQ(0U, schemes_okay_to_request_in_any_process_.count(scheme)) 394 DCHECK_EQ(0U, web_safe_schemes_.count(scheme))
414 << "Pseudo implies not web-safe.";
415 DCHECK_EQ(0U, schemes_okay_to_commit_in_any_process_.count(scheme))
416 << "Pseudo implies not web-safe."; 395 << "Pseudo implies not web-safe.";
417 396
418 pseudo_schemes_.insert(scheme); 397 pseudo_schemes_.insert(scheme);
419 } 398 }
420 399
421 bool ChildProcessSecurityPolicyImpl::IsPseudoScheme( 400 bool ChildProcessSecurityPolicyImpl::IsPseudoScheme(
422 const std::string& scheme) { 401 const std::string& scheme) {
423 base::AutoLock lock(lock_); 402 base::AutoLock lock(lock_);
424 403
425 return base::ContainsKey(pseudo_schemes_, scheme); 404 return base::ContainsKey(pseudo_schemes_, scheme);
426 } 405 }
427 406
428 void ChildProcessSecurityPolicyImpl::GrantRequestURL( 407 void ChildProcessSecurityPolicyImpl::GrantRequestURL(
429 int child_id, const GURL& url) { 408 int child_id, const GURL& url) {
430 409
431 if (!url.is_valid()) 410 if (!url.is_valid())
432 return; // Can't grant the capability to request invalid URLs. 411 return; // Can't grant the capability to request invalid URLs.
433 412
434 if (IsWebSafeScheme(url.scheme())) 413 if (IsWebSafeScheme(url.scheme()))
435 return; // The scheme has already been whitelisted for every child process. 414 return; // The scheme has already been whitelisted for every child process.
436 415
437 if (IsPseudoScheme(url.scheme())) { 416 if (IsPseudoScheme(url.scheme())) {
438 return; // Can't grant the capability to request pseudo schemes. 417 return; // Can't grant the capability to request pseudo schemes.
439 } 418 }
440 419
441 if (url.SchemeIsBlob() || url.SchemeIsFileSystem()) {
442 return; // Don't grant blanket access to blob: or filesystem: schemes.
443 }
444
445 { 420 {
446 base::AutoLock lock(lock_); 421 base::AutoLock lock(lock_);
447 SecurityStateMap::iterator state = security_state_.find(child_id); 422 SecurityStateMap::iterator state = security_state_.find(child_id);
448 if (state == security_state_.end()) 423 if (state == security_state_.end())
449 return; 424 return;
450 425
451 // When the child process has been commanded to request this scheme, 426 // When the child process has been commanded to request this scheme,
452 // we grant it the capability to request all URLs of that scheme. 427 // we grant it the capability to request all URLs of that scheme.
453 state->second->GrantScheme(url.scheme()); 428 state->second->GrantScheme(url.scheme());
454 } 429 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 // Every child process can request <about:blank>. 599 // Every child process can request <about:blank>.
625 if (base::LowerCaseEqualsASCII(url.spec(), url::kAboutBlankURL)) 600 if (base::LowerCaseEqualsASCII(url.spec(), url::kAboutBlankURL))
626 return true; 601 return true;
627 // URLs like <about:version>, <about:crash>, <view-source:...> shouldn't be 602 // URLs like <about:version>, <about:crash>, <view-source:...> shouldn't be
628 // requestable by any child process. Also, this case covers 603 // requestable by any child process. Also, this case covers
629 // <javascript:...>, which should be handled internally by the process and 604 // <javascript:...>, which should be handled internally by the process and
630 // not kicked up to the browser. 605 // not kicked up to the browser.
631 return false; 606 return false;
632 } 607 }
633 608
634 // Blob and filesystem URLs require special treatment, since they embed an 609 if (IsMalformedBlobUrl(url))
635 // inner origin. 610 return false;
636 if (url.SchemeIsBlob() || url.SchemeIsFileSystem()) {
637 if (IsMalformedBlobUrl(url))
638 return false;
639
640 url::Origin origin(url);
641 return origin.unique() || IsWebSafeScheme(origin.scheme()) ||
642 CanCommitURL(child_id, GURL(origin.Serialize()));
643 }
644
645 if (IsWebSafeScheme(url.scheme()))
646 return true;
647 611
648 // If the process can commit the URL, it can request it. 612 // If the process can commit the URL, it can request it.
649 if (CanCommitURL(child_id, url)) 613 if (CanCommitURL(child_id, url))
650 return true; 614 return true;
651 615
652 // Also allow URLs destined for ShellExecute and not the browser itself. 616 // Also allow URLs destined for ShellExecute and not the browser itself.
653 return !GetContentClient()->browser()->IsHandledURL(url) && 617 return !GetContentClient()->browser()->IsHandledURL(url) &&
654 !net::URLRequest::IsHandledURL(url); 618 !net::URLRequest::IsHandledURL(url);
655 } 619 }
656 620
657 bool ChildProcessSecurityPolicyImpl::CanCommitURL(int child_id, 621 bool ChildProcessSecurityPolicyImpl::CanCommitURL(int child_id,
658 const GURL& url) { 622 const GURL& url) {
659 if (!url.is_valid()) 623 if (!url.is_valid())
660 return false; // Can't commit invalid URLs. 624 return false; // Can't commit invalid URLs.
661 625
662 // Of all the pseudo schemes, only about:blank is allowed to commit. 626 // Of all the pseudo schemes, only about:blank is allowed to commit.
663 if (IsPseudoScheme(url.scheme())) 627 if (IsPseudoScheme(url.scheme()))
664 return base::LowerCaseEqualsASCII(url.spec(), url::kAboutBlankURL); 628 return base::LowerCaseEqualsASCII(url.spec(), url::kAboutBlankURL);
665 629
666 // Blob and filesystem URLs require special treatment; validate the inner 630 if (IsMalformedBlobUrl(url))
667 // origin they embed. 631 return false;
668 if (url.SchemeIsBlob() || url.SchemeIsFileSystem()) {
669 if (IsMalformedBlobUrl(url))
670 return false;
671 632
672 url::Origin origin(url); 633 // TODO(creis): Tighten this for Site Isolation, so that a URL from a site
673 return origin.unique() || CanCommitURL(child_id, GURL(origin.Serialize())); 634 // that is isolated can only be committed in a process dedicated to that site.
674 } 635 // CanRequestURL should still allow all web-safe schemes. See
636 // https://crbug.com/515309.
637 if (IsWebSafeScheme(url.scheme()))
638 return true; // The scheme has been white-listed for every child process.
675 639
676 { 640 {
677 base::AutoLock lock(lock_); 641 base::AutoLock lock(lock_);
678 642
679 // Most schemes can commit in any process. Note that we check
680 // schemes_okay_to_commit_in_any_process_ here, which is stricter than
681 // IsWebSafeScheme().
682 //
683 // TODO(creis, nick): https://crbug.com/515309: in generalized Site
684 // Isolation and/or --site-per-process, there will be no such thing as a
685 // scheme that is okay to commit in any process. Instead, an URL from a site
686 // that is isolated may only be committed in a process dedicated to that
687 // site, so CanCommitURL will need to rely on explicit, per-process grants.
688 // Note how today, even with extension isolation, the line below does not
689 // enforce that http pages cannot commit in an extension process.
690 if (base::ContainsKey(schemes_okay_to_commit_in_any_process_, url.scheme()))
691 return true;
692
693 SecurityStateMap::iterator state = security_state_.find(child_id); 643 SecurityStateMap::iterator state = security_state_.find(child_id);
694 if (state == security_state_.end()) 644 if (state == security_state_.end())
695 return false; 645 return false;
696 646
697 // Otherwise, we consult the child process's security state to see if it is 647 // Otherwise, we consult the child process's security state to see if it is
698 // allowed to commit the URL. 648 // allowed to commit the URL.
699 return state->second->CanCommitURL(url); 649 return state->second->CanCommitURL(url);
700 } 650 }
701 } 651 }
702 652
703 bool ChildProcessSecurityPolicyImpl::CanSetAsOriginHeader(int child_id, 653 bool ChildProcessSecurityPolicyImpl::CanSetAsOriginHeader(int child_id,
704 const GURL& url) { 654 const GURL& url) {
705 if (!url.is_valid()) 655 if (!url.is_valid())
706 return false; // Can't set invalid URLs as origin headers. 656 return false; // Can't set invalid URLs as origin headers.
707 657
708 // Suborigin URLs are a special case and are allowed to be an origin header. 658 // Suborigin URLs are a special case and are allowed to be an origin header.
709 if (url.scheme() == kHttpSuboriginScheme || 659 if (url.scheme() == kHttpSuboriginScheme ||
710 url.scheme() == kHttpsSuboriginScheme) { 660 url.scheme() == kHttpsSuboriginScheme) {
711 DCHECK(IsPseudoScheme(url.scheme())); 661 DCHECK(IsPseudoScheme(url.scheme()));
712 return true; 662 return true;
713 } 663 }
714 664
715 // If this process can commit |url|, it can use |url| as an origin for 665 return CanCommitURL(child_id, url);
716 // outbound requests.
717 if (CanCommitURL(child_id, url))
718 return true;
719
720 // Allow schemes which may come from scripts executing in isolated worlds;
721 // XHRs issued by such scripts reflect the script origin rather than the
722 // document origin.
723 {
724 base::AutoLock lock(lock_);
725 if (base::ContainsKey(schemes_okay_to_appear_as_origin_headers_,
726 url.scheme()))
727 return true;
728 }
729 return false;
730 } 666 }
731 667
732 bool ChildProcessSecurityPolicyImpl::CanReadFile(int child_id, 668 bool ChildProcessSecurityPolicyImpl::CanReadFile(int child_id,
733 const base::FilePath& file) { 669 const base::FilePath& file) {
734 return HasPermissionsForFile(child_id, file, READ_FILE_GRANT); 670 return HasPermissionsForFile(child_id, file, READ_FILE_GRANT);
735 } 671 }
736 672
737 bool ChildProcessSecurityPolicyImpl::CanReadAllFiles( 673 bool ChildProcessSecurityPolicyImpl::CanReadAllFiles(
738 int child_id, 674 int child_id,
739 const std::vector<base::FilePath>& files) { 675 const std::vector<base::FilePath>& files) {
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 base::AutoLock lock(lock_); 899 base::AutoLock lock(lock_);
964 900
965 SecurityStateMap::iterator state = security_state_.find(child_id); 901 SecurityStateMap::iterator state = security_state_.find(child_id);
966 if (state == security_state_.end()) 902 if (state == security_state_.end())
967 return false; 903 return false;
968 904
969 return state->second->can_send_midi_sysex(); 905 return state->second->can_send_midi_sysex();
970 } 906 }
971 907
972 } // namespace content 908 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/child_process_security_policy_impl.h ('k') | content/public/browser/child_process_security_policy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698