| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/browser/renderer_host/renderer_security_policy.h" | 5 #include "chrome/browser/child_process_security_policy.h" |
| 6 | 6 |
| 7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/stl_util-inl.h" | 9 #include "base/stl_util-inl.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "chrome/common/url_constants.h" | 11 #include "chrome/common/url_constants.h" |
| 12 #include "googleurl/src/gurl.h" | 12 #include "googleurl/src/gurl.h" |
| 13 #include "net/url_request/url_request.h" | 13 #include "net/url_request/url_request.h" |
| 14 | 14 |
| 15 // The SecurityState class is used to maintain per-renderer security state | 15 // The SecurityState class is used to maintain per-renderer security state |
| 16 // information. | 16 // information. |
| 17 class RendererSecurityPolicy::SecurityState { | 17 class ChildProcessSecurityPolicy::SecurityState { |
| 18 public: | 18 public: |
| 19 SecurityState() : has_dom_ui_bindings_(false) { } | 19 SecurityState() : has_dom_ui_bindings_(false) { } |
| 20 ~SecurityState() { | 20 ~SecurityState() { |
| 21 scheme_policy_.clear(); | 21 scheme_policy_.clear(); |
| 22 } | 22 } |
| 23 | 23 |
| 24 // Grant permission to request URLs with the specified scheme. | 24 // Grant permission to request URLs with the specified scheme. |
| 25 void GrantScheme(const std::string& scheme) { | 25 void GrantScheme(const std::string& scheme) { |
| 26 scheme_policy_[scheme] = true; | 26 scheme_policy_[scheme] = true; |
| 27 } | 27 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 SchemeMap scheme_policy_; | 71 SchemeMap scheme_policy_; |
| 72 | 72 |
| 73 // The set of files the renderer is permited to upload to the web. | 73 // The set of files the renderer is permited to upload to the web. |
| 74 FileSet uploadable_files_; | 74 FileSet uploadable_files_; |
| 75 | 75 |
| 76 bool has_dom_ui_bindings_; | 76 bool has_dom_ui_bindings_; |
| 77 | 77 |
| 78 DISALLOW_COPY_AND_ASSIGN(SecurityState); | 78 DISALLOW_COPY_AND_ASSIGN(SecurityState); |
| 79 }; | 79 }; |
| 80 | 80 |
| 81 RendererSecurityPolicy::RendererSecurityPolicy() { | 81 ChildProcessSecurityPolicy::ChildProcessSecurityPolicy() { |
| 82 // We know about these schemes and believe them to be safe. | 82 // We know about these schemes and believe them to be safe. |
| 83 RegisterWebSafeScheme(chrome::kHttpScheme); | 83 RegisterWebSafeScheme(chrome::kHttpScheme); |
| 84 RegisterWebSafeScheme(chrome::kHttpsScheme); | 84 RegisterWebSafeScheme(chrome::kHttpsScheme); |
| 85 RegisterWebSafeScheme(chrome::kFtpScheme); | 85 RegisterWebSafeScheme(chrome::kFtpScheme); |
| 86 RegisterWebSafeScheme(chrome::kDataScheme); | 86 RegisterWebSafeScheme(chrome::kDataScheme); |
| 87 RegisterWebSafeScheme("feed"); | 87 RegisterWebSafeScheme("feed"); |
| 88 RegisterWebSafeScheme("chrome-extension"); | 88 RegisterWebSafeScheme("chrome-extension"); |
| 89 | 89 |
| 90 // We know about the following psuedo schemes and treat them specially. | 90 // We know about the following psuedo schemes and treat them specially. |
| 91 RegisterPseudoScheme(chrome::kAboutScheme); | 91 RegisterPseudoScheme(chrome::kAboutScheme); |
| 92 RegisterPseudoScheme(chrome::kJavaScriptScheme); | 92 RegisterPseudoScheme(chrome::kJavaScriptScheme); |
| 93 RegisterPseudoScheme(chrome::kViewSourceScheme); | 93 RegisterPseudoScheme(chrome::kViewSourceScheme); |
| 94 } | 94 } |
| 95 | 95 |
| 96 RendererSecurityPolicy::~RendererSecurityPolicy() { | 96 ChildProcessSecurityPolicy::~ChildProcessSecurityPolicy() { |
| 97 web_safe_schemes_.clear(); | 97 web_safe_schemes_.clear(); |
| 98 pseudo_schemes_.clear(); | 98 pseudo_schemes_.clear(); |
| 99 STLDeleteContainerPairSecondPointers(security_state_.begin(), | 99 STLDeleteContainerPairSecondPointers(security_state_.begin(), |
| 100 security_state_.end()); | 100 security_state_.end()); |
| 101 security_state_.clear(); | 101 security_state_.clear(); |
| 102 } | 102 } |
| 103 | 103 |
| 104 // static | 104 // static |
| 105 RendererSecurityPolicy* RendererSecurityPolicy::GetInstance() { | 105 ChildProcessSecurityPolicy* ChildProcessSecurityPolicy::GetInstance() { |
| 106 return Singleton<RendererSecurityPolicy>::get(); | 106 return Singleton<ChildProcessSecurityPolicy>::get(); |
| 107 } | 107 } |
| 108 | 108 |
| 109 void RendererSecurityPolicy::Add(int renderer_id) { | 109 void ChildProcessSecurityPolicy::Add(int renderer_id) { |
| 110 AutoLock lock(lock_); | 110 AutoLock lock(lock_); |
| 111 if (security_state_.count(renderer_id) != 0) { | 111 if (security_state_.count(renderer_id) != 0) { |
| 112 NOTREACHED() << "Add renderers at most once."; | 112 NOTREACHED() << "Add renderers at most once."; |
| 113 return; | 113 return; |
| 114 } | 114 } |
| 115 | 115 |
| 116 security_state_[renderer_id] = new SecurityState(); | 116 security_state_[renderer_id] = new SecurityState(); |
| 117 } | 117 } |
| 118 | 118 |
| 119 void RendererSecurityPolicy::Remove(int renderer_id) { | 119 void ChildProcessSecurityPolicy::Remove(int renderer_id) { |
| 120 AutoLock lock(lock_); | 120 AutoLock lock(lock_); |
| 121 if (security_state_.count(renderer_id) != 1) { | 121 if (security_state_.count(renderer_id) != 1) { |
| 122 NOTREACHED() << "Remove renderers at most once."; | 122 NOTREACHED() << "Remove renderers at most once."; |
| 123 return; | 123 return; |
| 124 } | 124 } |
| 125 | 125 |
| 126 delete security_state_[renderer_id]; | 126 delete security_state_[renderer_id]; |
| 127 security_state_.erase(renderer_id); | 127 security_state_.erase(renderer_id); |
| 128 } | 128 } |
| 129 | 129 |
| 130 void RendererSecurityPolicy::RegisterWebSafeScheme(const std::string& scheme) { | 130 void ChildProcessSecurityPolicy::RegisterWebSafeScheme(const std::string& scheme
) { |
| 131 AutoLock lock(lock_); | 131 AutoLock lock(lock_); |
| 132 DCHECK(web_safe_schemes_.count(scheme) == 0) << "Add schemes at most once."; | 132 DCHECK(web_safe_schemes_.count(scheme) == 0) << "Add schemes at most once."; |
| 133 DCHECK(pseudo_schemes_.count(scheme) == 0) << "Web-safe implies not psuedo."; | 133 DCHECK(pseudo_schemes_.count(scheme) == 0) << "Web-safe implies not psuedo."; |
| 134 | 134 |
| 135 web_safe_schemes_.insert(scheme); | 135 web_safe_schemes_.insert(scheme); |
| 136 } | 136 } |
| 137 | 137 |
| 138 bool RendererSecurityPolicy::IsWebSafeScheme(const std::string& scheme) { | 138 bool ChildProcessSecurityPolicy::IsWebSafeScheme(const std::string& scheme) { |
| 139 AutoLock lock(lock_); | 139 AutoLock lock(lock_); |
| 140 | 140 |
| 141 return (web_safe_schemes_.find(scheme) != web_safe_schemes_.end()); | 141 return (web_safe_schemes_.find(scheme) != web_safe_schemes_.end()); |
| 142 } | 142 } |
| 143 | 143 |
| 144 void RendererSecurityPolicy::RegisterPseudoScheme(const std::string& scheme) { | 144 void ChildProcessSecurityPolicy::RegisterPseudoScheme(const std::string& scheme)
{ |
| 145 AutoLock lock(lock_); | 145 AutoLock lock(lock_); |
| 146 DCHECK(pseudo_schemes_.count(scheme) == 0) << "Add schemes at most once."; | 146 DCHECK(pseudo_schemes_.count(scheme) == 0) << "Add schemes at most once."; |
| 147 DCHECK(web_safe_schemes_.count(scheme) == 0) << | 147 DCHECK(web_safe_schemes_.count(scheme) == 0) << |
| 148 "Psuedo implies not web-safe."; | 148 "Psuedo implies not web-safe."; |
| 149 | 149 |
| 150 pseudo_schemes_.insert(scheme); | 150 pseudo_schemes_.insert(scheme); |
| 151 } | 151 } |
| 152 | 152 |
| 153 bool RendererSecurityPolicy::IsPseudoScheme(const std::string& scheme) { | 153 bool ChildProcessSecurityPolicy::IsPseudoScheme(const std::string& scheme) { |
| 154 AutoLock lock(lock_); | 154 AutoLock lock(lock_); |
| 155 | 155 |
| 156 return (pseudo_schemes_.find(scheme) != pseudo_schemes_.end()); | 156 return (pseudo_schemes_.find(scheme) != pseudo_schemes_.end()); |
| 157 } | 157 } |
| 158 | 158 |
| 159 void RendererSecurityPolicy::GrantRequestURL(int renderer_id, const GURL& url) { | 159 void ChildProcessSecurityPolicy::GrantRequestURL(int renderer_id, const GURL& ur
l) { |
| 160 | 160 |
| 161 if (!url.is_valid()) | 161 if (!url.is_valid()) |
| 162 return; // Can't grant the capability to request invalid URLs. | 162 return; // Can't grant the capability to request invalid URLs. |
| 163 | 163 |
| 164 if (IsWebSafeScheme(url.scheme())) | 164 if (IsWebSafeScheme(url.scheme())) |
| 165 return; // The scheme has already been white-listed for every renderer. | 165 return; // The scheme has already been white-listed for every renderer. |
| 166 | 166 |
| 167 if (IsPseudoScheme(url.scheme())) { | 167 if (IsPseudoScheme(url.scheme())) { |
| 168 // The view-source scheme is a special case of a pseudo URL that eventually | 168 // The view-source scheme is a special case of a pseudo URL that eventually |
| 169 // results in requesting its embedded URL. | 169 // results in requesting its embedded URL. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 183 SecurityStateMap::iterator state = security_state_.find(renderer_id); | 183 SecurityStateMap::iterator state = security_state_.find(renderer_id); |
| 184 if (state == security_state_.end()) | 184 if (state == security_state_.end()) |
| 185 return; | 185 return; |
| 186 | 186 |
| 187 // If the renderer has been commanded to request a scheme, then we grant | 187 // If the renderer has been commanded to request a scheme, then we grant |
| 188 // it the capability to request URLs of that scheme. | 188 // it the capability to request URLs of that scheme. |
| 189 state->second->GrantScheme(url.scheme()); | 189 state->second->GrantScheme(url.scheme()); |
| 190 } | 190 } |
| 191 } | 191 } |
| 192 | 192 |
| 193 void RendererSecurityPolicy::GrantUploadFile(int renderer_id, | 193 void ChildProcessSecurityPolicy::GrantUploadFile(int renderer_id, |
| 194 const FilePath& file) { | 194 const FilePath& file) { |
| 195 AutoLock lock(lock_); | 195 AutoLock lock(lock_); |
| 196 | 196 |
| 197 SecurityStateMap::iterator state = security_state_.find(renderer_id); | 197 SecurityStateMap::iterator state = security_state_.find(renderer_id); |
| 198 if (state == security_state_.end()) | 198 if (state == security_state_.end()) |
| 199 return; | 199 return; |
| 200 | 200 |
| 201 state->second->GrantUploadFile(file); | 201 state->second->GrantUploadFile(file); |
| 202 } | 202 } |
| 203 | 203 |
| 204 void RendererSecurityPolicy::GrantInspectElement(int renderer_id) { | 204 void ChildProcessSecurityPolicy::GrantInspectElement(int renderer_id) { |
| 205 AutoLock lock(lock_); | 205 AutoLock lock(lock_); |
| 206 | 206 |
| 207 SecurityStateMap::iterator state = security_state_.find(renderer_id); | 207 SecurityStateMap::iterator state = security_state_.find(renderer_id); |
| 208 if (state == security_state_.end()) | 208 if (state == security_state_.end()) |
| 209 return; | 209 return; |
| 210 | 210 |
| 211 // The inspector is served from a chrome: URL. In order to run the | 211 // The inspector is served from a chrome: URL. In order to run the |
| 212 // inspector, the renderer needs to be able to load chrome: URLs. | 212 // inspector, the renderer needs to be able to load chrome: URLs. |
| 213 state->second->GrantScheme(chrome::kChromeUIScheme); | 213 state->second->GrantScheme(chrome::kChromeUIScheme); |
| 214 } | 214 } |
| 215 | 215 |
| 216 void RendererSecurityPolicy::GrantDOMUIBindings(int renderer_id) { | 216 void ChildProcessSecurityPolicy::GrantDOMUIBindings(int renderer_id) { |
| 217 AutoLock lock(lock_); | 217 AutoLock lock(lock_); |
| 218 | 218 |
| 219 SecurityStateMap::iterator state = security_state_.find(renderer_id); | 219 SecurityStateMap::iterator state = security_state_.find(renderer_id); |
| 220 if (state == security_state_.end()) | 220 if (state == security_state_.end()) |
| 221 return; | 221 return; |
| 222 | 222 |
| 223 state->second->GrantDOMUIBindings(); | 223 state->second->GrantDOMUIBindings(); |
| 224 | 224 |
| 225 // DOM UI bindings need the ability to request chrome: URLs. | 225 // DOM UI bindings need the ability to request chrome: URLs. |
| 226 state->second->GrantScheme(chrome::kChromeUIScheme); | 226 state->second->GrantScheme(chrome::kChromeUIScheme); |
| 227 | 227 |
| 228 // DOM UI pages can contain links to file:// URLs. | 228 // DOM UI pages can contain links to file:// URLs. |
| 229 state->second->GrantScheme(chrome::kFileScheme); | 229 state->second->GrantScheme(chrome::kFileScheme); |
| 230 } | 230 } |
| 231 | 231 |
| 232 bool RendererSecurityPolicy::CanRequestURL(int renderer_id, const GURL& url) { | 232 bool ChildProcessSecurityPolicy::CanRequestURL(int renderer_id, const GURL& url)
{ |
| 233 if (!url.is_valid()) | 233 if (!url.is_valid()) |
| 234 return false; // Can't request invalid URLs. | 234 return false; // Can't request invalid URLs. |
| 235 | 235 |
| 236 if (IsWebSafeScheme(url.scheme())) | 236 if (IsWebSafeScheme(url.scheme())) |
| 237 return true; // The scheme has been white-listed for every renderer. | 237 return true; // The scheme has been white-listed for every renderer. |
| 238 | 238 |
| 239 if (IsPseudoScheme(url.scheme())) { | 239 if (IsPseudoScheme(url.scheme())) { |
| 240 // There are a number of special cases for pseudo schemes. | 240 // There are a number of special cases for pseudo schemes. |
| 241 | 241 |
| 242 if (url.SchemeIs(chrome::kViewSourceScheme)) { | 242 if (url.SchemeIs(chrome::kViewSourceScheme)) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 263 SecurityStateMap::iterator state = security_state_.find(renderer_id); | 263 SecurityStateMap::iterator state = security_state_.find(renderer_id); |
| 264 if (state == security_state_.end()) | 264 if (state == security_state_.end()) |
| 265 return false; | 265 return false; |
| 266 | 266 |
| 267 // Otherwise, we consult the renderer's security state to see if it is | 267 // Otherwise, we consult the renderer's security state to see if it is |
| 268 // allowed to request the URL. | 268 // allowed to request the URL. |
| 269 return state->second->CanRequestURL(url); | 269 return state->second->CanRequestURL(url); |
| 270 } | 270 } |
| 271 } | 271 } |
| 272 | 272 |
| 273 bool RendererSecurityPolicy::CanUploadFile(int renderer_id, | 273 bool ChildProcessSecurityPolicy::CanUploadFile(int renderer_id, |
| 274 const FilePath& file) { | 274 const FilePath& file) { |
| 275 AutoLock lock(lock_); | 275 AutoLock lock(lock_); |
| 276 | 276 |
| 277 SecurityStateMap::iterator state = security_state_.find(renderer_id); | 277 SecurityStateMap::iterator state = security_state_.find(renderer_id); |
| 278 if (state == security_state_.end()) | 278 if (state == security_state_.end()) |
| 279 return false; | 279 return false; |
| 280 | 280 |
| 281 return state->second->CanUploadFile(file); | 281 return state->second->CanUploadFile(file); |
| 282 } | 282 } |
| 283 | 283 |
| 284 bool RendererSecurityPolicy::HasDOMUIBindings(int renderer_id) { | 284 bool ChildProcessSecurityPolicy::HasDOMUIBindings(int renderer_id) { |
| 285 AutoLock lock(lock_); | 285 AutoLock lock(lock_); |
| 286 | 286 |
| 287 SecurityStateMap::iterator state = security_state_.find(renderer_id); | 287 SecurityStateMap::iterator state = security_state_.find(renderer_id); |
| 288 if (state == security_state_.end()) | 288 if (state == security_state_.end()) |
| 289 return false; | 289 return false; |
| 290 | 290 |
| 291 return state->second->has_dom_ui_bindings(); | 291 return state->second->has_dom_ui_bindings(); |
| 292 } | 292 } |
| OLD | NEW |