feat: sandbox renderer processes for cross-origin frames (#18650)
This commit is contained in:
parent
23286fe557
commit
f3f2990b9e
8 changed files with 139 additions and 10 deletions
|
@ -59,6 +59,11 @@ bool IsBrowserProcess(base::CommandLine* cmd) {
|
|||
return process_type.empty();
|
||||
}
|
||||
|
||||
bool IsSandboxEnabled(base::CommandLine* command_line) {
|
||||
return command_line->HasSwitch(switches::kEnableSandbox) ||
|
||||
!command_line->HasSwitch(service_manager::switches::kNoSandbox);
|
||||
}
|
||||
|
||||
// Returns true if this subprocess type needs the ResourceBundle initialized
|
||||
// and resources loaded.
|
||||
bool SubprocessNeedsResourceBundle(const std::string& process_type) {
|
||||
|
@ -281,10 +286,9 @@ content::ContentGpuClient* AtomMainDelegate::CreateContentGpuClient() {
|
|||
|
||||
content::ContentRendererClient*
|
||||
AtomMainDelegate::CreateContentRendererClient() {
|
||||
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kEnableSandbox) ||
|
||||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
service_manager::switches::kNoSandbox)) {
|
||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||
|
||||
if (IsSandboxEnabled(command_line)) {
|
||||
renderer_client_.reset(new AtomSandboxedRendererClient);
|
||||
} else {
|
||||
renderer_client_.reset(new AtomRendererClient);
|
||||
|
|
|
@ -1213,6 +1213,18 @@ base::ProcessId WebContents::GetOSProcessID() const {
|
|||
return base::GetProcId(process_handle);
|
||||
}
|
||||
|
||||
base::ProcessId WebContents::GetOSProcessIdForFrame(
|
||||
const std::string& name,
|
||||
const std::string& document_url) const {
|
||||
for (auto* frame : web_contents()->GetAllFrames()) {
|
||||
if (frame->GetFrameName() == name &&
|
||||
frame->GetLastCommittedURL().spec() == document_url) {
|
||||
return base::GetProcId(frame->GetProcess()->GetProcess().Handle());
|
||||
}
|
||||
}
|
||||
return base::kNullProcessId;
|
||||
}
|
||||
|
||||
WebContents::Type WebContents::GetType() const {
|
||||
return type_;
|
||||
}
|
||||
|
@ -2194,6 +2206,8 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
|||
&WebContents::SetBackgroundThrottling)
|
||||
.SetMethod("getProcessId", &WebContents::GetProcessID)
|
||||
.SetMethod("getOSProcessId", &WebContents::GetOSProcessID)
|
||||
.SetMethod("_getOSProcessIdForFrame",
|
||||
&WebContents::GetOSProcessIdForFrame)
|
||||
.SetMethod("equal", &WebContents::Equal)
|
||||
.SetMethod("_loadURL", &WebContents::LoadURL)
|
||||
.SetMethod("downloadURL", &WebContents::DownloadURL)
|
||||
|
|
|
@ -138,6 +138,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
|||
void SetBackgroundThrottling(bool allowed);
|
||||
int GetProcessID() const;
|
||||
base::ProcessId GetOSProcessID() const;
|
||||
base::ProcessId GetOSProcessIdForFrame(const std::string& name,
|
||||
const std::string& document_url) const;
|
||||
Type GetType() const;
|
||||
bool Equal(const WebContents* web_contents) const;
|
||||
void LoadURL(const GURL& url, const mate::Dictionary& options);
|
||||
|
|
|
@ -327,6 +327,10 @@ void AtomBrowserClient::ConsiderSiteInstanceForAffinity(
|
|||
}
|
||||
}
|
||||
|
||||
bool AtomBrowserClient::IsRendererSubFrame(int process_id) const {
|
||||
return base::ContainsKey(renderer_is_subframe_, process_id);
|
||||
}
|
||||
|
||||
void AtomBrowserClient::RenderProcessWillLaunch(
|
||||
content::RenderProcessHost* host,
|
||||
service_manager::mojom::ServiceRequest* service_request) {
|
||||
|
@ -463,6 +467,11 @@ void AtomBrowserClient::RegisterPendingSiteInstance(
|
|||
auto* web_contents = content::WebContents::FromRenderFrameHost(rfh);
|
||||
auto* pending_process = pending_site_instance->GetProcess();
|
||||
pending_processes_[pending_process->GetID()] = web_contents;
|
||||
|
||||
if (rfh->GetParent())
|
||||
renderer_is_subframe_.insert(pending_process->GetID());
|
||||
else
|
||||
renderer_is_subframe_.erase(pending_process->GetID());
|
||||
}
|
||||
|
||||
void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
|
@ -513,7 +522,8 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
|||
}
|
||||
auto* web_preferences = WebContentsPreferences::From(web_contents);
|
||||
if (web_preferences)
|
||||
web_preferences->AppendCommandLineSwitches(command_line);
|
||||
web_preferences->AppendCommandLineSwitches(
|
||||
command_line, IsRendererSubFrame(process_id));
|
||||
SessionPreferences::AppendExtraCommandLineSwitches(
|
||||
web_contents->GetBrowserContext(), command_line);
|
||||
if (CanUseCustomSiteInstance()) {
|
||||
|
@ -752,6 +762,7 @@ void AtomBrowserClient::RenderProcessHostDestroyed(
|
|||
content::RenderProcessHost* host) {
|
||||
int process_id = host->GetID();
|
||||
pending_processes_.erase(process_id);
|
||||
renderer_is_subframe_.erase(process_id);
|
||||
RemoveProcessPreferences(process_id);
|
||||
}
|
||||
|
||||
|
|
|
@ -235,11 +235,15 @@ class AtomBrowserClient : public content::ContentBrowserClient,
|
|||
void ConsiderSiteInstanceForAffinity(content::RenderFrameHost* rfh,
|
||||
content::SiteInstance* site_instance);
|
||||
|
||||
bool IsRendererSubFrame(int process_id) const;
|
||||
|
||||
// pending_render_process => web contents.
|
||||
std::map<int, content::WebContents*> pending_processes_;
|
||||
|
||||
std::map<int, base::ProcessId> render_process_host_pids_;
|
||||
|
||||
std::set<int> renderer_is_subframe_;
|
||||
|
||||
// list of site per affinity. weak_ptr to prevent instance locking
|
||||
std::map<std::string, content::SiteInstance*> site_per_affinities_;
|
||||
|
||||
|
|
|
@ -271,7 +271,8 @@ WebContentsPreferences* WebContentsPreferences::From(
|
|||
}
|
||||
|
||||
void WebContentsPreferences::AppendCommandLineSwitches(
|
||||
base::CommandLine* command_line) {
|
||||
base::CommandLine* command_line,
|
||||
bool is_subframe) {
|
||||
// Check if plugins are enabled.
|
||||
if (IsEnabled(options::kPlugins))
|
||||
command_line->AppendSwitch(switches::kEnablePlugins);
|
||||
|
@ -293,10 +294,16 @@ void WebContentsPreferences::AppendCommandLineSwitches(
|
|||
if (IsEnabled(options::kWebviewTag))
|
||||
command_line->AppendSwitch(switches::kWebviewTag);
|
||||
|
||||
// Sandbox can be enabled for renderer processes hosting cross-origin frames
|
||||
// unless nodeIntegrationInSubFrames is enabled
|
||||
bool can_sandbox_frame =
|
||||
is_subframe && !IsEnabled(options::kNodeIntegrationInSubFrames);
|
||||
|
||||
// If the `sandbox` option was passed to the BrowserWindow's webPreferences,
|
||||
// pass `--enable-sandbox` to the renderer so it won't have any node.js
|
||||
// integration.
|
||||
if (IsEnabled(options::kSandbox)) {
|
||||
// integration. Otherwise disable Chromium sandbox, unless app.enableSandbox()
|
||||
// was called.
|
||||
if (IsEnabled(options::kSandbox) || can_sandbox_frame) {
|
||||
command_line->AppendSwitch(switches::kEnableSandbox);
|
||||
} else if (!command_line->HasSwitch(switches::kEnableSandbox)) {
|
||||
command_line->AppendSwitch(service_manager::switches::kNoSandbox);
|
||||
|
|
|
@ -47,7 +47,8 @@ class WebContentsPreferences
|
|||
void Merge(const base::DictionaryValue& new_web_preferences);
|
||||
|
||||
// Append command paramters according to preferences.
|
||||
void AppendCommandLineSwitches(base::CommandLine* command_line);
|
||||
void AppendCommandLineSwitches(base::CommandLine* command_line,
|
||||
bool is_subframe);
|
||||
|
||||
// Modify the WebPreferences according to preferences.
|
||||
void OverrideWebkitPrefs(content::WebPreferences* prefs);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue