diff --git a/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/sandbox.rs b/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/sandbox.rs index ef5884cf4f5..e9da982b7b7 100644 --- a/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/sandbox.rs +++ b/apps/desktop/desktop_native/chromium_importer/src/chromium/platform/sandbox.rs @@ -1,9 +1,8 @@ /// Sandbox specific (for Mac App Store Builds) - use anyhow::{anyhow, Result}; use serde::{Deserialize, Serialize}; -// Bundle IDs of supported Chromium browsers - used to determine if browser is installed +// Bundle IDs of supported Chromium browsers - used to determine if browser is installed const BROWSER_BUNDLE_IDS: &[(&str, &str)] = &[ ("Chrome", "com.google.Chrome"), ("Chromium", "org.chromium.Chromium"), @@ -15,12 +14,16 @@ const BROWSER_BUNDLE_IDS: &[(&str, &str)] = &[ ]; #[derive(Debug, Deserialize)] -#[serde(tag = "type")] +#[serde(rename_all = "camelCase")] +struct CheckBrowserInstalledResponse { + is_installed: bool, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", tag = "type")] enum CommandResult { // rename = "camelCase" was a review suggestion with breaking changes - #[serde(rename = "success")] Success { value: T }, - #[serde(rename = "error")] Error { error: String }, } @@ -202,9 +205,3 @@ async fn is_browser_installed(browser_name: &str) -> Result { CommandResult::Error { error } => Err(anyhow!("{}", error)), } } - -#[derive(Debug, Deserialize)] -struct CheckBrowserInstalledResponse { - #[serde(rename = "isInstalled")] - is_installed: bool, -} diff --git a/apps/desktop/desktop_native/objc/src/native/chromium_importer/browser_access_manager.m b/apps/desktop/desktop_native/objc/src/native/chromium_importer/browser_access_manager.m index bd34b30f445..f36a9df4ca3 100644 --- a/apps/desktop/desktop_native/objc/src/native/chromium_importer/browser_access_manager.m +++ b/apps/desktop/desktop_native/objc/src/native/chromium_importer/browser_access_manager.m @@ -51,9 +51,34 @@ return nil; } + // Compare the selected path against the expected browser directory + NSString *expectedPath = browserPath.path; + NSString *selectedPath = selectedURL.path; + if (![selectedPath isEqualToString:expectedPath]) { + return nil; + } + + // Validate the selected directory contains a Local State file NSURL *localStatePath = [selectedURL URLByAppendingPathComponent:@"Local State"]; if (![[NSFileManager defaultManager] fileExistsAtPath:localStatePath.path]) { - // Invalid directory selected caller will handle + return nil; + } + + // Validate Local State contains expected Chromium structure + NSData *localStateData = [NSData dataWithContentsOfURL:localStatePath]; + if (!localStateData) { + return nil; + } + NSError *jsonError = nil; + id jsonObject = [NSJSONSerialization JSONObjectWithData:localStateData options:0 error:&jsonError]; + if (!jsonObject || ![jsonObject isKindOfClass:[NSDictionary class]]) { + return nil; + } + + NSDictionary *localState = (NSDictionary *)jsonObject; + + // Verify essential Chromium/Chrome keys exist to confirm this is actually a browser data directory + if (!localState[@"profile"] && !localState[@"browser"]) { return nil; } @@ -145,7 +170,6 @@ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *key = [self bookmarkKeyFor:browserName]; [defaults setObject:data forKey:key]; - [defaults synchronize]; } - (NSData *)loadBookmarkForBrowser:(NSString *)browserName {