diff --git a/chromium_src/ios/web/public/web_client.h b/chromium_src/ios/web/public/web_client.h index 14f691d2945f..2b163270b86d 100644 --- a/chromium_src/ios/web/public/web_client.h +++ b/chromium_src/ios/web/public/web_client.h @@ -2,10 +2,11 @@ #include #include "ios/web/webui/mojo_facade.h" +#include "ios/web/public/web_state.h" #define IsBrowserLockdownModeEnabled \ IsWebUIMessageAllowedForFrame(WKFrameInfo* frame, const GURL& origin, \ - NSString** prompt, web::MojoFacade* facade); \ + NSString** prompt, web::MojoFacade* facade, web::WebState* webState); \ virtual bool IsBrowserLockdownModeEnabled #include "src/ios/web/public/web_client.h" diff --git a/chromium_src/ios/web/web_client.mm b/chromium_src/ios/web/web_client.mm index 2f347a31e7e0..9c5c65d7025e 100644 --- a/chromium_src/ios/web/web_client.mm +++ b/chromium_src/ios/web/web_client.mm @@ -3,7 +3,7 @@ #define IsBrowserLockdownModeEnabled \ IsWebUIMessageAllowedForFrame(WKFrameInfo* frame, const GURL& origin, \ - NSString** prompt, web::MojoFacade* facade) { \ + NSString** prompt, web::MojoFacade* facade, web::WebState* webState) { \ return false; \ } \ bool WebClient::IsBrowserLockdownModeEnabled diff --git a/chromium_src/ios/web/web_state/ui/crw_wk_ui_handler.mm b/chromium_src/ios/web/web_state/ui/crw_wk_ui_handler.mm index a662d4bea2cf..0f41853004e9 100644 --- a/chromium_src/ios/web/web_state/ui/crw_wk_ui_handler.mm +++ b/chromium_src/ios/web/web_state/ui/crw_wk_ui_handler.mm @@ -5,7 +5,7 @@ #define IsAppSpecificURL(URL) \ IsAppSpecificURL(URL) && web::GetWebClient()->IsWebUIMessageAllowedForFrame( \ - frame, origin, &prompt, self.mojoFacade) + frame, origin, &prompt, self.mojoFacade, self.webStateImpl) #include "src/ios/web/web_state/ui/crw_wk_ui_handler.mm" diff --git a/ios/browser/brave_web_client.h b/ios/browser/brave_web_client.h index 82a66a8c13dd..cde0655f033f 100644 --- a/ios/browser/brave_web_client.h +++ b/ios/browser/brave_web_client.h @@ -9,6 +9,8 @@ #include #include #include +#include +#include "base/functional/callback_forward.h" #include "ios/chrome/browser/web/model/chrome_web_client.h" @@ -41,10 +43,26 @@ class BraveWebClient : public ChromeWebClient { bool IsWebUIMessageAllowedForFrame(WKFrameInfo* frame, const GURL& origin, NSString** prompt, - web::MojoFacade* facade) override; + web::MojoFacade* facade, web::WebState* webState) override; + + template + void RegisterUntrustedInterface(base::RepeatingCallback)> + callback) { + untrusted_bindings_.emplace(std::string(Interface::Name_), base::BindRepeating(&WrapCallback, std::move(callback))); + } private: std::string user_agent_; + std::map> untrusted_bindings_; + + template + static void WrapCallback( + base::RepeatingCallback)> + callback, + mojo::GenericPendingReceiver* receiver) { + if (auto typed_receiver = receiver->As()) + callback.Run(std::move(typed_receiver)); + } }; #endif // BRAVE_IOS_BROWSER_BRAVE_WEB_CLIENT_H_ diff --git a/ios/browser/brave_web_client.mm b/ios/browser/brave_web_client.mm index af578c46e766..641502e2ca47 100644 --- a/ios/browser/brave_web_client.mm +++ b/ios/browser/brave_web_client.mm @@ -14,6 +14,12 @@ #import "ios/web/public/navigation/browser_url_rewriter.h" #include "url/gurl.h" +#include "ios/web/public/thread/web_thread.h" +#include "ios/web/webui/mojo_facade.h" +#include "base/strings/sys_string_conversions.h" +#include "base/json/json_reader.h" +#include "net/base/apple/url_conversions.h" + #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif @@ -84,26 +90,56 @@ bool WillHandleBraveURLRedirect(GURL* url, web::BrowserState* browser_state) { bool BraveWebClient::IsWebUIMessageAllowedForFrame(WKFrameInfo* frame, const GURL& origin, NSString** prompt, - web::MojoFacade* facade) { - /*DCHECK_CURRENTLY_ON(WebThread::UI); + web::MojoFacade* facade, + web::WebState* webState) { + DCHECK_CURRENTLY_ON(web::WebThread::UI); CHECK(prompt && *prompt); - MessageNameAndArguments name_and_args = - GetMessageNameAndArguments(base::SysNSStringToUTF8(*prompt)); + auto GetMessageNameAndArguments = []( + const std::string& mojo_message_as_json) -> std::pair { + auto value_with_error = base::JSONReader::ReadAndReturnValueWithError( + mojo_message_as_json, base::JSON_PARSE_RFC); + CHECK(value_with_error.has_value()); + CHECK(value_with_error->is_dict()); - if (name_and_args.name == "Mojo.bindInterface") { - const base::Value::Dict& args name_and_args.args; + base::Value::Dict& dict = value_with_error->GetDict(); + const std::string* name = dict.FindString("name"); + CHECK(name); - const std::string* interface_name = args.FindString("interfaceName"); - CHECK(interface_name); + base::Value::Dict* args = dict.FindDict("args"); + CHECK(args); - // VALIDATE interface_name + return {*name, std::move(*args)}; + }; - }*/ + auto name_and_args = + GetMessageNameAndArguments(base::SysNSStringToUTF8(*prompt)); - // Must return an invalid message name - // *prompt = @"{\"name\":\"Mojo.invalidInterface\", args:{}}"; + // If the scheme is untrusted + if (name_and_args.first == "Mojo.bindInterface" && + origin.scheme() == "chrome-untrusted") { + const base::Value::Dict& args = name_and_args.second; + + const std::string* interface_name = args.FindString("interfaceName"); + CHECK(interface_name); + + // Get the request and validate that a chrome-untrusted:// can't access chrome:// + GURL request_url = net::GURLWithNSURL(frame.request.URL); + if (request_url.scheme() == "chrome") { + *prompt = @"{\"name\":\"Mojo.invalidRequest\",\"args\":{}}"; + return true; + } + + // Check if the requested interface is registered + if (auto it = untrusted_bindings_.find(*interface_name); it != untrusted_bindings_.end()) { + webState->GetInterfaceBinderForMainFrame()->AddInterface(it->first, it->second); + return true; + } + + NSLog(@"INTERFACE NOT FOUND!\n"); + *prompt = @"{\"name\":\"Mojo.invalidInterface\",\"args\":{}}"; + return true; + } - NSLog(@"PROMPT RECEIVED: %@", *prompt); return true; }