diff --git a/components/abstractions/src/main/java/com/microsoft/kiota/authentication/AllowedHostsValidator.java b/components/abstractions/src/main/java/com/microsoft/kiota/authentication/AllowedHostsValidator.java index 5da5529d..cc858788 100644 --- a/components/abstractions/src/main/java/com/microsoft/kiota/authentication/AllowedHostsValidator.java +++ b/components/abstractions/src/main/java/com/microsoft/kiota/authentication/AllowedHostsValidator.java @@ -6,6 +6,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.Locale; +import java.util.Objects; import java.util.Set; /** Maintains a list of valid hosts and allows authentication providers to check whether a host is valid before authenticating a request */ @@ -58,15 +59,28 @@ public void setAllowedHosts(@Nonnull final Set allowedHosts) { * @return true if the host is allowed, false otherwise. */ public boolean isUrlHostValid(@Nonnull final URI uri) { + Objects.requireNonNull(uri, "parameter uri cannot be null"); + final String scheme = uri.getScheme(); + if (scheme == null || scheme.trim().isEmpty()) { + return false; + } + final String userInfo = uri.getUserInfo(); + if (userInfo != null && !userInfo.isEmpty()) { + return false; + } + final String host = uri.getHost(); + if (host == null || host.trim().isEmpty()) { + return false; + } if (validHosts.isEmpty()) { return true; } - final String host = uri.getHost().trim().toLowerCase(Locale.ROOT); - if (validHosts.contains(host)) { + final String normalizedHost = host.trim().toLowerCase(Locale.ROOT); + if (validHosts.contains(normalizedHost)) { return true; } for (final String validHost : validHosts) { - if (validHost.startsWith(".") && host.endsWith(validHost)) { + if (validHost.startsWith(".") && normalizedHost.endsWith(validHost)) { return true; } } diff --git a/components/abstractions/src/test/java/com/microsoft/kiota/authentication/AllowedHostValidatorTest.java b/components/abstractions/src/test/java/com/microsoft/kiota/authentication/AllowedHostValidatorTest.java index 6f1a54b0..3fd66094 100644 --- a/components/abstractions/src/test/java/com/microsoft/kiota/authentication/AllowedHostValidatorTest.java +++ b/components/abstractions/src/test/java/com/microsoft/kiota/authentication/AllowedHostValidatorTest.java @@ -12,6 +12,9 @@ import java.util.Collections; class AllowedHostValidatorTest { + private static T nullValue() { + return java.util.Collections.emptyMap().get("missing"); + } @Test void throwsExceptionForHttpOrHttpsHosts() { @@ -93,4 +96,33 @@ void allowsSuffixBasedHostsAfterUpdate() throws URISyntaxException { validator.isUrlHostValid( new URI("https://abc.123.graphql.fabric.microsoft.com/path"))); } + + @Test + void throwsNullPointerExceptionForNullUri() { + final AllowedHostsValidator validator = new AllowedHostsValidator("example.com"); + assertThrows(NullPointerException.class, () -> validator.isUrlHostValid(nullValue())); + } + + @Test + void returnsFalseForUriWithoutSchemeOrHost() throws URISyntaxException { + final AllowedHostsValidator validator = new AllowedHostsValidator("example.com"); + assertFalse(validator.isUrlHostValid(new URI("mailto:test@example.com"))); + assertFalse(validator.isUrlHostValid(new URI("/path/only"))); + } + + @Test + void returnsFalseForUriWithUserInfo() throws URISyntaxException { + final AllowedHostsValidator validator = new AllowedHostsValidator("example.com"); + assertFalse(validator.isUrlHostValid(new URI("https://user:password@example.com/path"))); + assertFalse(validator.isUrlHostValid(new URI("https://user@example.com/path"))); + } + + @Test + void validatesUriEvenWhenAllowedHostsEmpty() throws URISyntaxException { + final AllowedHostsValidator validator = new AllowedHostsValidator(); + assertThrows(NullPointerException.class, () -> validator.isUrlHostValid(nullValue())); + assertFalse(validator.isUrlHostValid(new URI("mailto:test@example.com"))); + assertFalse(validator.isUrlHostValid(new URI("https://user:pass@example.com/path"))); + assertTrue(validator.isUrlHostValid(new URI("https://anything.com/path"))); + } }