From a9b9cdbec1473e19465951c2911ef91b32c16ecb Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 16 Jun 2026 15:06:48 +0200 Subject: [PATCH] LibWebView: Make helper sandboxing opt-out Apply helper process sandboxing by default and replace the old --enable-sandbox switch with --disable-sandbox. Propagate the opt-out from Ladybird, test-web, and WebDriver to WebContent, WebWorker, RequestServer, ImageDecoder, and Compositor. --- Libraries/LibWebView/Application.cpp | 6 +++--- Libraries/LibWebView/HelperProcess.cpp | 20 ++++++++++---------- Libraries/LibWebView/Options.h | 4 ++-- Services/Compositor/main.cpp | 6 +++--- Services/ImageDecoder/main.cpp | 6 +++--- Services/RequestServer/main.cpp | 6 +++--- Services/WebContent/main.cpp | 6 +++--- Services/WebDriver/main.cpp | 8 ++++++-- Services/WebWorker/main.cpp | 6 +++--- 9 files changed, 36 insertions(+), 32 deletions(-) diff --git a/Libraries/LibWebView/Application.cpp b/Libraries/LibWebView/Application.cpp index b6ae00289d..e9c51593e9 100644 --- a/Libraries/LibWebView/Application.cpp +++ b/Libraries/LibWebView/Application.cpp @@ -193,7 +193,7 @@ ErrorOr Application::initialize(Main::Arguments const& arguments) bool disable_http_memory_cache = false; bool disable_http_disk_cache = false; bool disable_content_blocker = false; - bool enable_sandbox = false; + bool disable_sandbox = false; Vector content_blocker_list_paths; Optional resource_substitution_map_path; bool enable_autoplay = false; @@ -269,7 +269,7 @@ ErrorOr Application::initialize(Main::Arguments const& arguments) args_parser.add_option(disable_http_memory_cache, "Disable HTTP memory cache", "disable-http-memory-cache"); args_parser.add_option(disable_http_disk_cache, "Disable HTTP disk cache", "disable-http-disk-cache"); args_parser.add_option(disable_content_blocker, "Disable content blocker", "disable-content-blocker"); - args_parser.add_option(enable_sandbox, "Enable helper process sandboxing", "enable-sandbox"); + args_parser.add_option(disable_sandbox, "Disable helper process sandboxing", "disable-sandbox"); args_parser.add_option(Core::ArgsParser::Option { .argument_mode = Core::ArgsParser::OptionArgumentMode::Required, .help_string = "Path to a content blocker list. May be specified multiple times.", @@ -393,7 +393,7 @@ ErrorOr Application::initialize(Main::Arguments const& arguments) : OptionalNone()), .devtools_port = devtools_port, .enable_content_blocker = disable_content_blocker ? EnableContentBlocker::No : EnableContentBlocker::Yes, - .enable_sandbox = enable_sandbox ? EnableSandbox::Yes : EnableSandbox::No, + .disable_sandbox = disable_sandbox ? DisableSandbox::Yes : DisableSandbox::No, .content_blocker_list_paths = move(content_blocker_list_paths_as_byte_strings), }; diff --git a/Libraries/LibWebView/HelperProcess.cpp b/Libraries/LibWebView/HelperProcess.cpp index efb302768c..dc660025bd 100644 --- a/Libraries/LibWebView/HelperProcess.cpp +++ b/Libraries/LibWebView/HelperProcess.cpp @@ -124,8 +124,8 @@ ErrorOr> launch_web_content_process(u64 arguments.append("--tuple-file-origins"sv); if (web_content_options.report_session_history_updates_in_test_mode == ReportSessionHistoryUpdatesInTestMode::Yes) arguments.append("--report-session-history-updates-in-test-mode"sv); - if (browser_options.enable_sandbox == EnableSandbox::Yes) - arguments.append("--enable-sandbox"sv); + if (browser_options.disable_sandbox == DisableSandbox::Yes) + arguments.append("--disable-sandbox"sv); if (auto const maybe_echo_server_port = web_content_options.echo_server_port; maybe_echo_server_port.has_value()) { arguments.append("--echo-server-port"sv); @@ -153,8 +153,8 @@ ErrorOr> launch_image_decoder_process( auto const& browser_options = WebView::Application::browser_options(); Vector arguments; - if (browser_options.enable_sandbox == EnableSandbox::Yes) - arguments.append("--enable-sandbox"sv); + if (browser_options.disable_sandbox == DisableSandbox::Yes) + arguments.append("--disable-sandbox"sv); if (auto server = mach_server_name(); server.has_value()) { arguments.append("--mach-server-name"sv); arguments.append(server.value()); @@ -169,8 +169,8 @@ ErrorOr> launch_compositor_process() auto const& web_content_options = WebView::Application::web_content_options(); Vector arguments; - if (browser_options.enable_sandbox == EnableSandbox::Yes) - arguments.append("--enable-sandbox"sv); + if (browser_options.disable_sandbox == DisableSandbox::Yes) + arguments.append("--disable-sandbox"sv); if (web_content_options.force_cpu_painting == WebView::ForceCPUPainting::Yes) arguments.append("--force-cpu-painting"sv); if (web_content_options.force_fontconfig == WebView::ForceFontconfig::Yes) @@ -192,8 +192,8 @@ ErrorOr> launch_web_worker_process(Web::Bindings: Vector arguments; - if (browser_options.enable_sandbox == EnableSandbox::Yes) - arguments.append("--enable-sandbox"sv); + if (browser_options.disable_sandbox == DisableSandbox::Yes) + arguments.append("--disable-sandbox"sv); if (web_content_options.expose_experimental_interfaces == WebView::ExposeExperimentalInterfaces::Yes) arguments.append("--expose-experimental-interfaces"sv); if (web_content_options.enable_http_memory_cache == WebView::EnableMemoryHTTPCache::Yes) @@ -231,8 +231,8 @@ ErrorOr> launch_request_server_process() Vector arguments; - if (browser_options.enable_sandbox == EnableSandbox::Yes) - arguments.append("--enable-sandbox"sv); + if (browser_options.disable_sandbox == DisableSandbox::Yes) + arguments.append("--disable-sandbox"sv); for (auto const& certificate : request_server_options.certificates) arguments.append(ByteString::formatted("--certificate={}", certificate)); diff --git a/Libraries/LibWebView/Options.h b/Libraries/LibWebView/Options.h index 28a43be82e..b5fa538ef2 100644 --- a/Libraries/LibWebView/Options.h +++ b/Libraries/LibWebView/Options.h @@ -74,7 +74,7 @@ enum class EnableContentBlocker { Yes, }; -enum class EnableSandbox { +enum class DisableSandbox { No, Yes, }; @@ -98,7 +98,7 @@ struct BrowserOptions { Optional dns_settings {}; Optional devtools_port; EnableContentBlocker enable_content_blocker { EnableContentBlocker::Yes }; - EnableSandbox enable_sandbox { EnableSandbox::No }; + DisableSandbox disable_sandbox { DisableSandbox::No }; Vector content_blocker_list_paths {}; }; diff --git a/Services/Compositor/main.cpp b/Services/Compositor/main.cpp index 8bfb3eaa06..4afe36b4da 100644 --- a/Services/Compositor/main.cpp +++ b/Services/Compositor/main.cpp @@ -25,7 +25,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) bool force_cpu_painting = false; bool force_fontconfig = false; bool disable_async_scrolling = false; - bool enable_sandbox = false; + bool disable_sandbox = false; Core::ArgsParser args_parser; args_parser.add_option(mach_server_name, "Mach server name", "mach-server-name", 0, "mach_server_name"); @@ -33,7 +33,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) args_parser.add_option(force_cpu_painting, "Force CPU painting", "force-cpu-painting"); args_parser.add_option(force_fontconfig, "Force using fontconfig for font loading", "force-fontconfig"); args_parser.add_option(disable_async_scrolling, "Disable async scrolling", "disable-async-scrolling"); - args_parser.add_option(enable_sandbox, "Enable process sandboxing", "enable-sandbox"); + args_parser.add_option(disable_sandbox, "Disable process sandboxing", "disable-sandbox"); args_parser.parse(arguments); if (wait_for_debugger) @@ -51,7 +51,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) Gfx::SkiaBackendContext::initialize_gpu_backend(); auto skia_backend_context = Gfx::SkiaBackendContext::the_main_thread_context(); - if (enable_sandbox) + if (!disable_sandbox) TRY(Compositor::apply_sandbox()); auto& event_loop = Core::EventLoop::initialize_for_current_thread(); diff --git a/Services/ImageDecoder/main.cpp b/Services/ImageDecoder/main.cpp index 82b41fb673..66c8d58ce4 100644 --- a/Services/ImageDecoder/main.cpp +++ b/Services/ImageDecoder/main.cpp @@ -21,17 +21,17 @@ ErrorOr ladybird_main(Main::Arguments arguments) Core::ArgsParser args_parser; StringView mach_server_name; bool wait_for_debugger = false; - bool enable_sandbox = false; + bool disable_sandbox = false; args_parser.add_option(mach_server_name, "Mach server name", "mach-server-name", 0, "mach_server_name"); args_parser.add_option(wait_for_debugger, "Wait for debugger", "wait-for-debugger"); - args_parser.add_option(enable_sandbox, "Enable process sandboxing", "enable-sandbox"); + args_parser.add_option(disable_sandbox, "Disable process sandboxing", "disable-sandbox"); args_parser.parse(arguments); if (wait_for_debugger) Core::Process::wait_for_debugger_and_break(); - if (enable_sandbox) + if (!disable_sandbox) TRY(ImageDecoder::apply_sandbox()); auto& event_loop = Core::EventLoop::initialize_for_current_thread(); diff --git a/Services/RequestServer/main.cpp b/Services/RequestServer/main.cpp index 95c6d9bdcb..f07ff5550d 100644 --- a/Services/RequestServer/main.cpp +++ b/Services/RequestServer/main.cpp @@ -44,7 +44,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) StringView http_disk_cache_mode; StringView resource_map_path; bool wait_for_debugger = false; - bool enable_sandbox = false; + bool disable_sandbox = false; Core::ArgsParser args_parser; args_parser.add_option(certificates, "Path to a certificate file", "certificate", 'C', "certificate"); @@ -52,7 +52,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) args_parser.add_option(http_disk_cache_mode, "HTTP disk cache mode", "http-disk-cache-mode", 0, "mode"); args_parser.add_option(resource_map_path, "Path to JSON file mapping URLs to local files", "resource-map", 0, "path"); args_parser.add_option(wait_for_debugger, "Wait for debugger", "wait-for-debugger"); - args_parser.add_option(enable_sandbox, "Enable process sandboxing", "enable-sandbox"); + args_parser.add_option(disable_sandbox, "Disable process sandboxing", "disable-sandbox"); args_parser.parse(arguments); if (wait_for_debugger) @@ -100,7 +100,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) disk_cache = cache.release_value(); } - if (enable_sandbox) + if (!disable_sandbox) TRY(RequestServer::apply_sandbox(certificates)); // Connections are stored on the stack to ensure they are destroyed before static destruction begins. This prevents diff --git a/Services/WebContent/main.cpp b/Services/WebContent/main.cpp index c855e1b05b..cf7205c718 100644 --- a/Services/WebContent/main.cpp +++ b/Services/WebContent/main.cpp @@ -151,7 +151,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) bool is_headless = false; bool disable_scrollbar_painting = false; bool disable_async_scrolling = false; - bool enable_sandbox = false; + bool disable_sandbox = false; bool report_session_history_updates_in_test_mode = false; StringView echo_server_port_string_view {}; StringView default_time_zone {}; @@ -175,7 +175,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) args_parser.add_option(collect_garbage_on_every_allocation, "Collect garbage after every JS heap allocation", "collect-garbage-on-every-allocation"); args_parser.add_option(disable_scrollbar_painting, "Don't paint horizontal or vertical viewport scrollbars", "disable-scrollbar-painting"); args_parser.add_option(disable_async_scrolling, "Disable async scrolling", "disable-async-scrolling"); - args_parser.add_option(enable_sandbox, "Enable process sandboxing", "enable-sandbox"); + args_parser.add_option(disable_sandbox, "Disable process sandboxing", "disable-sandbox"); args_parser.add_option(report_session_history_updates_in_test_mode, "Report session history updates in test mode", "report-session-history-updates-in-test-mode"); args_parser.add_option(echo_server_port_string_view, "Echo server port used in test internals", "echo-server-port", 0, "echo_server_port"); args_parser.add_option(is_headless, "Report that the browser is running in headless mode", "headless"); @@ -262,7 +262,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) if (maybe_content_blocker_error.is_error()) dbgln("Failed to load content blockers: {}", maybe_content_blocker_error.error()); - if (enable_sandbox) + if (!disable_sandbox) TRY(RendererSandbox::apply_sandbox(config_path)); #if defined(AK_OS_MACOS) diff --git a/Services/WebDriver/main.cpp b/Services/WebDriver/main.cpp index 9c7fbe6055..16eecb33e1 100644 --- a/Services/WebDriver/main.cpp +++ b/Services/WebDriver/main.cpp @@ -34,7 +34,7 @@ static ErrorOr launch_process(StringView application, ReadonlySpa return result; } -static Vector create_arguments(ByteString const& webdriver_endpoint, bool headless, bool expose_experimental_interfaces, bool force_cpu_painting, Optional debug_process, Optional default_time_zone) +static Vector create_arguments(ByteString const& webdriver_endpoint, bool headless, bool expose_experimental_interfaces, bool force_cpu_painting, bool disable_sandbox, Optional debug_process, Optional default_time_zone) { Vector arguments; #if defined(AK_OS_MACOS) @@ -61,6 +61,8 @@ static Vector create_arguments(ByteString const& webdriver_endpoint, arguments.append("--expose-experimental-interfaces"sv); if (force_cpu_painting) arguments.append("--force-cpu-painting"sv); + if (disable_sandbox) + arguments.append("--disable-sandbox"sv); if (debug_process.has_value()) arguments.append(ByteString::formatted("--debug-process={}", debug_process.value())); @@ -84,6 +86,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) int port = 8000; bool expose_experimental_interfaces = false; bool force_cpu_painting = false; + bool disable_sandbox = false; bool headless = false; Optional debug_process; Optional default_time_zone; @@ -94,6 +97,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) args_parser.add_option(certificates, "Path to a certificate file", "certificate", 'C', "certificate"); args_parser.add_option(expose_experimental_interfaces, "Expose experimental IDL interfaces", "expose-experimental-interfaces"); args_parser.add_option(force_cpu_painting, "Launch browser with GPU painting disabled", "force-cpu-painting"); + args_parser.add_option(disable_sandbox, "Launch browser with helper process sandboxing disabled", "disable-sandbox"); args_parser.add_option(debug_process, "Wait for a debugger to attach to the given process name (WebContent, RequestServer, etc.)", "debug-process", 0, "process-name"); args_parser.add_option(headless, "Launch browser without a graphical interface", "headless"); args_parser.add_option(default_time_zone, "Default time zone", "default-time-zone", 0, "time-zone-id"); @@ -137,7 +141,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) } auto launch_browser_callback = [&](ByteString const& webdriver_endpoint, bool headless) { - auto arguments = create_arguments(webdriver_endpoint, headless, expose_experimental_interfaces, force_cpu_painting, debug_process, default_time_zone); + auto arguments = create_arguments(webdriver_endpoint, headless, expose_experimental_interfaces, force_cpu_painting, disable_sandbox, debug_process, default_time_zone); return launch_process("Ladybird"sv, arguments.span()); }; diff --git a/Services/WebWorker/main.cpp b/Services/WebWorker/main.cpp index adb62ad6c9..7bd3dafac1 100644 --- a/Services/WebWorker/main.cpp +++ b/Services/WebWorker/main.cpp @@ -57,7 +57,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) bool enable_http_memory_cache = false; bool wait_for_debugger = false; bool file_origins_are_tuple_origins = false; - bool enable_sandbox = false; + bool disable_sandbox = false; Core::ArgsParser args_parser; args_parser.add_option(serenity_resource_root, "Absolute path to directory for serenity resources", "serenity-resource-root", 'r', "serenity-resource-root"); @@ -68,7 +68,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) args_parser.add_option(worker_type_string, "Type of WebWorker to start (dedicated, shared, or service)", "type", 't', "type"); args_parser.add_option(mach_server_name, "Mach server name", "mach-server-name", 0, "mach_server_name"); args_parser.add_option(file_origins_are_tuple_origins, "Treat file:// URLs as having tuple origins", "tuple-file-origins"); - args_parser.add_option(enable_sandbox, "Enable process sandboxing", "enable-sandbox"); + args_parser.add_option(disable_sandbox, "Disable process sandboxing", "disable-sandbox"); args_parser.parse(arguments); @@ -97,7 +97,7 @@ ErrorOr ladybird_main(Main::Arguments arguments) Web::Bindings::initialize_main_thread_vm(worker_type); - if (enable_sandbox) + if (!disable_sandbox) TRY(RendererSandbox::apply_sandbox({})); auto client = TRY(IPC::take_over_accepted_client_from_system_server(mach_server_name));