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 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_CHILD_PROCESS_SECURITY_POLICY_IMPL_H_ 6 #define CONTENT_BROWSER_CHILD_PROCESS_SECURITY_POLICY_IMPL_H_ 7 8 9 #include <map> 10 #include <set> 11 #include <string> 12 13 #include "base/compiler_specific.h" 14 #include "base/gtest_prod_util.h" 15 #include "base/memory/singleton.h" 16 #include "base/synchronization/lock.h" 17 #include "content/public/browser/child_process_security_policy.h" 18 #include "webkit/common/fileapi/file_system_types.h" 19 #include "webkit/common/resource_type.h" 20 21 class GURL; 22 23 namespace base { 24 class FilePath; 25 } 26 27 namespace fileapi { 28 class FileSystemURL; 29 } 30 31 namespace content { 32 33 class CONTENT_EXPORT ChildProcessSecurityPolicyImpl 34 : NON_EXPORTED_BASE(public ChildProcessSecurityPolicy) { 35 public: 36 // Object can only be created through GetInstance() so the constructor is 37 // private. 38 virtual ~ChildProcessSecurityPolicyImpl(); 39 40 static ChildProcessSecurityPolicyImpl* GetInstance(); 41 42 // ChildProcessSecurityPolicy implementation. 43 virtual void RegisterWebSafeScheme(const std::string& scheme) OVERRIDE; 44 virtual bool IsWebSafeScheme(const std::string& scheme) OVERRIDE; 45 virtual void GrantReadFile(int child_id, const base::FilePath& file) OVERRIDE; 46 virtual void GrantCreateReadWriteFile(int child_id, 47 const base::FilePath& file) OVERRIDE; 48 virtual void GrantReadFileSystem( 49 int child_id, 50 const std::string& filesystem_id) OVERRIDE; 51 virtual void GrantWriteFileSystem( 52 int child_id, 53 const std::string& filesystem_id) OVERRIDE; 54 virtual void GrantCreateFileForFileSystem( 55 int child_id, 56 const std::string& filesystem_id) OVERRIDE; 57 virtual void GrantCreateReadWriteFileSystem( 58 int child_id, 59 const std::string& filesystem_id) OVERRIDE; 60 virtual void GrantCopyIntoFileSystem( 61 int child_id, 62 const std::string& filesystem_id) OVERRIDE; 63 virtual void GrantDeleteFromFileSystem( 64 int child_id, 65 const std::string& filesystem_id) OVERRIDE; 66 virtual void GrantScheme(int child_id, const std::string& scheme) OVERRIDE; 67 virtual bool CanReadFile(int child_id, const base::FilePath& file) OVERRIDE; 68 virtual bool CanCreateReadWriteFile(int child_id, 69 const base::FilePath& file) OVERRIDE; 70 virtual bool CanReadFileSystem(int child_id, 71 const std::string& filesystem_id) OVERRIDE; 72 virtual bool CanReadWriteFileSystem( 73 int child_id, 74 const std::string& filesystem_id) OVERRIDE; 75 virtual bool CanCopyIntoFileSystem(int child_id, 76 const std::string& filesystem_id) OVERRIDE; 77 virtual bool CanDeleteFromFileSystem( 78 int child_id, 79 const std::string& filesystem_id) OVERRIDE; 80 81 // Pseudo schemes are treated differently than other schemes because they 82 // cannot be requested like normal URLs. There is no mechanism for revoking 83 // pseudo schemes. 84 void RegisterPseudoScheme(const std::string& scheme); 85 86 // Returns true iff |scheme| has been registered as pseudo scheme. 87 bool IsPseudoScheme(const std::string& scheme); 88 89 // Upon creation, child processes should register themselves by calling this 90 // this method exactly once. 91 void Add(int child_id); 92 93 // Upon creation, worker thread child processes should register themselves by 94 // calling this this method exactly once. Workers that are not shared will 95 // inherit permissions from their parent renderer process identified with 96 // |main_render_process_id|. 97 void AddWorker(int worker_child_id, int main_render_process_id); 98 99 // Upon destruction, child processess should unregister themselves by caling 100 // this method exactly once. 101 void Remove(int child_id); 102 103 // Whenever the browser processes commands the child process to request a URL, 104 // it should call this method to grant the child process the capability to 105 // request the URL, along with permission to request all URLs of the same 106 // scheme. 107 void GrantRequestURL(int child_id, const GURL& url); 108 109 // Whenever the browser process drops a file icon on a tab, it should call 110 // this method to grant the child process the capability to request this one 111 // file:// URL, but not all urls of the file:// scheme. 112 void GrantRequestSpecificFileURL(int child_id, const GURL& url); 113 114 // Revokes all permissions granted to the given file. 115 void RevokeAllPermissionsForFile(int child_id, const base::FilePath& file); 116 117 // Grant the child process the ability to use Web UI Bindings. 118 void GrantWebUIBindings(int child_id); 119 120 // Grant the child process the ability to read raw cookies. 121 void GrantReadRawCookies(int child_id); 122 123 // Revoke read raw cookies permission. 124 void RevokeReadRawCookies(int child_id); 125 126 // Grants permission to send system exclusive message to any MIDI devices. 127 void GrantSendMIDISysExMessage(int child_id); 128 129 // Before servicing a child process's request for a URL, the browser should 130 // call this method to determine whether the process has the capability to 131 // request the URL. 132 bool CanRequestURL(int child_id, const GURL& url); 133 134 // Returns true if the process is permitted to load pages from 135 // the given origin in main frames or subframes. 136 // Only might return false if --site-per-process flag is used. 137 bool CanLoadPage(int child_id, 138 const GURL& url, 139 ResourceType::Type resource_type); 140 141 // Explicit permissions checks for FileSystemURL specified files. 142 bool CanReadFileSystemFile(int child_id, const fileapi::FileSystemURL& url); 143 bool CanWriteFileSystemFile(int child_id, const fileapi::FileSystemURL& url); 144 bool CanCreateFileSystemFile(int child_id, const fileapi::FileSystemURL& url); 145 bool CanCreateReadWriteFileSystemFile(int child_id, 146 const fileapi::FileSystemURL& url); 147 bool CanCopyIntoFileSystemFile(int child_id, 148 const fileapi::FileSystemURL& url); 149 bool CanDeleteFileSystemFile(int child_id, 150 const fileapi::FileSystemURL& url); 151 152 // Returns true if the specified child_id has been granted WebUIBindings. 153 // The browser should check this property before assuming the child process is 154 // allowed to use WebUIBindings. 155 bool HasWebUIBindings(int child_id); 156 157 // Returns true if the specified child_id has been granted ReadRawCookies. 158 bool CanReadRawCookies(int child_id); 159 160 // Returns true if the process is permitted to read and modify the cookies for 161 // the given origin. Does not affect cookies attached to or set by network 162 // requests. 163 // Only might return false if the very experimental 164 // --enable-strict-site-isolation or --site-per-process flags are used. 165 bool CanAccessCookiesForOrigin(int child_id, const GURL& gurl); 166 167 // Returns true if the process is permitted to attach cookies to (or have 168 // cookies set by) network requests. 169 // Only might return false if the very experimental 170 // --enable-strict-site-isolation or --site-per-process flags are used. 171 bool CanSendCookiesForOrigin(int child_id, const GURL& gurl); 172 173 // Sets the process as only permitted to use and see the cookies for the 174 // given origin. 175 // Only used if the very experimental --enable-strict-site-isolation or 176 // --site-per-process flags are used. 177 void LockToOrigin(int child_id, const GURL& gurl); 178 179 // Register FileSystem type and permission policy which should be used 180 // for the type. The |policy| must be a bitwise-or'd value of 181 // fileapi::FilePermissionPolicy. 182 void RegisterFileSystemPermissionPolicy( 183 fileapi::FileSystemType type, 184 int policy); 185 186 // Returns true if sending system exclusive messages is allowed. 187 bool CanSendMIDISysExMessage(int child_id); 188 189 private: 190 friend class ChildProcessSecurityPolicyInProcessBrowserTest; 191 friend class ChildProcessSecurityPolicyTest; 192 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyInProcessBrowserTest, 193 NoLeak); 194 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, FilePermissions); 195 196 class SecurityState; 197 198 typedef std::set<std::string> SchemeSet; 199 typedef std::map<int, SecurityState*> SecurityStateMap; 200 typedef std::map<int, int> WorkerToMainProcessMap; 201 typedef std::map<fileapi::FileSystemType, int> FileSystemPermissionPolicyMap; 202 203 // Obtain an instance of ChildProcessSecurityPolicyImpl via GetInstance(). 204 ChildProcessSecurityPolicyImpl(); 205 friend struct DefaultSingletonTraits<ChildProcessSecurityPolicyImpl>; 206 207 // Adds child process during registration. 208 void AddChild(int child_id); 209 210 // Determines if certain permissions were granted for a file to given child 211 // process. |permissions| is an internally defined bit-set. 212 bool ChildProcessHasPermissionsForFile(int child_id, 213 const base::FilePath& file, 214 int permissions); 215 216 // Grant a particular permission set for a file. |permissions| is an 217 // internally defined bit-set. 218 void GrantPermissionsForFile(int child_id, 219 const base::FilePath& file, 220 int permissions); 221 222 // Grants access permission to the given isolated file system 223 // identified by |filesystem_id|. See comments for 224 // ChildProcessSecurityPolicy::GrantReadFileSystem() for more details. 225 void GrantPermissionsForFileSystem( 226 int child_id, 227 const std::string& filesystem_id, 228 int permission); 229 230 // Determines if certain permissions were granted for a file. |permissions| 231 // is an internally defined bit-set. If |child_id| is a worker process, 232 // this returns true if either the worker process or its parent renderer 233 // has permissions for the file. 234 bool HasPermissionsForFile(int child_id, 235 const base::FilePath& file, 236 int permissions); 237 238 // Determines if certain permissions were granted for a file in FileSystem 239 // API. |permissions| is an internally defined bit-set. 240 bool HasPermissionsForFileSystemFile(int child_id, 241 const fileapi::FileSystemURL& url, 242 int permissions); 243 244 // Determines if certain permissions were granted for a file system. 245 // |permissions| is an internally defined bit-set. 246 bool HasPermissionsForFileSystem( 247 int child_id, 248 const std::string& filesystem_id, 249 int permission); 250 251 // You must acquire this lock before reading or writing any members of this 252 // class. You must not block while holding this lock. 253 base::Lock lock_; 254 255 // These schemes are white-listed for all child processes. This set is 256 // protected by |lock_|. 257 SchemeSet web_safe_schemes_; 258 259 // These schemes do not actually represent retrievable URLs. For example, 260 // the the URLs in the "about" scheme are aliases to other URLs. This set is 261 // protected by |lock_|. 262 SchemeSet pseudo_schemes_; 263 264 // This map holds a SecurityState for each child process. The key for the 265 // map is the ID of the ChildProcessHost. The SecurityState objects are 266 // owned by this object and are protected by |lock_|. References to them must 267 // not escape this class. 268 SecurityStateMap security_state_; 269 270 // This maps keeps the record of which js worker thread child process 271 // corresponds to which main js thread child process. 272 WorkerToMainProcessMap worker_map_; 273 274 FileSystemPermissionPolicyMap file_system_policy_map_; 275 276 DISALLOW_COPY_AND_ASSIGN(ChildProcessSecurityPolicyImpl); 277 }; 278 279 } // namespace content 280 281 #endif // CONTENT_BROWSER_CHILD_PROCESS_SECURITY_POLICY_IMPL_H_ 282