From 1fd4cb87b202ddacbc45c2a14284acfafc552101 Mon Sep 17 00:00:00 2001 From: Eva H <63033505+hoyyeva@users.noreply.github.com> Date: Mon, 17 Nov 2025 20:10:45 -0500 Subject: [PATCH] app/cmd: restrict ollama:// URL scheme to supported paths (#13120) --- app/cmd/app/app.go | 29 +++++++++++------------------ app/cmd/app/app_windows.go | 4 ++-- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/app/cmd/app/app.go b/app/cmd/app/app.go index 1a4cd568..ef282fd0 100644 --- a/app/cmd/app/app.go +++ b/app/cmd/app/app.go @@ -434,37 +434,30 @@ func openInBrowser(url string) { } } -// parseURLScheme parses an ollama:// URL and returns whether it's a connect URL and the UI path -func parseURLScheme(urlSchemeRequest string) (isConnect bool, uiPath string, err error) { +// parseURLScheme parses an ollama:// URL and validates it +// Supports: ollama:// (open app) and ollama://connect (OAuth) +func parseURLScheme(urlSchemeRequest string) (isConnect bool, err error) { parsedURL, err := url.Parse(urlSchemeRequest) if err != nil { - return false, "", err + return false, fmt.Errorf("invalid URL: %w", err) } // Check if this is a connect URL if parsedURL.Host == "connect" || strings.TrimPrefix(parsedURL.Path, "/") == "connect" { - return true, "", nil + return true, nil } - // Extract the UI path - path := "/" - if parsedURL.Path != "" && parsedURL.Path != "/" { - // For URLs like ollama:///settings, use the path directly - path = parsedURL.Path - } else if parsedURL.Host != "" { - // For URLs like ollama://settings (without triple slash), - // the "settings" part is parsed as the host, not the path. - // We need to convert it to a path by prepending "/" - // This also handles ollama://settings/ where Windows adds a trailing slash - path = "/" + parsedURL.Host + // Allow bare ollama:// or ollama:/// to open the app + if (parsedURL.Host == "" && parsedURL.Path == "") || parsedURL.Path == "/" { + return false, nil } - return false, path, nil + return false, fmt.Errorf("unsupported ollama:// URL path: %s", urlSchemeRequest) } // handleURLSchemeInCurrentInstance processes URL scheme requests in the current instance func handleURLSchemeInCurrentInstance(urlSchemeRequest string) { - isConnect, uiPath, err := parseURLScheme(urlSchemeRequest) + isConnect, err := parseURLScheme(urlSchemeRequest) if err != nil { slog.Error("failed to parse URL scheme request", "url", urlSchemeRequest, "error", err) return @@ -473,6 +466,6 @@ func handleURLSchemeInCurrentInstance(urlSchemeRequest string) { if isConnect { handleConnectURLScheme() } else { - sendUIRequestMessage(uiPath) + sendUIRequestMessage("/") } } diff --git a/app/cmd/app/app_windows.go b/app/cmd/app/app_windows.go index 51cf1f92..8a487640 100644 --- a/app/cmd/app/app_windows.go +++ b/app/cmd/app/app_windows.go @@ -138,7 +138,7 @@ func (app *appCallbacks) HandleURLScheme(urlScheme string) { // handleURLSchemeRequest processes URL scheme requests from other instances func handleURLSchemeRequest(urlScheme string) { - isConnect, uiPath, err := parseURLScheme(urlScheme) + isConnect, err := parseURLScheme(urlScheme) if err != nil { slog.Error("failed to parse URL scheme request", "url", urlScheme, "error", err) return @@ -147,7 +147,7 @@ func handleURLSchemeRequest(urlScheme string) { if isConnect { handleConnectURLScheme() } else { - sendUIRequestMessage(uiPath) + sendUIRequestMessage("/") } }