#include "content/browser/child_process_security_policy_impl.h"
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/debug/crash_logging.h"
#include "base/debug/dump_without_crashing.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/not_fatal_until.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "content/browser/bad_message.h"
#include "content/browser/isolated_origin_util.h"
#include "content/browser/process_lock.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/site_info.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/url_info.h"
#include "content/browser/webui/url_data_manager_backend.h"
#include "content/common/content_navigation_policy.h"
#include "content/common/features.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_or_resource_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/child_process_host.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/url_constants.h"
#include "net/base/filename_util.h"
#include "net/base/url_util.h"
#include "net/net_buildflags.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "storage/browser/file_system/file_permission_policy.h"
#include "storage/browser/file_system/file_system_context.h"
#include "storage/browser/file_system/file_system_url.h"
#include "storage/browser/file_system/isolated_context.h"
#include "storage/common/file_system/file_system_util.h"
#include "third_party/blink/public/common/features.h"
#include "url/gurl.h"
#include "url/url_canon.h"
#include "url/url_constants.h"
namespace features {
BASE_FEATURE(…);
BASE_FEATURE(…);
}
namespace content {
namespace {
enum ChildProcessSecurityPermissions { … };
enum ChildProcessSecurityGrants { … };
bool IsMalformedBlobUrl(const GURL& url) { … }
bool IsRunningOnExpectedThread() { … }
base::debug::CrashKeyString* GetRequestedOriginCrashKey() { … }
base::debug::CrashKeyString* GetExpectedProcessLockKey() { … }
base::debug::CrashKeyString* GetKilledProcessOriginLockKey() { … }
base::debug::CrashKeyString* GetCanAccessDataFailureReasonKey() { … }
base::debug::CrashKeyString* GetCanAccessDataKeepAliveDurationKey() { … }
base::debug::CrashKeyString* GetCanAccessDataShutdownDelayRefCountKey() { … }
base::debug::CrashKeyString* GetCanAccessDataProcessRFHCount() { … }
void LogCanAccessDataForOriginCrashKeys(
const std::string& expected_process_lock,
const std::string& killed_process_origin_lock,
const std::string& requested_origin,
const std::string& failure_reason,
const std::string& keep_alive_durations,
const std::string& shutdown_delay_ref_count,
const std::string& process_rfh_count) { … }
void LogCanCommitUrlFailureReason(const std::string& failure_reason) { … }
bool AllowProcessLockMismatchForNTP(const ProcessLock& expected_lock,
const ProcessLock& actual_lock) { … }
base::WeakPtr<ResourceContext> GetResourceContext(
BrowserContext* browser_context) { … }
}
ChildProcessSecurityPolicyImpl::Handle::Handle()
: … { … }
ChildProcessSecurityPolicyImpl::Handle::Handle(int child_id,
bool duplicating_handle)
: … { … }
ChildProcessSecurityPolicyImpl::Handle::Handle(Handle&& rhs)
: … { … }
ChildProcessSecurityPolicyImpl::Handle
ChildProcessSecurityPolicyImpl::Handle::Duplicate() { … }
ChildProcessSecurityPolicyImpl::Handle::~Handle() { … }
ChildProcessSecurityPolicyImpl::Handle& ChildProcessSecurityPolicyImpl::Handle::
operator=(Handle&& rhs) { … }
bool ChildProcessSecurityPolicyImpl::Handle::is_valid() const { … }
bool ChildProcessSecurityPolicyImpl::Handle::CanReadFile(
const base::FilePath& file) { … }
bool ChildProcessSecurityPolicyImpl::Handle::CanReadFileSystemFile(
const storage::FileSystemURL& url) { … }
bool ChildProcessSecurityPolicyImpl::Handle::CanAccessDataForOrigin(
const url::Origin& origin) { … }
ChildProcessSecurityPolicyImpl::OriginAgentClusterOptInEntry::
OriginAgentClusterOptInEntry(
const OriginAgentClusterIsolationState& oac_isolation_state_in,
const url::Origin& origin_in)
: … { … }
ChildProcessSecurityPolicyImpl::OriginAgentClusterOptInEntry::
OriginAgentClusterOptInEntry(const OriginAgentClusterOptInEntry&) = default;
ChildProcessSecurityPolicyImpl::OriginAgentClusterOptInEntry::
~OriginAgentClusterOptInEntry() = default;
class ChildProcessSecurityPolicyImpl::SecurityState { … };
ChildProcessSecurityPolicyImpl::IsolatedOriginEntry::IsolatedOriginEntry(
const url::Origin& origin,
bool applies_to_future_browsing_instances,
BrowsingInstanceId browsing_instance_id,
BrowserContext* browser_context,
ResourceContext* resource_context,
bool isolate_all_subdomains,
IsolatedOriginSource source)
: … { … }
ChildProcessSecurityPolicyImpl::IsolatedOriginEntry::IsolatedOriginEntry(
const IsolatedOriginEntry& other) = default;
ChildProcessSecurityPolicyImpl::IsolatedOriginEntry&
ChildProcessSecurityPolicyImpl::IsolatedOriginEntry::operator=(
const IsolatedOriginEntry& other) = default;
ChildProcessSecurityPolicyImpl::IsolatedOriginEntry::IsolatedOriginEntry(
IsolatedOriginEntry&& other) = default;
ChildProcessSecurityPolicyImpl::IsolatedOriginEntry&
ChildProcessSecurityPolicyImpl::IsolatedOriginEntry::operator=(
IsolatedOriginEntry&& other) = default;
ChildProcessSecurityPolicyImpl::IsolatedOriginEntry::~IsolatedOriginEntry() =
default;
bool ChildProcessSecurityPolicyImpl::IsolatedOriginEntry::
AppliesToAllBrowserContexts() const { … }
bool ChildProcessSecurityPolicyImpl::IsolatedOriginEntry::MatchesProfile(
const BrowserOrResourceContext& browser_or_resource_context) const { … }
bool ChildProcessSecurityPolicyImpl::IsolatedOriginEntry::
MatchesBrowsingInstance(BrowsingInstanceId browsing_instance_id) const { … }
ChildProcessSecurityPolicyImpl::ChildProcessSecurityPolicyImpl()
: … { … }
ChildProcessSecurityPolicyImpl::~ChildProcessSecurityPolicyImpl() { … }
ChildProcessSecurityPolicy* ChildProcessSecurityPolicy::GetInstance() { … }
ChildProcessSecurityPolicyImpl* ChildProcessSecurityPolicyImpl::GetInstance() { … }
void ChildProcessSecurityPolicyImpl::Add(int child_id,
BrowserContext* browser_context) { … }
void ChildProcessSecurityPolicyImpl::AddForTesting(
int child_id,
BrowserContext* browser_context) { … }
void ChildProcessSecurityPolicyImpl::Remove(int child_id) { … }
void ChildProcessSecurityPolicyImpl::RegisterWebSafeScheme(
const std::string& scheme) { … }
void ChildProcessSecurityPolicyImpl::RegisterWebSafeIsolatedScheme(
const std::string& scheme,
bool always_allow_in_origin_headers) { … }
bool ChildProcessSecurityPolicyImpl::IsWebSafeScheme(
const std::string& scheme) { … }
void ChildProcessSecurityPolicyImpl::RegisterPseudoScheme(
const std::string& scheme) { … }
bool ChildProcessSecurityPolicyImpl::IsPseudoScheme(
const std::string& scheme) { … }
void ChildProcessSecurityPolicyImpl::ClearRegisteredSchemeForTesting(
const std::string& scheme) { … }
void ChildProcessSecurityPolicyImpl::GrantCommitURL(int child_id,
const GURL& url) { … }
void ChildProcessSecurityPolicyImpl::GrantRequestSpecificFileURL(
int child_id,
const GURL& url) { … }
void ChildProcessSecurityPolicyImpl::GrantReadFile(int child_id,
const base::FilePath& file) { … }
void ChildProcessSecurityPolicyImpl::GrantCreateReadWriteFile(
int child_id, const base::FilePath& file) { … }
void ChildProcessSecurityPolicyImpl::GrantCopyInto(int child_id,
const base::FilePath& dir) { … }
void ChildProcessSecurityPolicyImpl::GrantDeleteFrom(
int child_id, const base::FilePath& dir) { … }
void ChildProcessSecurityPolicyImpl::GrantPermissionsForFile(
int child_id, const base::FilePath& file, int permissions) { … }
void ChildProcessSecurityPolicyImpl::RevokeAllPermissionsForFile(
int child_id, const base::FilePath& file) { … }
void ChildProcessSecurityPolicyImpl::GrantReadFileSystem(
int child_id, const std::string& filesystem_id) { … }
void ChildProcessSecurityPolicyImpl::GrantWriteFileSystem(
int child_id, const std::string& filesystem_id) { … }
void ChildProcessSecurityPolicyImpl::GrantCreateFileForFileSystem(
int child_id, const std::string& filesystem_id) { … }
void ChildProcessSecurityPolicyImpl::GrantCreateReadWriteFileSystem(
int child_id, const std::string& filesystem_id) { … }
void ChildProcessSecurityPolicyImpl::GrantCopyIntoFileSystem(
int child_id, const std::string& filesystem_id) { … }
void ChildProcessSecurityPolicyImpl::GrantDeleteFromFileSystem(
int child_id, const std::string& filesystem_id) { … }
void ChildProcessSecurityPolicyImpl::GrantSendMidiMessage(int child_id) { … }
void ChildProcessSecurityPolicyImpl::GrantSendMidiSysExMessage(int child_id) { … }
void ChildProcessSecurityPolicyImpl::GrantCommitOrigin(
int child_id,
const url::Origin& origin) { … }
void ChildProcessSecurityPolicyImpl::GrantRequestOrigin(
int child_id,
const url::Origin& origin) { … }
void ChildProcessSecurityPolicyImpl::GrantRequestScheme(
int child_id,
const std::string& scheme) { … }
void ChildProcessSecurityPolicyImpl::GrantWebUIBindings(
int child_id,
BindingsPolicySet bindings) { … }
void ChildProcessSecurityPolicyImpl::GrantReadRawCookies(int child_id) { … }
void ChildProcessSecurityPolicyImpl::RevokeReadRawCookies(int child_id) { … }
void ChildProcessSecurityPolicyImpl::GrantOriginCheckExemptionForWebView(
int child_id,
const url::Origin& origin) { … }
bool ChildProcessSecurityPolicyImpl::HasOriginCheckExemptionForWebView(
int child_id,
const url::Origin& origin) { … }
bool ChildProcessSecurityPolicyImpl::CanRequestURL(
int child_id, const GURL& url) { … }
bool ChildProcessSecurityPolicyImpl::CanRedirectToURL(const GURL& url) { … }
bool ChildProcessSecurityPolicyImpl::CanCommitURL(int child_id,
const GURL& url) { … }
bool ChildProcessSecurityPolicyImpl::CanReadFile(int child_id,
const base::FilePath& file) { … }
bool ChildProcessSecurityPolicyImpl::CanReadAllFiles(
int child_id,
const std::vector<base::FilePath>& files) { … }
bool ChildProcessSecurityPolicyImpl::CanReadRequestBody(
int child_id,
const storage::FileSystemContext* file_system_context,
const scoped_refptr<network::ResourceRequestBody>& body) { … }
bool ChildProcessSecurityPolicyImpl::CanReadRequestBody(
RenderProcessHost* process,
const scoped_refptr<network::ResourceRequestBody>& body) { … }
bool ChildProcessSecurityPolicyImpl::CanCreateReadWriteFile(
int child_id,
const base::FilePath& file) { … }
bool ChildProcessSecurityPolicyImpl::CanReadFileSystem(
int child_id, const std::string& filesystem_id) { … }
bool ChildProcessSecurityPolicyImpl::CanReadWriteFileSystem(
int child_id, const std::string& filesystem_id) { … }
bool ChildProcessSecurityPolicyImpl::CanCopyIntoFileSystem(
int child_id, const std::string& filesystem_id) { … }
bool ChildProcessSecurityPolicyImpl::CanDeleteFromFileSystem(
int child_id, const std::string& filesystem_id) { … }
bool ChildProcessSecurityPolicyImpl::HasPermissionsForFile(
int child_id, const base::FilePath& file, int permissions) { … }
bool ChildProcessSecurityPolicyImpl::HasPermissionsForFileSystemFile(
int child_id,
const storage::FileSystemURL& filesystem_url,
int permissions) { … }
bool ChildProcessSecurityPolicyImpl::CanReadFileSystemFile(
int child_id,
const storage::FileSystemURL& filesystem_url) { … }
bool ChildProcessSecurityPolicyImpl::CanWriteFileSystemFile(
int child_id,
const storage::FileSystemURL& filesystem_url) { … }
bool ChildProcessSecurityPolicyImpl::CanCreateFileSystemFile(
int child_id,
const storage::FileSystemURL& filesystem_url) { … }
bool ChildProcessSecurityPolicyImpl::CanCreateReadWriteFileSystemFile(
int child_id,
const storage::FileSystemURL& filesystem_url) { … }
bool ChildProcessSecurityPolicyImpl::CanCopyIntoFileSystemFile(
int child_id,
const storage::FileSystemURL& filesystem_url) { … }
bool ChildProcessSecurityPolicyImpl::CanDeleteFileSystemFile(
int child_id,
const storage::FileSystemURL& filesystem_url) { … }
bool ChildProcessSecurityPolicyImpl::CanMoveFileSystemFile(
int child_id,
const storage::FileSystemURL& src_url,
const storage::FileSystemURL& dest_url) { … }
bool ChildProcessSecurityPolicyImpl::CanCopyFileSystemFile(
int child_id,
const storage::FileSystemURL& src_url,
const storage::FileSystemURL& dest_url) { … }
bool ChildProcessSecurityPolicyImpl::HasWebUIBindings(int child_id) { … }
bool ChildProcessSecurityPolicyImpl::CanReadRawCookies(int child_id) { … }
bool ChildProcessSecurityPolicyImpl::ChildProcessHasPermissionsForFile(
int child_id, const base::FilePath& file, int permissions) { … }
size_t ChildProcessSecurityPolicyImpl::BrowsingInstanceIdCountForTesting(
int child_id) { … }
CanCommitStatus ChildProcessSecurityPolicyImpl::CanCommitOriginAndUrl(
int child_id,
const IsolationContext& isolation_context,
const UrlInfo& url_info) { … }
bool ChildProcessSecurityPolicyImpl::CanAccessDataForOrigin(
int child_id,
const url::Origin& origin) { … }
bool ChildProcessSecurityPolicyImpl::HostsOrigin(int child_id,
const url::Origin& origin) { … }
bool ChildProcessSecurityPolicyImpl::CanAccessOrigin(int child_id,
const url::Origin& origin,
AccessType access_type) { … }
bool ChildProcessSecurityPolicyImpl::IsAccessAllowedForSandboxedProcess(
const ProcessLock& process_lock,
const GURL& url,
bool url_is_for_opaque_origin,
AccessType access_type) { … }
bool ChildProcessSecurityPolicyImpl::IsAccessAllowedForPdfProcess(
AccessType access_type) { … }
bool ChildProcessSecurityPolicyImpl::CanAccessMaybeOpaqueOrigin(
int child_id,
const GURL& url,
bool url_is_precursor_of_opaque_origin,
AccessType access_type) { … }
void ChildProcessSecurityPolicyImpl::IncludeIsolationContext(
int child_id,
const IsolationContext& isolation_context) { … }
void ChildProcessSecurityPolicyImpl::LockProcess(
const IsolationContext& context,
int child_id,
bool is_process_used,
const ProcessLock& process_lock) { … }
void ChildProcessSecurityPolicyImpl::LockProcessForTesting(
const IsolationContext& isolation_context,
int child_id,
const GURL& url) { … }
ProcessLock ChildProcessSecurityPolicyImpl::GetProcessLock(int child_id) { … }
void ChildProcessSecurityPolicyImpl::GrantPermissionsForFileSystem(
int child_id,
const std::string& filesystem_id,
int permission) { … }
bool ChildProcessSecurityPolicyImpl::HasPermissionsForFileSystem(
int child_id,
const std::string& filesystem_id,
int permission) { … }
void ChildProcessSecurityPolicyImpl::RegisterFileSystemPermissionPolicy(
storage::FileSystemType type,
int policy) { … }
bool ChildProcessSecurityPolicyImpl::CanSendMidiMessage(int child_id) { … }
bool ChildProcessSecurityPolicyImpl::CanSendMidiSysExMessage(int child_id) { … }
void ChildProcessSecurityPolicyImpl::AddFutureIsolatedOrigins(
const std::vector<url::Origin>& origins_to_add,
IsolatedOriginSource source,
BrowserContext* browser_context) { … }
void ChildProcessSecurityPolicyImpl::AddFutureIsolatedOrigins(
std::string_view origins_to_add,
IsolatedOriginSource source,
BrowserContext* browser_context) { … }
void ChildProcessSecurityPolicyImpl::AddFutureIsolatedOrigins(
const std::vector<IsolatedOriginPattern>& patterns,
IsolatedOriginSource source,
BrowserContext* browser_context) { … }
void ChildProcessSecurityPolicyImpl::AddIsolatedOriginInternal(
BrowserContext* browser_context,
const url::Origin& origin_to_add,
bool applies_to_future_browsing_instances,
BrowsingInstanceId browsing_instance_id,
bool isolate_all_subdomains,
IsolatedOriginSource source) { … }
void ChildProcessSecurityPolicyImpl::RemoveStateForBrowserContext(
const BrowserContext& browser_context) { … }
bool ChildProcessSecurityPolicyImpl::IsIsolatedOrigin(
const IsolationContext& isolation_context,
const url::Origin& origin,
bool origin_requests_isolation) { … }
bool ChildProcessSecurityPolicyImpl::IsGloballyIsolatedOriginForTesting(
const url::Origin& origin) { … }
std::vector<url::Origin> ChildProcessSecurityPolicyImpl::GetIsolatedOrigins(
std::optional<IsolatedOriginSource> source,
BrowserContext* browser_context) { … }
bool ChildProcessSecurityPolicyImpl::IsIsolatedSiteFromSource(
const url::Origin& origin,
IsolatedOriginSource source) { … }
bool ChildProcessSecurityPolicyImpl::GetMatchingProcessIsolatedOrigin(
const IsolationContext& isolation_context,
const url::Origin& origin,
bool requests_origin_keyed_process,
url::Origin* result) { … }
bool ChildProcessSecurityPolicyImpl::GetMatchingProcessIsolatedOrigin(
const IsolationContext& isolation_context,
const url::Origin& origin,
bool requests_origin_keyed_process,
const GURL& site_url,
url::Origin* result) { … }
OriginAgentClusterIsolationState
ChildProcessSecurityPolicyImpl::DetermineOriginAgentClusterIsolation(
const IsolationContext& isolation_context,
const url::Origin& origin,
const OriginAgentClusterIsolationState& requested_isolation_state) { … }
bool ChildProcessSecurityPolicyImpl::
HasOriginEverRequestedOriginAgentClusterValue(
BrowserContext* browser_context,
const url::Origin& origin) { … }
OriginAgentClusterIsolationState*
ChildProcessSecurityPolicyImpl::LookupOriginIsolationState(
const BrowsingInstanceId& browsing_instance_id,
const url::Origin& origin) { … }
OriginAgentClusterIsolationState*
ChildProcessSecurityPolicyImpl::LookupOriginIsolationStateForTesting(
const BrowsingInstanceId& browsing_instance_id,
const url::Origin& origin) { … }
void ChildProcessSecurityPolicyImpl::AddDefaultIsolatedOriginIfNeeded(
const IsolationContext& isolation_context,
const url::Origin& origin,
bool is_global_walk_or_frame_removal) { … }
void ChildProcessSecurityPolicyImpl::
RemoveOptInIsolatedOriginsForBrowsingInstance(
const BrowsingInstanceId& browsing_instance_id) { … }
void ChildProcessSecurityPolicyImpl::
RemoveOptInIsolatedOriginsForBrowsingInstanceInternal(
const BrowsingInstanceId browsing_instance_id) { … }
void ChildProcessSecurityPolicyImpl::AddCoopIsolatedOriginForBrowsingInstance(
const IsolationContext& isolation_context,
const url::Origin& origin,
IsolatedOriginSource source) { … }
void ChildProcessSecurityPolicyImpl::AddOriginIsolationStateForBrowsingInstance(
const IsolationContext& isolation_context,
const url::Origin& origin,
bool is_origin_agent_cluster,
bool requires_origin_keyed_process) { … }
bool ChildProcessSecurityPolicyImpl::UpdateOriginIsolationOptInListIfNecessary(
BrowserContext* browser_context,
const url::Origin& origin) { … }
void ChildProcessSecurityPolicyImpl::RemoveIsolatedOriginForTesting(
const url::Origin& origin) { … }
void ChildProcessSecurityPolicyImpl::ClearIsolatedOriginsForTesting() { … }
ChildProcessSecurityPolicyImpl::SecurityState*
ChildProcessSecurityPolicyImpl::GetSecurityState(int child_id) { … }
std::vector<IsolatedOriginPattern>
ChildProcessSecurityPolicyImpl::ParseIsolatedOrigins(
std::string_view pattern_list) { … }
std::string ChildProcessSecurityPolicyImpl::GetKilledProcessOriginLock(
const SecurityState* security_state) { … }
void ChildProcessSecurityPolicyImpl::LogKilledProcessOriginLock(int child_id) { … }
ChildProcessSecurityPolicyImpl::Handle
ChildProcessSecurityPolicyImpl::CreateHandle(int child_id) { … }
bool ChildProcessSecurityPolicyImpl::AddProcessReference(
int child_id,
bool duplicating_handle) { … }
bool ChildProcessSecurityPolicyImpl::AddProcessReferenceLocked(
int child_id,
bool duplicating_handle) { … }
void ChildProcessSecurityPolicyImpl::RemoveProcessReference(int child_id) { … }
void ChildProcessSecurityPolicyImpl::RemoveProcessReferenceLocked(
int child_id) { … }
}