| OLD | NEW |
| 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 "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 } | 159 } |
| 160 | 160 |
| 161 void RevokeReadRawCookies() { | 161 void RevokeReadRawCookies() { |
| 162 can_read_raw_cookies_ = false; | 162 can_read_raw_cookies_ = false; |
| 163 } | 163 } |
| 164 | 164 |
| 165 void GrantPermissionForMidiSysEx() { | 165 void GrantPermissionForMidiSysEx() { |
| 166 can_send_midi_sysex_ = true; | 166 can_send_midi_sysex_ = true; |
| 167 } | 167 } |
| 168 | 168 |
| 169 // Determine whether permission has been granted to request |url|. | 169 // Determine whether permission has been granted to commit |url|. |
| 170 bool CanRequestURL(const GURL& url) { | 170 bool CanCommitURL(const GURL& url) { |
| 171 // Having permission to a scheme implies permssion to all of its URLs. | 171 // Having permission to a scheme implies permssion to all of its URLs. |
| 172 SchemeMap::const_iterator judgment(scheme_policy_.find(url.scheme())); | 172 SchemeMap::const_iterator judgment(scheme_policy_.find(url.scheme())); |
| 173 if (judgment != scheme_policy_.end()) | 173 if (judgment != scheme_policy_.end()) |
| 174 return judgment->second; | 174 return judgment->second; |
| 175 | 175 |
| 176 // file:// URLs are more granular. The child may have been given | 176 // file:// URLs are more granular. The child may have been given |
| 177 // permission to a specific file but not the file:// scheme in general. | 177 // permission to a specific file but not the file:// scheme in general. |
| 178 if (url.SchemeIs(url::kFileScheme)) { | 178 if (url.SchemeIs(url::kFileScheme)) { |
| 179 base::FilePath path; | 179 base::FilePath path; |
| 180 if (net::FileURLToFilePath(url, &path)) | 180 if (net::FileURLToFilePath(url, &path)) |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 return; | 548 return; |
| 549 | 549 |
| 550 state->second->RevokeReadRawCookies(); | 550 state->second->RevokeReadRawCookies(); |
| 551 } | 551 } |
| 552 | 552 |
| 553 bool ChildProcessSecurityPolicyImpl::CanRequestURL( | 553 bool ChildProcessSecurityPolicyImpl::CanRequestURL( |
| 554 int child_id, const GURL& url) { | 554 int child_id, const GURL& url) { |
| 555 if (!url.is_valid()) | 555 if (!url.is_valid()) |
| 556 return false; // Can't request invalid URLs. | 556 return false; // Can't request invalid URLs. |
| 557 | 557 |
| 558 if (IsWebSafeScheme(url.scheme())) | |
| 559 return true; // The scheme has been white-listed for every child process. | |
| 560 | |
| 561 if (IsPseudoScheme(url.scheme())) { | 558 if (IsPseudoScheme(url.scheme())) { |
| 562 // There are a number of special cases for pseudo schemes. | 559 // There are a number of special cases for pseudo schemes. |
| 563 | 560 |
| 564 if (url.SchemeIs(kViewSourceScheme)) { | 561 if (url.SchemeIs(kViewSourceScheme)) { |
| 565 // A view-source URL is allowed if the child process is permitted to | 562 // A view-source URL is allowed if the child process is permitted to |
| 566 // request the embedded URL. Careful to avoid pointless recursion. | 563 // request the embedded URL. Careful to avoid pointless recursion. |
| 567 GURL child_url(url.GetContent()); | 564 GURL child_url(url.GetContent()); |
| 568 if (child_url.SchemeIs(kViewSourceScheme) && | 565 if (child_url.SchemeIs(kViewSourceScheme) && |
| 569 url.SchemeIs(kViewSourceScheme)) | 566 url.SchemeIs(kViewSourceScheme)) |
| 570 return false; | 567 return false; |
| 571 | 568 |
| 572 return CanRequestURL(child_id, child_url); | 569 return CanRequestURL(child_id, child_url); |
| 573 } | 570 } |
| 574 | 571 |
| 575 if (base::LowerCaseEqualsASCII(url.spec(), url::kAboutBlankURL)) | 572 if (base::LowerCaseEqualsASCII(url.spec(), url::kAboutBlankURL)) |
| 576 return true; // Every child process can request <about:blank>. | 573 return true; // Every child process can request <about:blank>. |
| 577 | 574 |
| 578 // URLs like <about:memory> and <about:crash> shouldn't be requestable by | 575 // URLs like <about:memory> and <about:crash> shouldn't be requestable by |
| 579 // any child process. Also, this case covers <javascript:...>, which should | 576 // any child process. Also, this case covers <javascript:...>, which should |
| 580 // be handled internally by the process and not kicked up to the browser. | 577 // be handled internally by the process and not kicked up to the browser. |
| 581 return false; | 578 return false; |
| 582 } | 579 } |
| 583 | 580 |
| 584 if (!GetContentClient()->browser()->IsHandledURL(url) && | 581 // If the process can commit the URL, it can request it. |
| 585 !net::URLRequest::IsHandledURL(url)) { | 582 if (CanCommitURL(child_id, url)) |
| 586 return true; // This URL request is destined for ShellExecute. | 583 return true; |
| 587 } | 584 |
| 585 // Also allow URLs destined for ShellExecute and not the browser itself. |
| 586 return !GetContentClient()->browser()->IsHandledURL(url) && |
| 587 !net::URLRequest::IsHandledURL(url); |
| 588 } |
| 589 |
| 590 bool ChildProcessSecurityPolicyImpl::CanCommitURL(int child_id, |
| 591 const GURL& url) { |
| 592 if (!url.is_valid()) |
| 593 return false; // Can't commit invalid URLs. |
| 594 |
| 595 // Of all the pseudo schemes, only about:blank is allowed to commit. |
| 596 if (IsPseudoScheme(url.scheme())) |
| 597 return base::LowerCaseEqualsASCII(url.spec(), url::kAboutBlankURL); |
| 598 |
| 599 // TODO(creis): Tighten this for Site Isolation, so that a URL from a site |
| 600 // that is isolated can only be committed in a process dedicated to that site. |
| 601 // CanRequestURL should still allow all web-safe schemes. See |
| 602 // https://crbug.com/515309. |
| 603 if (IsWebSafeScheme(url.scheme())) |
| 604 return true; // The scheme has been white-listed for every child process. |
| 588 | 605 |
| 589 { | 606 { |
| 590 base::AutoLock lock(lock_); | 607 base::AutoLock lock(lock_); |
| 591 | 608 |
| 592 SecurityStateMap::iterator state = security_state_.find(child_id); | 609 SecurityStateMap::iterator state = security_state_.find(child_id); |
| 593 if (state == security_state_.end()) | 610 if (state == security_state_.end()) |
| 594 return false; | 611 return false; |
| 595 | 612 |
| 596 // Otherwise, we consult the child process's security state to see if it is | 613 // Otherwise, we consult the child process's security state to see if it is |
| 597 // allowed to request the URL. | 614 // allowed to commit the URL. |
| 598 return state->second->CanRequestURL(url); | 615 return state->second->CanCommitURL(url); |
| 599 } | 616 } |
| 600 } | 617 } |
| 601 | 618 |
| 602 bool ChildProcessSecurityPolicyImpl::CanReadFile(int child_id, | 619 bool ChildProcessSecurityPolicyImpl::CanReadFile(int child_id, |
| 603 const base::FilePath& file) { | 620 const base::FilePath& file) { |
| 604 return HasPermissionsForFile(child_id, file, READ_FILE_GRANT); | 621 return HasPermissionsForFile(child_id, file, READ_FILE_GRANT); |
| 605 } | 622 } |
| 606 | 623 |
| 607 bool ChildProcessSecurityPolicyImpl::CanCreateReadWriteFile( | 624 bool ChildProcessSecurityPolicyImpl::CanCreateReadWriteFile( |
| 608 int child_id, | 625 int child_id, |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 base::AutoLock lock(lock_); | 838 base::AutoLock lock(lock_); |
| 822 | 839 |
| 823 SecurityStateMap::iterator state = security_state_.find(child_id); | 840 SecurityStateMap::iterator state = security_state_.find(child_id); |
| 824 if (state == security_state_.end()) | 841 if (state == security_state_.end()) |
| 825 return false; | 842 return false; |
| 826 | 843 |
| 827 return state->second->can_send_midi_sysex(); | 844 return state->second->can_send_midi_sysex(); |
| 828 } | 845 } |
| 829 | 846 |
| 830 } // namespace content | 847 } // namespace content |
| OLD | NEW |