mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 11:36:10 +00:00
LibWeb+LibWebView+WebContent: Begin implementing simple site islotation
Site isolation is a common technique to reduce the chance that malicious sites can access data from other sites. When the user navigates, we now check if the target site is the same as the current site. If not, we instruct the UI to perform the navigation in a new WebContent process. The phrase "site" here is defined as the public suffix of the URL plus one level. This means that navigating from "www.example.com" to "sub.example.com" remains in the same process. There's plenty of room for optimization around this. For example, we can create a spare WebContent process ahead of time to hot-swap the target site. We can also create a policy to keep the navigated-from process around, in case the user quickly navigates back.
This commit is contained in:
parent
a34f7a5bd1
commit
5810c8073e
Notes:
github-actions[bot]
2025-03-11 11:11:49 +00:00
Author: https://github.com/trflynn89 Commit: https://github.com/LadybirdBrowser/ladybird/commit/5810c8073e7 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3882 Reviewed-by: https://github.com/gmta ✅
12 changed files with 94 additions and 0 deletions
|
@ -1349,6 +1349,12 @@ WebIDL::ExceptionOr<void> Navigable::navigate(NavigateParams params)
|
|||
auto& active_document = *this->active_document();
|
||||
auto& realm = active_document.realm();
|
||||
|
||||
// AD-HOC: If we are not able to continue in this process, request a new process from the UI.
|
||||
if (!active_document.page().client().is_url_suitable_for_same_process_navigation(active_document.url(), params.url)) {
|
||||
active_document.page().client().request_new_process_for_navigation(params.url);
|
||||
return {};
|
||||
}
|
||||
|
||||
// 2. Let sourceSnapshotParams be the result of snapshotting source snapshot params given sourceDocument.
|
||||
auto source_snapshot_params = source_document->snapshot_source_snapshot_params();
|
||||
|
||||
|
|
|
@ -321,6 +321,8 @@ public:
|
|||
virtual Page& page() = 0;
|
||||
virtual Page const& page() const = 0;
|
||||
virtual bool is_connection_open() const = 0;
|
||||
virtual bool is_url_suitable_for_same_process_navigation([[maybe_unused]] URL::URL const& current_url, [[maybe_unused]] URL::URL const& target_url) const { return true; }
|
||||
virtual void request_new_process_for_navigation(URL::URL const&) { }
|
||||
virtual Gfx::Palette palette() const = 0;
|
||||
virtual DevicePixelRect screen_rect() const = 0;
|
||||
virtual double device_pixels_per_css_pixel() const = 0;
|
||||
|
|
|
@ -16,6 +16,7 @@ set(SOURCES
|
|||
ProcessHandle.cpp
|
||||
ProcessManager.cpp
|
||||
SearchEngine.cpp
|
||||
SiteIsolation.cpp
|
||||
SourceHighlighter.cpp
|
||||
URL.cpp
|
||||
UserAgent.cpp
|
||||
|
|
31
Libraries/LibWebView/SiteIsolation.cpp
Normal file
31
Libraries/LibWebView/SiteIsolation.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibURL/URL.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/URL.h>
|
||||
#include <LibWeb/HTML/BrowsingContext.h>
|
||||
#include <LibWebView/SiteIsolation.h>
|
||||
|
||||
namespace WebView {
|
||||
|
||||
bool is_url_suitable_for_same_process_navigation(URL::URL const& current_url, URL::URL const& target_url)
|
||||
{
|
||||
// Allow navigating from about:blank to any site.
|
||||
if (Web::HTML::url_matches_about_blank(current_url))
|
||||
return true;
|
||||
|
||||
// Allow cross-scheme non-HTTP(S) navigation. Disallow cross-scheme HTTP(s) navigation.
|
||||
auto current_url_is_http = Web::Fetch::Infrastructure::is_http_or_https_scheme(current_url.scheme());
|
||||
auto target_url_is_http = Web::Fetch::Infrastructure::is_http_or_https_scheme(target_url.scheme());
|
||||
|
||||
if (!current_url_is_http || !target_url_is_http)
|
||||
return !current_url_is_http && !target_url_is_http;
|
||||
|
||||
// Disallow cross-site HTTP(S) navigation.
|
||||
return current_url.origin().is_same_site(target_url.origin());
|
||||
}
|
||||
|
||||
}
|
15
Libraries/LibWebView/SiteIsolation.h
Normal file
15
Libraries/LibWebView/SiteIsolation.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibURL/Forward.h>
|
||||
|
||||
namespace WebView {
|
||||
|
||||
[[nodiscard]] bool is_url_suitable_for_same_process_navigation(URL::URL const& current_url, URL::URL const& target_url);
|
||||
|
||||
}
|
|
@ -14,6 +14,7 @@
|
|||
#include <LibWeb/Infra/Strings.h>
|
||||
#include <LibWebView/Application.h>
|
||||
#include <LibWebView/HelperProcess.h>
|
||||
#include <LibWebView/SiteIsolation.h>
|
||||
#include <LibWebView/UserAgent.h>
|
||||
#include <LibWebView/ViewImplementation.h>
|
||||
|
||||
|
@ -89,6 +90,21 @@ u64 ViewImplementation::page_id() const
|
|||
return m_client_state.page_index;
|
||||
}
|
||||
|
||||
void ViewImplementation::create_new_process_for_cross_site_navigation(URL::URL const& url)
|
||||
{
|
||||
if (m_client_state.client)
|
||||
client().async_close_server();
|
||||
|
||||
initialize_client();
|
||||
VERIFY(m_client_state.client);
|
||||
|
||||
// Don't keep a stale backup bitmap around.
|
||||
m_backup_bitmap = nullptr;
|
||||
handle_resize();
|
||||
|
||||
load(url);
|
||||
}
|
||||
|
||||
void ViewImplementation::server_did_paint(Badge<WebContentClient>, i32 bitmap_id, Gfx::IntSize size)
|
||||
{
|
||||
if (m_client_state.back_bitmap.id == bitmap_id) {
|
||||
|
|
|
@ -58,6 +58,8 @@ public:
|
|||
|
||||
String const& handle() const { return m_client_state.client_handle; }
|
||||
|
||||
void create_new_process_for_cross_site_navigation(URL::URL const&);
|
||||
|
||||
void server_did_paint(Badge<WebContentClient>, i32 bitmap_id, Gfx::IntSize size);
|
||||
|
||||
void set_window_position(Gfx::IntPoint);
|
||||
|
|
|
@ -62,6 +62,12 @@ void WebContentClient::did_paint(u64 page_id, Gfx::IntRect rect, i32 bitmap_id)
|
|||
view->server_did_paint({}, bitmap_id, rect.size());
|
||||
}
|
||||
|
||||
void WebContentClient::did_request_new_process_for_navigation(u64 page_id, URL::URL url)
|
||||
{
|
||||
if (auto view = view_for_page_id(page_id); view.has_value())
|
||||
view->create_new_process_for_cross_site_navigation(url);
|
||||
}
|
||||
|
||||
void WebContentClient::did_start_loading(u64 page_id, URL::URL url, bool is_redirect)
|
||||
{
|
||||
if (auto process = WebView::Application::the().find_process(m_process_handle.pid); process.has_value())
|
||||
|
|
|
@ -52,6 +52,7 @@ private:
|
|||
virtual void die() override;
|
||||
|
||||
virtual void did_paint(u64 page_id, Gfx::IntRect, i32) override;
|
||||
virtual void did_request_new_process_for_navigation(u64 page_id, URL::URL url) override;
|
||||
virtual void did_finish_loading(u64 page_id, URL::URL) override;
|
||||
virtual void did_request_refresh(u64 page_id) override;
|
||||
virtual void did_request_cursor_change(u64 page_id, Gfx::Cursor) override;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <LibWeb/Painting/PaintableBox.h>
|
||||
#include <LibWeb/Painting/ViewportPaintable.h>
|
||||
#include <LibWebView/Attribute.h>
|
||||
#include <LibWebView/SiteIsolation.h>
|
||||
#include <WebContent/ConnectionFromClient.h>
|
||||
#include <WebContent/DevToolsConsoleClient.h>
|
||||
#include <WebContent/InspectorConsoleClient.h>
|
||||
|
@ -134,6 +135,16 @@ bool PageClient::is_connection_open() const
|
|||
return client().is_open();
|
||||
}
|
||||
|
||||
bool PageClient::is_url_suitable_for_same_process_navigation(URL::URL const& current_url, URL::URL const& target_url) const
|
||||
{
|
||||
return WebView::is_url_suitable_for_same_process_navigation(current_url, target_url);
|
||||
}
|
||||
|
||||
void PageClient::request_new_process_for_navigation(URL::URL const& url)
|
||||
{
|
||||
client().async_did_request_new_process_for_navigation(m_id, url);
|
||||
}
|
||||
|
||||
Gfx::Palette PageClient::palette() const
|
||||
{
|
||||
return Gfx::Palette(*m_palette_impl);
|
||||
|
|
|
@ -111,6 +111,8 @@ private:
|
|||
|
||||
// ^PageClient
|
||||
virtual bool is_connection_open() const override;
|
||||
virtual bool is_url_suitable_for_same_process_navigation(URL::URL const& current_url, URL::URL const& target_url) const override;
|
||||
virtual void request_new_process_for_navigation(URL::URL const&) override;
|
||||
virtual Gfx::Palette palette() const override;
|
||||
virtual Web::DevicePixelRect screen_rect() const override { return m_screen_rect; }
|
||||
virtual Web::CSS::PreferredColorScheme preferred_color_scheme() const override { return m_preferred_color_scheme; }
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
endpoint WebContentClient
|
||||
{
|
||||
did_request_new_process_for_navigation(u64 page_id, URL::URL url) =|
|
||||
did_start_loading(u64 page_id, URL::URL url, bool is_redirect) =|
|
||||
did_finish_loading(u64 page_id, URL::URL url) =|
|
||||
did_request_refresh(u64 page_id) =|
|
||||
|
|
Loading…
Add table
Reference in a new issue