diff --git a/src/main/java/net/snowflake/client/core/SessionUtilExternalBrowser.java b/src/main/java/net/snowflake/client/core/SessionUtilExternalBrowser.java index 46a27b8aa..b18d1ebcb 100644 --- a/src/main/java/net/snowflake/client/core/SessionUtilExternalBrowser.java +++ b/src/main/java/net/snowflake/client/core/SessionUtilExternalBrowser.java @@ -57,6 +57,10 @@ public HttpPost build(URI uri) { public void openBrowser(String ssoUrl) throws SFException { try { // start web browser + if (!URLUtil.isValidURL(ssoUrl)) { + throw new SFException( + ErrorCode.INVALID_CONNECTION_URL, "Invalid SSOUrl found - " + ssoUrl); + } if (java.awt.Desktop.isDesktopSupported()) { URI uri = new URI(ssoUrl); java.awt.Desktop.getDesktop().browse(uri); diff --git a/src/main/java/net/snowflake/client/core/URLUtil.java b/src/main/java/net/snowflake/client/core/URLUtil.java new file mode 100644 index 000000000..cd4129e4c --- /dev/null +++ b/src/main/java/net/snowflake/client/core/URLUtil.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved. + */ +package net.snowflake.client.core; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; +import javax.annotation.Nullable; +import net.snowflake.client.log.SFLogger; +import net.snowflake.client.log.SFLoggerFactory; + +public class URLUtil { + + static final SFLogger logger = SFLoggerFactory.getLogger(URLUtil.class); + static final String validURLPattern = + "^http(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z@:])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\&\\(\\)\\/\\\\\\+&%\\$#_=@]*)?$"; + static final Pattern pattern = Pattern.compile(validURLPattern); + + public static boolean isValidURL(String url) { + try { + Matcher matcher = pattern.matcher(url); + return matcher.find(); + } catch (PatternSyntaxException pex) { + logger.debug("The URL REGEX is invalid. Falling back to basic sanity test"); + try { + new URL(url).toURI(); + return true; + } catch (MalformedURLException mex) { + logger.debug("The URL " + url + ", is invalid"); + return false; + } catch (URISyntaxException uex) { + logger.debug("The URL " + url + ", is invalid"); + return false; + } + } + } + + @Nullable + public static String urlEncode(String target) throws UnsupportedEncodingException { + String encodedTarget; + try { + encodedTarget = URLEncoder.encode(target, StandardCharsets.UTF_8.toString()); + } catch (UnsupportedEncodingException uex) { + logger.debug("The string to be encoded- " + target + ", is invalid"); + return null; + } + return encodedTarget; + } +} diff --git a/src/test/java/net/snowflake/client/core/URLUtilTest.java b/src/test/java/net/snowflake/client/core/URLUtilTest.java new file mode 100644 index 000000000..f2ef78691 --- /dev/null +++ b/src/test/java/net/snowflake/client/core/URLUtilTest.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved. + */ +package net.snowflake.client.core; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class URLUtilTest { + + @Test + public void testValidURL() throws Exception { + assertTrue(URLUtil.isValidURL("https://ssoTestURL.okta.com")); + assertTrue(URLUtil.isValidURL("https://ssoTestURL.okta.com:8080")); + assertTrue(URLUtil.isValidURL("https://ssoTestURL.okta.com/testpathvalue")); + } + + @Test + public void testInvalidURL() throws Exception { + assertFalse(URLUtil.isValidURL("-a Calculator")); + assertFalse(URLUtil.isValidURL("This is random text")); + assertFalse(URLUtil.isValidURL("file://TestForFile")); + } + + @Test + public void testEncodeURL() throws Exception { + assertEquals(URLUtil.urlEncode("Hello @World"), "Hello+%40World"); + assertEquals(URLUtil.urlEncode("Test//String"), "Test%2F%2FString"); + } +}