diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/AdoptiumJdkToolchainResolver.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/AdoptiumJdkToolchainResolver.java
index bddf95cae77d4..388254e400229 100644
--- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/AdoptiumJdkToolchainResolver.java
+++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/toolchain/AdoptiumJdkToolchainResolver.java
@@ -10,6 +10,8 @@
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 
 import org.apache.commons.compress.utils.Lists;
 import org.gradle.jvm.toolchain.JavaLanguageVersion;
@@ -58,8 +60,7 @@ private Optional<AdoptiumVersionInfo> resolveAvailableVersion(AdoptiumVersionReq
         ObjectMapper mapper = new ObjectMapper();
         try {
             int languageVersion = requestKey.languageVersion.asInt();
-            URL source = new URL(
-                "https://api.adoptium.net/v3/info/release_versions?architecture="
+            URL source = Urls.create("https://api.adoptium.net/v3/info/release_versions?architecture="
                     + requestKey.arch
                     + "&image_type=jdk&os="
                     + requestKey.platform
@@ -68,8 +69,7 @@ private Optional<AdoptiumVersionInfo> resolveAvailableVersion(AdoptiumVersionReq
                     + languageVersion
                     + ","
                     + (languageVersion + 1)
-                    + ")"
-            );
+                    + ")", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
             JsonNode jsonNode = mapper.readTree(source);
             JsonNode versionsNode = jsonNode.get("versions");
             return Optional.of(
diff --git a/build-tools/src/main/java/org/elasticsearch/gradle/testclusters/WaitForHttpResource.java b/build-tools/src/main/java/org/elasticsearch/gradle/testclusters/WaitForHttpResource.java
index 550dd0fdcf8fb..42763e636ce1b 100644
--- a/build-tools/src/main/java/org/elasticsearch/gradle/testclusters/WaitForHttpResource.java
+++ b/build-tools/src/main/java/org/elasticsearch/gradle/testclusters/WaitForHttpResource.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.gradle.testclusters;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.gradle.api.logging.Logger;
 import org.gradle.api.logging.Logging;
 
@@ -44,7 +46,7 @@ public class WaitForHttpResource {
     private String password;
 
     public WaitForHttpResource(String protocol, String host, int numberOfNodes) throws MalformedURLException {
-        this(new URL(protocol + "://" + host + "/_cluster/health?wait_for_nodes=>=" + numberOfNodes + "&wait_for_status=yellow"));
+        this(Urls.create(protocol + "://" + host + "/_cluster/health?wait_for_nodes=>=" + numberOfNodes + "&wait_for_status=yellow", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS));
     }
 
     public WaitForHttpResource(URL url) {
diff --git a/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/InstallPluginAction.java b/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/InstallPluginAction.java
index c7bee4a6c172d..9522bb075e9ec 100644
--- a/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/InstallPluginAction.java
+++ b/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/InstallPluginAction.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.plugins.cli;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.apache.lucene.search.spell.LevenshteinDistance;
 import org.apache.lucene.util.CollectionUtil;
 import org.apache.lucene.util.Constants;
@@ -434,7 +436,7 @@ private String getMavenUrl(String[] coordinates) throws IOException {
     @SuppressForbidden(reason = "Make HEAD request using URLConnection.connect()")
     boolean urlExists(String urlString) throws IOException {
         terminal.println(VERBOSE, "Checking if url exists: " + urlString);
-        URL url = new URL(urlString);
+        URL url = Urls.create(urlString, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         assert "https".equals(url.getProtocol()) : "Only http urls can be checked";
         HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
         urlConnection.addRequestProperty("User-Agent", "elasticsearch-plugin-installer");
@@ -464,7 +466,7 @@ private static List<String> checkMisspelledPlugin(String pluginId) {
     @SuppressForbidden(reason = "We use getInputStream to download plugins")
     Path downloadZip(String urlString, Path tmpDir) throws IOException {
         terminal.println(VERBOSE, "Retrieving zip from " + urlString);
-        URL url = new URL(urlString);
+        URL url = Urls.create(urlString, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         Path zip = Files.createTempFile(tmpDir, null, ".zip");
         URLConnection urlConnection = this.proxy == null ? url.openConnection() : url.openConnection(this.proxy);
         urlConnection.addRequestProperty("User-Agent", "elasticsearch-plugin-installer");
@@ -760,7 +762,7 @@ InputStream getPublicKey() {
      */
     // pkg private for tests
     URL openUrl(String urlString) throws IOException {
-        URL checksumUrl = new URL(urlString);
+        URL checksumUrl = Urls.create(urlString, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         HttpURLConnection connection = this.proxy == null
             ? (HttpURLConnection) checksumUrl.openConnection()
             : (HttpURLConnection) checksumUrl.openConnection(this.proxy);
diff --git a/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/cli/InstallPluginActionTests.java b/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/cli/InstallPluginActionTests.java
index c088e89338e74..995bcf185c6ca 100644
--- a/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/cli/InstallPluginActionTests.java
+++ b/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/cli/InstallPluginActionTests.java
@@ -11,6 +11,8 @@
 import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
 import com.google.common.jimfs.Configuration;
 import com.google.common.jimfs.Jimfs;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 
 import org.apache.lucene.tests.util.LuceneTestCase;
 import org.bouncycastle.bcpg.ArmoredOutputStream;
@@ -569,7 +571,7 @@ public void testInstallFailsIfPreviouslyRemovedPluginFailed() throws Exception {
     public void testSpaceInUrl() throws Exception {
         InstallablePlugin pluginZip = createPluginZip("fake", pluginDir);
         Path pluginZipWithSpaces = createTempFile("foo bar", ".zip");
-        try (InputStream in = FileSystemUtils.openFileURLStream(new URL(pluginZip.getLocation()))) {
+        try (InputStream in = FileSystemUtils.openFileURLStream(Urls.create(pluginZip.getLocation(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS))) {
             Files.copy(in, pluginZipWithSpaces, StandardCopyOption.REPLACE_EXISTING);
         }
         InstallablePlugin modifiedPlugin = new InstallablePlugin("fake", pluginZipWithSpaces.toUri().toURL().toString());
diff --git a/libs/core/src/main/java/org/elasticsearch/core/internal/provider/EmbeddedImplClassLoader.java b/libs/core/src/main/java/org/elasticsearch/core/internal/provider/EmbeddedImplClassLoader.java
index 049b619fb57ac..2fb90e8ac62c0 100644
--- a/libs/core/src/main/java/org/elasticsearch/core/internal/provider/EmbeddedImplClassLoader.java
+++ b/libs/core/src/main/java/org/elasticsearch/core/internal/provider/EmbeddedImplClassLoader.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.core.internal.provider;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
@@ -466,7 +468,7 @@ private static Map<JarMeta, CodeSource> getProviderPrefixes(ClassLoader parent,
     }
 
     private static CodeSource codeSource(URL baseURL, String jarName) throws MalformedURLException {
-        return new CodeSource(new URL(baseURL, jarName), (CodeSigner[]) null /*signers*/);
+        return new CodeSource(Urls.create(baseURL, jarName, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS), (CodeSigner[]) null /*signers*/);
     }
 
     private static boolean isMultiRelease(ClassLoader parent, String jarPrefix) throws IOException {
diff --git a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/UriPartsProcessor.java b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/UriPartsProcessor.java
index 2a7025a02ac30..953476e38a7f2 100644
--- a/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/UriPartsProcessor.java
+++ b/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/UriPartsProcessor.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.ingest.common;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.core.SuppressForbidden;
 import org.elasticsearch.ingest.AbstractProcessor;
 import org.elasticsearch.ingest.ConfigurationUtils;
@@ -94,7 +96,7 @@ public static Map<String, Object> apply(String urlString) {
             uri = new URI(urlString);
         } catch (URISyntaxException e) {
             try {
-                url = new URL(urlString);
+                url = Urls.create(urlString, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
             } catch (MalformedURLException e2) {
                 throw new IllegalArgumentException("unable to parse URI [" + urlString + "]");
             }
diff --git a/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/HttpClient.java b/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/HttpClient.java
index 188d826b05ff5..2edb82290626d 100644
--- a/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/HttpClient.java
+++ b/modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/HttpClient.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.ingest.geoip;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.ElasticsearchStatusException;
 import org.elasticsearch.ResourceNotFoundException;
 import org.elasticsearch.SpecialPermission;
@@ -53,8 +55,8 @@ InputStream get(String urlToGet) throws IOException {
                             throw new IllegalStateException("too many redirects connection to [" + urlToGet + "]");
                         }
                         String location = conn.getHeaderField("Location");
-                        URL base = new URL(url);
-                        URL next = new URL(base, location);  // Deal with relative URLs
+                        URL base = Urls.create(url, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
+                        URL next = Urls.create(base, location, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);  // Deal with relative URLs
                         url = next.toExternalForm();
                         conn = createConnection(url);
                         break;
@@ -74,7 +76,7 @@ private static InputStream getInputStream(HttpURLConnection conn) throws IOExcep
     }
 
     private static HttpURLConnection createConnection(String url) throws IOException {
-        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
+        HttpURLConnection conn = (HttpURLConnection) Urls.create(url, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS).openConnection();
         conn.setConnectTimeout(10000);
         conn.setReadTimeout(10000);
         conn.setDoOutput(false);
diff --git a/modules/lang-painless/src/doc/java/org/elasticsearch/painless/ContextGeneratorCommon.java b/modules/lang-painless/src/doc/java/org/elasticsearch/painless/ContextGeneratorCommon.java
index c54214e5f854d..87d096f8e9b2c 100644
--- a/modules/lang-painless/src/doc/java/org/elasticsearch/painless/ContextGeneratorCommon.java
+++ b/modules/lang-painless/src/doc/java/org/elasticsearch/painless/ContextGeneratorCommon.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.painless;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.core.SuppressForbidden;
 import org.elasticsearch.painless.action.PainlessContextClassBindingInfo;
 import org.elasticsearch.painless.action.PainlessContextClassInfo;
@@ -35,7 +37,7 @@
 public class ContextGeneratorCommon {
     @SuppressForbidden(reason = "retrieving data from an internal API not exposed as part of the REST client")
     public static List<PainlessContextInfo> getContextInfos() throws IOException {
-        URLConnection getContextNames = new URL("http://" + System.getProperty("cluster.uri") + "/_scripts/painless/_context")
+        URLConnection getContextNames = Urls.create("http://" + System.getProperty("cluster.uri") + "/_scripts/painless/_context", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS)
             .openConnection();
         XContentParser parser = JsonXContent.jsonXContent.createParser(XContentParserConfiguration.EMPTY, getContextNames.getInputStream());
         parser.nextToken();
@@ -48,9 +50,7 @@ public static List<PainlessContextInfo> getContextInfos() throws IOException {
         List<PainlessContextInfo> contextInfos = new ArrayList<>();
 
         for (String contextName : contextNames) {
-            URLConnection getContextInfo = new URL(
-                "http://" + System.getProperty("cluster.uri") + "/_scripts/painless/_context?context=" + contextName
-            ).openConnection();
+            URLConnection getContextInfo = Urls.create("http://" + System.getProperty("cluster.uri") + "/_scripts/painless/_context?context=" + contextName, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS).openConnection();
             parser = JsonXContent.jsonXContent.createParser(XContentParserConfiguration.EMPTY, getContextInfo.getInputStream());
             contextInfos.add(PainlessContextInfo.fromXContent(parser));
             ((HttpURLConnection) getContextInfo).disconnect();
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Compiler.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Compiler.java
index 3c31a962d841b..c9a7a2079cad8 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Compiler.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Compiler.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.painless;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.bootstrap.BootstrapInfo;
 import org.elasticsearch.painless.antlr.Walker;
 import org.elasticsearch.painless.ir.ClassNode;
@@ -60,7 +62,7 @@ final class Compiler {
     static {
         try {
             // Setup the code privileges.
-            CODESOURCE = new CodeSource(new URL("file:" + BootstrapInfo.UNTRUSTED_CODEBASE), (Certificate[]) null);
+            CODESOURCE = new CodeSource(Urls.create("file:" + BootstrapInfo.UNTRUSTED_CODEBASE, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS), (Certificate[]) null);
         } catch (MalformedURLException impossible) {
             throw new RuntimeException(impossible);
         }
diff --git a/modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageService.java b/modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageService.java
index 760c1c57e0496..61b3c06d81822 100644
--- a/modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageService.java
+++ b/modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageService.java
@@ -20,6 +20,8 @@
 import com.google.cloud.storage.Storage;
 import com.google.cloud.storage.StorageOptions;
 import com.google.cloud.storage.StorageRetryStrategy;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -244,7 +246,7 @@ static String getDefaultProjectId(@Nullable Proxy proxy) throws IOException {
         if (metaHost == null) {
             metaHost = "metadata.google.internal";
         }
-        URL url = new URL("http://" + metaHost + "/computeMetadata/v1/project/project-id");
+        URL url = Urls.create("http://" + metaHost + "/computeMetadata/v1/project/project-id", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         HttpURLConnection connection = (HttpURLConnection) (proxy != null ? url.openConnection(proxy) : url.openConnection());
         connection.setConnectTimeout(5000);
         connection.setReadTimeout(5000);
diff --git a/modules/repository-url/src/main/java/org/elasticsearch/common/blobstore/url/URLBlobContainer.java b/modules/repository-url/src/main/java/org/elasticsearch/common/blobstore/url/URLBlobContainer.java
index c33e1519e8a28..a26c5fe0394d8 100644
--- a/modules/repository-url/src/main/java/org/elasticsearch/common/blobstore/url/URLBlobContainer.java
+++ b/modules/repository-url/src/main/java/org/elasticsearch/common/blobstore/url/URLBlobContainer.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.common.blobstore.url;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.common.blobstore.BlobContainer;
 import org.elasticsearch.common.blobstore.BlobPath;
@@ -110,7 +112,7 @@ public DeleteResult delete(OperationPurpose purpose) {
     @Override
     public InputStream readBlob(OperationPurpose purpose, String name) throws IOException {
         try {
-            return new BufferedInputStream(getInputStream(new URL(path, name)), blobStore.bufferSizeInBytes());
+            return new BufferedInputStream(getInputStream(Urls.create(path, name, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS)), blobStore.bufferSizeInBytes());
         } catch (FileNotFoundException fnfe) {
             throw new NoSuchFileException("blob object [" + name + "] not found");
         }
diff --git a/modules/repository-url/src/main/java/org/elasticsearch/common/blobstore/url/URLBlobStore.java b/modules/repository-url/src/main/java/org/elasticsearch/common/blobstore/url/URLBlobStore.java
index 0a6a7c22e79e5..a92e4583e4688 100644
--- a/modules/repository-url/src/main/java/org/elasticsearch/common/blobstore/url/URLBlobStore.java
+++ b/modules/repository-url/src/main/java/org/elasticsearch/common/blobstore/url/URLBlobStore.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.common.blobstore.url;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.common.blobstore.BlobContainer;
 import org.elasticsearch.common.blobstore.BlobPath;
 import org.elasticsearch.common.blobstore.BlobStore;
@@ -129,9 +131,9 @@ private URL buildPath(BlobPath relativePath) throws MalformedURLException {
         if (paths.isEmpty()) {
             return path();
         }
-        URL blobPath = new URL(this.path, paths.get(0) + "/");
+        URL blobPath = Urls.create(this.path, paths.get(0) + "/", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         for (int i = 1; i < paths.size(); i++) {
-            blobPath = new URL(blobPath, paths.get(i) + "/");
+            blobPath = Urls.create(blobPath, paths.get(i) + "/", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         }
         return blobPath;
     }
diff --git a/modules/repository-url/src/main/java/org/elasticsearch/common/blobstore/url/http/HttpURLBlobContainer.java b/modules/repository-url/src/main/java/org/elasticsearch/common/blobstore/url/http/HttpURLBlobContainer.java
index 186c119d78230..ec9284307a08b 100644
--- a/modules/repository-url/src/main/java/org/elasticsearch/common/blobstore/url/http/HttpURLBlobContainer.java
+++ b/modules/repository-url/src/main/java/org/elasticsearch/common/blobstore/url/http/HttpURLBlobContainer.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.common.blobstore.url.http;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.common.blobstore.BlobPath;
 import org.elasticsearch.common.blobstore.OperationPurpose;
 import org.elasticsearch.common.blobstore.url.URLBlobContainer;
@@ -58,7 +60,7 @@ public InputStream readBlob(OperationPurpose purpose, String name) throws IOExce
 
     private URI getURIForBlob(String name) throws IOException {
         try {
-            return new URL(path, name).toURI();
+            return Urls.create(path, name, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS).toURI();
         } catch (Exception e) {
             throw new IOException("Unable to get an URI for blob with name [" + name + "]", e);
         }
diff --git a/modules/repository-url/src/main/java/org/elasticsearch/repositories/url/URLRepository.java b/modules/repository-url/src/main/java/org/elasticsearch/repositories/url/URLRepository.java
index db68ecf93e4b7..799a83eafa51c 100644
--- a/modules/repository-url/src/main/java/org/elasticsearch/repositories/url/URLRepository.java
+++ b/modules/repository-url/src/main/java/org/elasticsearch/repositories/url/URLRepository.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.repositories.url;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.elasticsearch.cluster.metadata.RepositoryMetadata;
@@ -177,7 +179,7 @@ public boolean isReadOnly() {
 
     private static URL parseURL(String s) {
         try {
-            return new URL(s);
+            return Urls.create(s, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         } catch (MalformedURLException e) {
             throw new IllegalArgumentException("Unable to parse URL repository setting", e);
         }
diff --git a/modules/repository-url/src/test/java/org/elasticsearch/common/blobstore/url/HttpURLBlobStoreTests.java b/modules/repository-url/src/test/java/org/elasticsearch/common/blobstore/url/HttpURLBlobStoreTests.java
index b5be5cdbbe3d9..f10bc2d9f27ca 100644
--- a/modules/repository-url/src/test/java/org/elasticsearch/common/blobstore/url/HttpURLBlobStoreTests.java
+++ b/modules/repository-url/src/test/java/org/elasticsearch/common/blobstore/url/HttpURLBlobStoreTests.java
@@ -10,6 +10,8 @@
 
 import com.sun.net.httpserver.Headers;
 import com.sun.net.httpserver.HttpServer;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 
 import org.elasticsearch.common.blobstore.BlobContainer;
 import org.elasticsearch.common.blobstore.BlobPath;
@@ -108,7 +110,7 @@ public static void stopHttp() throws IOException {
     @Before
     public void storeSetup() throws MalformedURLException {
         final URLHttpClientSettings httpClientSettings = URLHttpClientSettings.fromSettings(Settings.EMPTY);
-        urlBlobStore = new URLBlobStore(Settings.EMPTY, new URL(getEndpointForServer()), httpClient, httpClientSettings);
+        urlBlobStore = new URLBlobStore(Settings.EMPTY, Urls.create(getEndpointForServer(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS), httpClient, httpClientSettings);
     }
 
     @Override
diff --git a/modules/repository-url/src/test/java/org/elasticsearch/common/blobstore/url/URLBlobContainerRetriesTests.java b/modules/repository-url/src/test/java/org/elasticsearch/common/blobstore/url/URLBlobContainerRetriesTests.java
index af91d807305fc..1eb317e13bfc7 100644
--- a/modules/repository-url/src/test/java/org/elasticsearch/common/blobstore/url/URLBlobContainerRetriesTests.java
+++ b/modules/repository-url/src/test/java/org/elasticsearch/common/blobstore/url/URLBlobContainerRetriesTests.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.common.blobstore.url;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.apache.http.ConnectionClosedException;
 import org.elasticsearch.common.blobstore.BlobContainer;
 import org.elasticsearch.common.blobstore.BlobPath;
@@ -92,7 +94,7 @@ protected BlobContainer createBlobContainer(
             final URLHttpClientSettings httpClientSettings = URLHttpClientSettings.fromSettings(settings);
             URLBlobStore urlBlobStore = new URLBlobStore(
                 settings,
-                new URL(getEndpointForServer()),
+                Urls.create(getEndpointForServer(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS),
                 factory.create(httpClientSettings),
                 httpClientSettings
             );
diff --git a/modules/repository-url/src/yamlRestTest/java/org/elasticsearch/repositories/url/RepositoryURLClientYamlTestSuiteIT.java b/modules/repository-url/src/yamlRestTest/java/org/elasticsearch/repositories/url/RepositoryURLClientYamlTestSuiteIT.java
index 0958276656a81..df149bb28bf80 100644
--- a/modules/repository-url/src/yamlRestTest/java/org/elasticsearch/repositories/url/RepositoryURLClientYamlTestSuiteIT.java
+++ b/modules/repository-url/src/yamlRestTest/java/org/elasticsearch/repositories/url/RepositoryURLClientYamlTestSuiteIT.java
@@ -10,6 +10,8 @@
 
 import com.carrotsearch.randomizedtesting.annotations.Name;
 import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 
 import org.apache.http.HttpEntity;
 import org.apache.http.entity.ContentType;
@@ -95,7 +97,7 @@ public void registerRepositories() throws IOException {
         List<String> allowedUrls = (List<String>) XContentMapValues.extractValue("defaults.repositories.url.allowed_urls", clusterSettings);
         for (String allowedUrl : allowedUrls) {
             try {
-                InetAddress inetAddress = InetAddress.getByName(new URL(allowedUrl).getHost());
+                InetAddress inetAddress = InetAddress.getByName(Urls.create(allowedUrl, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS).getHost());
                 if (inetAddress.isAnyLocalAddress() || inetAddress.isLoopbackAddress()) {
                     Request createUrlRepositoryRequest = new Request("PUT", "/_snapshot/repository-url");
                     createUrlRepositoryRequest.setEntity(buildRepositorySettings("url", Settings.builder().put("url", allowedUrl).build()));
diff --git a/plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/AwsEc2Utils.java b/plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/AwsEc2Utils.java
index 256a5516a2ef2..7e983ea64ff88 100644
--- a/plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/AwsEc2Utils.java
+++ b/plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/AwsEc2Utils.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.discovery.ec2;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.elasticsearch.common.Strings;
@@ -37,7 +39,7 @@ static Optional<String> getMetadataToken(String metadataTokenUrl) {
         return SocketAccess.doPrivileged(() -> {
             HttpURLConnection urlConnection;
             try {
-                urlConnection = (HttpURLConnection) new URL(metadataTokenUrl).openConnection();
+                urlConnection = (HttpURLConnection) Urls.create(metadataTokenUrl, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS).openConnection();
                 urlConnection.setRequestMethod("PUT");
                 urlConnection.setConnectTimeout(CONNECT_TIMEOUT);
                 urlConnection.setRequestProperty("X-aws-ec2-metadata-token-ttl-seconds", String.valueOf(METADATA_TOKEN_TTL_SECONDS));
diff --git a/plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/Ec2DiscoveryPlugin.java b/plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/Ec2DiscoveryPlugin.java
index 69447e800d4ac..67f94dc622c9e 100644
--- a/plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/Ec2DiscoveryPlugin.java
+++ b/plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/Ec2DiscoveryPlugin.java
@@ -10,6 +10,8 @@
 
 import com.amazonaws.util.EC2MetadataUtils;
 import com.amazonaws.util.json.Jackson;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 
 import org.elasticsearch.SpecialPermission;
 import org.elasticsearch.common.network.NetworkService;
@@ -142,7 +144,7 @@ static Settings getAvailabilityZoneNodeAttributes(Settings settings, String azMe
         final URL url;
         final URLConnection urlConnection;
         try {
-            url = new URL(azMetadataUrl);
+            url = Urls.create(azMetadataUrl, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
             logger.debug("obtaining ec2 [placement/availability-zone] from ec2 meta-data url {}", url);
             urlConnection = SocketAccess.doPrivilegedIOException(url::openConnection);
             urlConnection.setConnectTimeout(2000);
diff --git a/plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/Ec2NameResolver.java b/plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/Ec2NameResolver.java
index 5c8a2a8fb92f9..3ad9a021ce9d8 100644
--- a/plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/Ec2NameResolver.java
+++ b/plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/Ec2NameResolver.java
@@ -9,6 +9,8 @@
 package org.elasticsearch.discovery.ec2;
 
 import com.amazonaws.util.EC2MetadataUtils;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 
 import org.elasticsearch.common.network.NetworkService.CustomNameResolver;
 import org.elasticsearch.core.IOUtils;
@@ -85,7 +87,7 @@ public static InetAddress[] resolve(Ec2HostnameType type) throws IOException {
         String metadataUrl = EC2MetadataUtils.getHostAddressForEC2MetadataService() + "/latest/meta-data/" + type.ec2Name;
         String metadataTokenUrl = EC2MetadataUtils.getHostAddressForEC2MetadataService() + "/latest/api/token";
         try {
-            URL url = new URL(metadataUrl);
+            URL url = Urls.create(metadataUrl, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
             logger.debug("obtaining ec2 hostname from ec2 meta-data url {}", url);
             URLConnection urlConnection = SocketAccess.doPrivilegedIOException(url::openConnection);
             urlConnection.setConnectTimeout(2000);
diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/PolicyUtilTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/PolicyUtilTests.java
index 57c79c7d2e411..b867d44df808c 100644
--- a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/PolicyUtilTests.java
+++ b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/PolicyUtilTests.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.bootstrap;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.core.SuppressForbidden;
 import org.elasticsearch.plugins.PluginDescriptor;
 import org.elasticsearch.test.ESTestCase;
@@ -44,7 +46,7 @@ public void assumeSecurityManagerDisabled() {
 
     URL makeUrl(String s) {
         try {
-            return new URL(s);
+            return Urls.create(s, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         } catch (MalformedURLException e) {
             throw new RuntimeException(e);
         }
diff --git a/server/src/main/java/org/elasticsearch/env/Environment.java b/server/src/main/java/org/elasticsearch/env/Environment.java
index 2f738eb1412a5..af9f985f7bb60 100644
--- a/server/src/main/java/org/elasticsearch/env/Environment.java
+++ b/server/src/main/java/org/elasticsearch/env/Environment.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.env;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.apache.lucene.util.Constants;
 import org.elasticsearch.common.settings.Setting;
 import org.elasticsearch.common.settings.Setting.Property;
@@ -214,7 +216,7 @@ public URL resolveRepoURL(URL url) {
                 }
                 String jarTail = file.substring(pos);
                 String filePath = file.substring(0, pos);
-                URL internalUrl = new URL(filePath);
+                URL internalUrl = Urls.create(filePath, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
                 URL normalizedUrl = resolveRepoURL(internalUrl);
                 if (normalizedUrl == null) {
                     return null;
diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/WaitForHttpResource.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/WaitForHttpResource.java
index 0c839aeddd189..bc18ab41bb6ac 100644
--- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/WaitForHttpResource.java
+++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/WaitForHttpResource.java
@@ -8,6 +8,8 @@
 
 package org.elasticsearch.test.cluster.local;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
@@ -56,7 +58,7 @@ public class WaitForHttpResource {
     private String password;
 
     public WaitForHttpResource(String protocol, String host, int numberOfNodes) throws MalformedURLException {
-        this(new URL(protocol + "://" + host + "/_cluster/health?wait_for_nodes=>=" + numberOfNodes + "&wait_for_status=yellow"));
+        this(Urls.create(protocol + "://" + host + "/_cluster/health?wait_for_nodes=>=" + numberOfNodes + "&wait_for_status=yellow", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS));
     }
 
     public WaitForHttpResource(URL url) {
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/CommandLineHttpClient.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/CommandLineHttpClient.java
index ca30f9f7ac7e8..de40cecdb180d 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/CommandLineHttpClient.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/CommandLineHttpClient.java
@@ -6,6 +6,8 @@
  */
 package org.elasticsearch.xpack.core.security;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.common.CheckedSupplier;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.hash.MessageDigests;
@@ -266,7 +268,7 @@ public static String getErrorCause(HttpResponse httpResponse) {
      * If status is 'Red', we will wait for 'Yellow' for 30s (default timeout)
      */
     public void checkClusterHealthWithRetriesWaitingForCluster(String username, SecureString password, int retries) throws Exception {
-        final URL clusterHealthUrl = createURL(new URL(getDefaultURL()), "_cluster/health", "?wait_for_status=yellow&pretty");
+        final URL clusterHealthUrl = createURL(Urls.create(getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS), "_cluster/health", "?wait_for_status=yellow&pretty");
         HttpResponse response;
         try {
             response = execute("GET", clusterHealthUrl, username, password, () -> null, CommandLineHttpClient::responseBuilder);
@@ -318,7 +320,7 @@ public static HttpResponse.HttpResponseBuilder responseBuilder(InputStream is) t
     }
 
     public static URL createURL(URL url, String path, String query) throws MalformedURLException, URISyntaxException {
-        return new URL(url, (url.toURI().getPath() + path).replaceAll("/+", "/") + query);
+        return Urls.create(url, (url.toURI().getPath() + path).replaceAll("/+", "/") + query, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
     }
 
     public static String apiKeyHeaderValue(SecureString apiKey) {
diff --git a/x-pack/plugin/identity-provider/src/internalClusterTest/java/org/elasticsearch/xpack/idp/action/SamlIdentityProviderTests.java b/x-pack/plugin/identity-provider/src/internalClusterTest/java/org/elasticsearch/xpack/idp/action/SamlIdentityProviderTests.java
index 76bf415fdcce5..4affa77982911 100644
--- a/x-pack/plugin/identity-provider/src/internalClusterTest/java/org/elasticsearch/xpack/idp/action/SamlIdentityProviderTests.java
+++ b/x-pack/plugin/identity-provider/src/internalClusterTest/java/org/elasticsearch/xpack/idp/action/SamlIdentityProviderTests.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.idp.action;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.client.Request;
 import org.elasticsearch.client.RequestOptions;
@@ -171,7 +173,7 @@ public void testSpInitiatedSso() throws Exception {
         final boolean forceAuthn = true;
         final AuthnRequest authnRequest = buildAuthnRequest(
             entityId,
-            new URL(acsUrl),
+            Urls.create(acsUrl, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS),
             new URL("https://idp.org/sso/redirect"),
             nameIdFormat,
             forceAuthn
@@ -240,7 +242,7 @@ public void testSpInitiatedSsoFailsForUserWithNoAccess() throws Exception {
         final boolean forceAuthn = true;
         final AuthnRequest authnRequest = buildAuthnRequest(
             entityId,
-            new URL(acsUrl),
+            Urls.create(acsUrl, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS),
             new URL("https://idp.org/sso/redirect"),
             nameIdFormat,
             forceAuthn
@@ -307,7 +309,7 @@ public void testSpInitiatedSsoFailsForUnknownSp() throws Exception {
         final boolean forceAuthn = randomBoolean();
         final AuthnRequest authnRequest = buildAuthnRequest(
             entityId + randomAlphaOfLength(4),
-            new URL(acsUrl),
+            Urls.create(acsUrl, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS),
             new URL("https://idp.org/sso/redirect"),
             nameIdFormat,
             forceAuthn
@@ -332,7 +334,7 @@ public void testSpInitiatedSsoFailsForMalformedRequest() throws Exception {
         final boolean forceAuthn = randomBoolean();
         final AuthnRequest authnRequest = buildAuthnRequest(
             entityId + randomAlphaOfLength(4),
-            new URL(acsUrl),
+            Urls.create(acsUrl, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS),
             new URL("https://idp.org/sso/redirect"),
             nameIdFormat,
             forceAuthn
diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/action/PutSamlServiceProviderRequest.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/action/PutSamlServiceProviderRequest.java
index 930bfc512e736..d45fe52ab71a5 100644
--- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/action/PutSamlServiceProviderRequest.java
+++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/action/PutSamlServiceProviderRequest.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.idp.action;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.ElasticsearchParseException;
 import org.elasticsearch.action.ActionRequest;
 import org.elasticsearch.action.ActionRequestValidationException;
@@ -100,7 +102,7 @@ public ActionRequestValidationException validate() {
 
         if (Strings.hasText(document.acs)) { // if this is blank the document validation will fail
             try {
-                final URL url = new URL(document.acs);
+                final URL url = Urls.create(document.acs, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
                 if (url.getProtocol().equals("https") == false) {
                     validationException = addValidationError(
                         "[" + SamlServiceProviderDocument.Fields.ACS + "] must use the [https] protocol",
diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/SamlIdentityProviderBuilder.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/SamlIdentityProviderBuilder.java
index 8051b08c78a86..32f538ced2bb8 100644
--- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/SamlIdentityProviderBuilder.java
+++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/idp/SamlIdentityProviderBuilder.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.idp.saml.idp;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.ElasticsearchSecurityException;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.ValidationException;
@@ -293,7 +295,7 @@ public SamlIdentityProviderBuilder organization(SamlIdentityProvider.Organizatio
 
     private static URL parseUrl(String key, String value) {
         try {
-            return new URL(value);
+            return Urls.create(value, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         } catch (MalformedURLException e) {
             throw new IllegalArgumentException("Invalid value [" + value + "] for [" + key + "]. Not a valid URL", e);
         }
diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderFactory.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderFactory.java
index 25a3ae59f17fd..513b2000e2989 100644
--- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderFactory.java
+++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderFactory.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.idp.saml.sp;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.xpack.idp.privileges.ServiceProviderPrivileges;
 import org.opensaml.security.x509.BasicX509Credential;
 import org.opensaml.security.x509.X509Credential;
@@ -92,7 +94,7 @@ private ServiceProviderPrivileges buildPrivileges(SamlServiceProviderDocument.Pr
     private static URL parseUrl(SamlServiceProviderDocument document) {
         final URL acs;
         try {
-            acs = new URL(document.acs);
+            acs = Urls.create(document.acs, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         } catch (MalformedURLException e) {
             final ServiceProviderException exception = new ServiceProviderException(
                 "Service provider [{}] (doc {}) has an invalid ACS [{}]",
diff --git a/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/authn/SuccessfulAuthenticationResponseMessageBuilderTests.java b/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/authn/SuccessfulAuthenticationResponseMessageBuilderTests.java
index bd433e828436b..0883c242a4746 100644
--- a/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/authn/SuccessfulAuthenticationResponseMessageBuilderTests.java
+++ b/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/authn/SuccessfulAuthenticationResponseMessageBuilderTests.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.idp.saml.authn;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.xpack.idp.saml.idp.SamlIdentityProvider;
 import org.elasticsearch.xpack.idp.saml.sp.SamlServiceProvider;
 import org.elasticsearch.xpack.idp.saml.sp.ServiceProviderDefaults;
@@ -59,7 +61,7 @@ private Response buildResponse() throws Exception {
         final String baseServiceUrl = "https://" + randomAlphaOfLength(32) + ".us-east-1.aws.found.io/";
         final String acs = baseServiceUrl + "api/security/saml/callback";
         when(sp.getEntityId()).thenReturn(baseServiceUrl);
-        when(sp.getAssertionConsumerService()).thenReturn(new URL(acs));
+        when(sp.getAssertionConsumerService()).thenReturn(Urls.create(acs, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS));
         when(sp.getAuthnExpiry()).thenReturn(Duration.ofMinutes(10));
         when(sp.getAttributeNames()).thenReturn(new SamlServiceProvider.AttributeNames("principal", null, null, null));
 
diff --git a/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/idp/SamlIdentityProviderBuilderTests.java b/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/idp/SamlIdentityProviderBuilderTests.java
index e5f995204ac0c..6d2397ef4bf47 100644
--- a/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/idp/SamlIdentityProviderBuilderTests.java
+++ b/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/idp/SamlIdentityProviderBuilderTests.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.idp.saml.idp;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.apache.lucene.tests.util.LuceneTestCase;
 import org.elasticsearch.common.ValidationException;
 import org.elasticsearch.common.settings.MockSecureSettings;
@@ -599,13 +601,11 @@ public void testCreateMetadataSigningCredentialFromKeyStoreWithMultipleEntriesBu
 
     public void testCreateViaMethodCalls() throws Exception {
         final String entityId = randomAlphaOfLength(4) + ":" + randomAlphaOfLength(6) + "/" + randomAlphaOfLengthBetween(4, 12);
-        final URL redirectUrl = new URL(
-            randomFrom("http", "https")
+        final URL redirectUrl = Urls.create(randomFrom("http", "https")
                 + "://"
                 + String.join(".", randomArray(2, 5, String[]::new, () -> randomAlphaOfLengthBetween(3, 6)))
                 + "/"
-                + String.join("/", randomArray(1, 3, String[]::new, () -> randomAlphaOfLengthBetween(2, 4)))
-        );
+                + String.join("/", randomArray(1, 3, String[]::new, () -> randomAlphaOfLengthBetween(2, 4))), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
 
         final X509Credential credential = readCredentials("RSA", randomFrom(1024, 2048));
         final String nameIdFormat = randomFrom(NameID.TRANSIENT, PERSISTENT, EMAIL);
diff --git a/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderResolverTests.java b/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderResolverTests.java
index 6b76deb08aad6..7a516066982eb 100644
--- a/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderResolverTests.java
+++ b/x-pack/plugin/identity-provider/src/test/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderResolverTests.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.idp.saml.sp;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.support.PlainActionFuture;
 import org.elasticsearch.common.settings.Settings;
@@ -51,7 +53,7 @@ public void setupMocks() {
     public void testResolveWithoutCache() throws Exception {
 
         final String entityId = "https://" + randomAlphaOfLength(12) + ".elastic-cloud.com/";
-        final URL acs = new URL(entityId + "saml/acs");
+        final URL acs = Urls.create(entityId + "saml/acs", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
 
         final String principalAttribute = randomAlphaOfLengthBetween(6, 36);
         final String rolesAttribute = randomAlphaOfLengthBetween(6, 36);
diff --git a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeIntegTestCase.java b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeIntegTestCase.java
index 209f12c2e90ce..0e0fdb042e9d3 100644
--- a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeIntegTestCase.java
+++ b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeIntegTestCase.java
@@ -6,6 +6,8 @@
  */
 package org.elasticsearch.xpack.ml.integration;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.action.admin.cluster.snapshots.features.ResetFeatureStateAction;
 import org.elasticsearch.action.admin.cluster.snapshots.features.ResetFeatureStateRequest;
 import org.elasticsearch.action.admin.indices.refresh.RefreshAction;
@@ -227,7 +229,7 @@ protected TestCluster buildTestCluster(Scope scope, long seed) throws IOExceptio
         final TransportAddress[] transportAddresses = new TransportAddress[stringAddresses.length];
         int i = 0;
         for (String stringAddress : stringAddresses) {
-            URL url = new URL("http://" + stringAddress);
+            URL url = Urls.create("http://" + stringAddress, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
             InetAddress inetAddress = InetAddress.getByName(url.getHost());
             transportAddresses[i++] = new TransportAddress(new InetSocketAddress(inetAddress, url.getPort()));
         }
diff --git a/x-pack/plugin/ql/test-fixtures/src/main/java/org/elasticsearch/xpack/ql/TestUtils.java b/x-pack/plugin/ql/test-fixtures/src/main/java/org/elasticsearch/xpack/ql/TestUtils.java
index a395ac7766b0a..93ce822889646 100644
--- a/x-pack/plugin/ql/test-fixtures/src/main/java/org/elasticsearch/xpack/ql/TestUtils.java
+++ b/x-pack/plugin/ql/test-fixtures/src/main/java/org/elasticsearch/xpack/ql/TestUtils.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.ql;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.apache.http.HttpHost;
 import org.elasticsearch.TransportVersion;
 import org.elasticsearch.Version;
@@ -244,7 +246,7 @@ public static List<URL> classpathResources(String pattern) throws IOException {
                         String name = entry.getName();
                         Tuple<String, String> entrySplit = pathAndName(name);
                         if (root.equals(entrySplit.v1()) && Regex.simpleMatch(filePattern, entrySplit.v2())) {
-                            matches.add(new URL("jar:" + path.toUri() + "!/" + name));
+                            matches.add(Urls.create("jar:" + path.toUri() + "!/" + name, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS));
                         }
                     }
                 }
diff --git a/x-pack/plugin/security/cli/src/main/java/org/elasticsearch/xpack/security/cli/AutoConfigureNode.java b/x-pack/plugin/security/cli/src/main/java/org/elasticsearch/xpack/security/cli/AutoConfigureNode.java
index 29828fba085d8..4e24ddbb8d9e5 100644
--- a/x-pack/plugin/security/cli/src/main/java/org/elasticsearch/xpack/security/cli/AutoConfigureNode.java
+++ b/x-pack/plugin/security/cli/src/main/java/org/elasticsearch/xpack/security/cli/AutoConfigureNode.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.security.cli;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import joptsimple.OptionSet;
 import joptsimple.OptionSpec;
 
@@ -304,7 +306,7 @@ public void execute(Terminal terminal, OptionSet options, Environment env, Proce
             URL enrollNodeUrl = null;
             for (String address : enrollmentToken.getBoundAddress()) {
                 try {
-                    enrollNodeUrl = createURL(new URL("https://" + address), "/_security/enroll/node", "");
+                    enrollNodeUrl = createURL(Urls.create("https://" + address, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS), "/_security/enroll/node", "");
                     enrollResponse = client.execute(
                         "GET",
                         enrollNodeUrl,
diff --git a/x-pack/plugin/security/qa/saml-rest-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/saml/SamlServiceProviderMetadataIT.java b/x-pack/plugin/security/qa/saml-rest-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/saml/SamlServiceProviderMetadataIT.java
index 383598c804f7a..2772740db132f 100644
--- a/x-pack/plugin/security/qa/saml-rest-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/saml/SamlServiceProviderMetadataIT.java
+++ b/x-pack/plugin/security/qa/saml-rest-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/saml/SamlServiceProviderMetadataIT.java
@@ -9,6 +9,8 @@
 
 import com.sun.net.httpserver.HttpExchange;
 import com.sun.net.httpserver.HttpsServer;
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 
 import org.elasticsearch.client.Request;
 import org.elasticsearch.client.ResponseException;
@@ -217,7 +219,7 @@ private void samlAuthUser(int realmNumber, String username) throws Exception {
         var httpsAddress = httpsServer.getAddress();
         var message = new SamlResponseBuilder().spEntityId("https://sp" + realmNumber + ".example.org/")
             .idpEntityId(getIdpEntityId(realmNumber))
-            .acs(new URL("https://" + httpsAddress.getHostName() + ":" + httpsAddress.getPort() + "/acs/" + realmNumber))
+            .acs(Urls.create("https://" + httpsAddress.getHostName() + ":" + httpsAddress.getPort() + "/acs/" + realmNumber, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS))
             .attribute("urn:oid:2.5.4.3", username)
             .sign(getDataPath("/saml/signing.crt"), getDataPath("/saml/signing.key"), new char[0])
             .asString();
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/tool/ResetPasswordTool.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/tool/ResetPasswordTool.java
index 0718742d362cb..9b177e15457c4 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/tool/ResetPasswordTool.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/tool/ResetPasswordTool.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.security.authc.esnative.tool;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import joptsimple.OptionSet;
 import joptsimple.OptionSpec;
 import joptsimple.OptionSpecBuilder;
@@ -90,7 +92,7 @@ protected void executeCommand(Terminal terminal, OptionSet options, Environment
         }
         try {
             final CommandLineHttpClient client = clientFunction.apply(env);
-            final URL baseUrl = options.has(urlOption) ? new URL(options.valueOf(urlOption)) : new URL(client.getDefaultURL());
+            final URL baseUrl = options.has(urlOption) ? Urls.create(options.valueOf(urlOption), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS) : Urls.create(client.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
             final URL changePasswordUrl = createURL(baseUrl, "_security/user/" + providedUsername + "/_password", "?pretty");
             final HttpResponse httpResponse = client.execute(
                 "POST",
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/tool/SetupPasswordTool.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/tool/SetupPasswordTool.java
index 95f06051abb40..edae085bb8489 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/tool/SetupPasswordTool.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/tool/SetupPasswordTool.java
@@ -6,6 +6,8 @@
  */
 package org.elasticsearch.xpack.security.authc.esnative.tool;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import joptsimple.OptionParser;
 import joptsimple.OptionSet;
 import joptsimple.OptionSpec;
@@ -304,7 +306,7 @@ void setupOptions(Terminal terminal, OptionSet options, Environment env) throws
             client = clientFunction.apply(newEnv);
 
             String providedUrl = urlOption.value(options);
-            url = new URL(providedUrl == null ? client.getDefaultURL() : providedUrl);
+            url = Urls.create(providedUrl == null ? client.getDefaultURL() : providedUrl, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
             setShouldPrompt(options);
         }
 
@@ -634,7 +636,7 @@ private static HttpResponseBuilder responseBuilder(InputStream is, Terminal term
         }
 
         private static URL createURL(URL url, String path, String query) throws MalformedURLException, URISyntaxException {
-            return new URL(url, (url.toURI().getPath() + path).replaceAll("/+", "/") + query);
+            return Urls.create(url, (url.toURI().getPath() + path).replaceAll("/+", "/") + query, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         }
     }
 
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/oidc/OpenIdConnectAuthenticator.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/oidc/OpenIdConnectAuthenticator.java
index e637bda19d886..d13e23e5b15a1 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/oidc/OpenIdConnectAuthenticator.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/oidc/OpenIdConnectAuthenticator.java
@@ -6,6 +6,8 @@
  */
 package org.elasticsearch.xpack.security.authc.oidc;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import net.minidev.json.JSONArray;
 
 import com.nimbusds.jose.JOSEException;
@@ -788,7 +790,7 @@ IDTokenValidator createIdTokenValidator(boolean addFileWatcherIfRequired) {
                 } else if (jwkSetPath.startsWith("https://")) {
                     final JWSVerificationKeySelector<SecurityContext> keySelector = new JWSVerificationKeySelector<>(
                         requestedAlgorithm,
-                        new ReloadableJWKSource<>(new URL(jwkSetPath))
+                        new ReloadableJWKSource<>(Urls.create(jwkSetPath, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS))
                     );
                     idTokenValidator = new IDTokenValidator(opConfig.getIssuer(), rpConfig.getClientId(), keySelector, null);
                 } else {
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/enrollment/ExternalEnrollmentTokenGenerator.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/enrollment/ExternalEnrollmentTokenGenerator.java
index 0a899bd70e619..4f156e37a96a6 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/enrollment/ExternalEnrollmentTokenGenerator.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/enrollment/ExternalEnrollmentTokenGenerator.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.security.enrollment;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.elasticsearch.common.CheckedSupplier;
@@ -88,11 +90,11 @@ private static HttpResponse.HttpResponseBuilder responseBuilder(InputStream is)
     }
 
     protected static URL createAPIKeyUrl(URL baseUrl) throws MalformedURLException, URISyntaxException {
-        return new URL(baseUrl, (baseUrl.toURI().getPath() + "/_security/api_key").replaceAll("/+", "/"));
+        return Urls.create(baseUrl, (baseUrl.toURI().getPath() + "/_security/api_key").replaceAll("/+", "/"), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
     }
 
     protected static URL getHttpInfoUrl(URL baseUrl) throws MalformedURLException, URISyntaxException {
-        return new URL(baseUrl, (baseUrl.toURI().getPath() + "/_nodes/_local/http").replaceAll("/+", "/"));
+        return Urls.create(baseUrl, (baseUrl.toURI().getPath() + "/_nodes/_local/http").replaceAll("/+", "/"), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
     }
 
     @SuppressWarnings("unchecked")
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/enrollment/tool/CreateEnrollmentTokenTool.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/enrollment/tool/CreateEnrollmentTokenTool.java
index 919f4531734fb..36db066cb60fe 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/enrollment/tool/CreateEnrollmentTokenTool.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/enrollment/tool/CreateEnrollmentTokenTool.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.security.enrollment.tool;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import joptsimple.OptionSet;
 import joptsimple.OptionSpec;
 
@@ -74,8 +76,8 @@ protected void executeCommand(Terminal terminal, OptionSet options, Environment
         throws Exception {
         final String tokenScope = scope.value(options);
         final URL baseUrl = options.has(urlOption)
-            ? new URL(options.valueOf(urlOption))
-            : new URL(clientFunction.apply(env).getDefaultURL());
+            ? Urls.create(options.valueOf(urlOption), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS)
+            : Urls.create(clientFunction.apply(env).getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         try {
             ExternalEnrollmentTokenGenerator externalEnrollmentTokenGenerator = createEnrollmentTokenFunction.apply(env);
             if (tokenScope.equals("node")) {
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/tool/BaseRunAsSuperuserCommand.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/tool/BaseRunAsSuperuserCommand.java
index 2f45bafe493bb..c45779e056069 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/tool/BaseRunAsSuperuserCommand.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/tool/BaseRunAsSuperuserCommand.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.security.tool;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import joptsimple.OptionSet;
 import joptsimple.OptionSpec;
 import joptsimple.OptionSpecBuilder;
@@ -207,7 +209,7 @@ private void checkClusterHealthWithRetries(
         boolean force
     ) throws Exception {
         CommandLineHttpClient client = clientFunction.apply(env);
-        final URL baseUrl = options.has(urlOption) ? new URL(options.valueOf(urlOption)) : new URL(client.getDefaultURL());
+        final URL baseUrl = options.has(urlOption) ? Urls.create(options.valueOf(urlOption), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS) : Urls.create(client.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         final URL clusterHealthUrl = CommandLineHttpClient.createURL(baseUrl, "_cluster/health", "?pretty");
         final HttpResponse response;
         try {
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/esnative/tool/CommandLineHttpClientTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/esnative/tool/CommandLineHttpClientTests.java
index f5e773b2e8e21..be96e1b01410a 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/esnative/tool/CommandLineHttpClientTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/esnative/tool/CommandLineHttpClientTests.java
@@ -6,6 +6,8 @@
  */
 package org.elasticsearch.xpack.security.authc.esnative.tool;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.common.settings.MockSecureSettings;
 import org.elasticsearch.common.settings.SecureString;
 import org.elasticsearch.common.settings.Settings;
@@ -68,7 +70,7 @@ public void testCommandLineHttpClientCanExecuteAndReturnCorrectResultUsingSSLSet
         CommandLineHttpClient client = new CommandLineHttpClient(TestEnvironment.newEnvironment(settings));
         HttpResponse httpResponse = client.execute(
             "GET",
-            new URL("https://localhost:" + webServer.getPort() + "/test"),
+            Urls.create("https://localhost:" + webServer.getPort() + "/test", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS),
             "u1",
             new SecureString(new char[] { 'p' }),
             () -> null,
@@ -88,7 +90,7 @@ public void testCommandLineClientCanTrustPinnedCaCertificateFingerprint() throws
         );
         HttpResponse httpResponse = client.execute(
             "GET",
-            new URL("https://localhost:" + webServer.getPort() + "/test"),
+            Urls.create("https://localhost:" + webServer.getPort() + "/test", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS),
             "u1",
             new SecureString(new char[] { 'p' }),
             () -> null,
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/esnative/tool/SetupPasswordToolTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/esnative/tool/SetupPasswordToolTests.java
index 9d8128c9be200..a02f052c427a1 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/esnative/tool/SetupPasswordToolTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/esnative/tool/SetupPasswordToolTests.java
@@ -6,6 +6,8 @@
  */
 package org.elasticsearch.xpack.security.authc.esnative.tool;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.cli.Command;
 import org.elasticsearch.cli.CommandTestCase;
@@ -116,7 +118,7 @@ public void resetSecretsAndKeyStore(String promptResponse) throws Exception {
             )
         ).thenReturn(httpResponse);
 
-        URL url = new URL(httpClient.getDefaultURL());
+        URL url = Urls.create(httpClient.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         httpResponse = new HttpResponse(HttpURLConnection.HTTP_OK, Collections.singletonMap("status", randomFrom("yellow", "green")));
         when(
             httpClient.execute(
@@ -198,7 +200,7 @@ protected Command newCommand() {
     }
 
     public void testAutoSetup() throws Exception {
-        URL url = new URL(httpClient.getDefaultURL());
+        URL url = Urls.create(httpClient.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         if (randomBoolean()) {
             execute("auto", "-b", "true");
         } else {
@@ -248,7 +250,7 @@ public void testAutoSetup() throws Exception {
     }
 
     public void testAuthnFail() throws Exception {
-        URL url = new URL(httpClient.getDefaultURL());
+        URL url = Urls.create(httpClient.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         URL authnURL = authenticateUrl(url);
 
         HttpResponse httpResponse = new HttpResponse(HttpURLConnection.HTTP_UNAUTHORIZED, new HashMap<>());
@@ -273,7 +275,7 @@ public void testAuthnFail() throws Exception {
     }
 
     public void testErrorMessagesWhenXPackIsNotAvailableOnNode() throws Exception {
-        URL url = new URL(httpClient.getDefaultURL());
+        URL url = Urls.create(httpClient.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         URL authnURL = authenticateUrl(url);
 
         HttpResponse httpResponse = new HttpResponse(HttpURLConnection.HTTP_NOT_FOUND, new HashMap<>());
@@ -317,7 +319,7 @@ public void testErrorMessagesWhenXPackIsNotAvailableOnNode() throws Exception {
     }
 
     public void testErrorMessagesWhenXPackIsAvailableWithCorrectLicenseAndIsEnabledButStillFailedForUnknown() throws Exception {
-        URL url = new URL(httpClient.getDefaultURL());
+        URL url = Urls.create(httpClient.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         URL authnURL = authenticateUrl(url);
 
         HttpResponse httpResponse = new HttpResponse(HttpURLConnection.HTTP_NOT_FOUND, new HashMap<>());
@@ -364,7 +366,7 @@ public void testErrorMessagesWhenXPackIsAvailableWithCorrectLicenseAndIsEnabledB
     }
 
     public void testErrorMessagesWhenXPackPluginIsAvailableButNoSecurityLicense() throws Exception {
-        URL url = new URL(httpClient.getDefaultURL());
+        URL url = Urls.create(httpClient.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         URL authnURL = authenticateUrl(url);
         URL xpackSecurityPluginQueryURL = queryXPackSecurityFeatureConfigURL(url);
 
@@ -410,7 +412,7 @@ public void testErrorMessagesWhenXPackPluginIsAvailableButNoSecurityLicense() th
     }
 
     public void testErrorMessagesWhenXPackPluginIsAvailableWithValidLicenseButDisabledSecurity() throws Exception {
-        URL url = new URL(httpClient.getDefaultURL());
+        URL url = Urls.create(httpClient.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         URL authnURL = authenticateUrl(url);
         URL xpackSecurityPluginQueryURL = queryXPackSecurityFeatureConfigURL(url);
 
@@ -455,7 +457,7 @@ public void testErrorMessagesWhenXPackPluginIsAvailableWithValidLicenseButDisabl
     }
 
     public void testWrongServer() throws Exception {
-        URL url = new URL(httpClient.getDefaultURL());
+        URL url = Urls.create(httpClient.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         URL authnURL = authenticateUrl(url);
         doThrow(randomFrom(new IOException(), new SSLException(""))).when(httpClient)
             .execute(eq("GET"), eq(authnURL), eq(ElasticUser.NAME), any(SecureString.class), anyCheckedSupplier(), anyCheckedFunction());
@@ -470,7 +472,7 @@ public void testWrongServer() throws Exception {
 
     public void testRedCluster() throws Exception {
         resetSecretsAndKeyStore("n");
-        URL url = new URL(httpClient.getDefaultURL());
+        URL url = Urls.create(httpClient.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
 
         HttpResponse httpResponse = new HttpResponse(HttpURLConnection.HTTP_OK, new HashMap<>());
         when(
@@ -509,7 +511,7 @@ public void testRedCluster() throws Exception {
     }
 
     public void testUrlOption() throws Exception {
-        URL url = new URL("http://localhost:9202" + randomFrom("", "/", "//", "/smth", "//smth/", "//x//x/"));
+        URL url = Urls.create("http://localhost:9202" + randomFrom("", "/", "//", "/smth", "//smth/", "//x//x/"), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         execute("auto", "-u", url.toString(), "-b");
 
         InOrder inOrder = Mockito.inOrder(httpClient);
@@ -532,7 +534,7 @@ public void testUrlOption() throws Exception {
     }
 
     public void testSetUserPassFail() throws Exception {
-        URL url = new URL(httpClient.getDefaultURL());
+        URL url = Urls.create(httpClient.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         String userToFail = randomFrom(SetupPasswordTool.USERS);
         URL userToFailURL = passwordUrl(url, userToFail);
 
@@ -549,7 +551,7 @@ public void testSetUserPassFail() throws Exception {
     public void testInteractiveSetup() throws Exception {
         resetSecretsAndKeyStore("Y");
 
-        URL url = new URL(httpClient.getDefaultURL());
+        URL url = Urls.create(httpClient.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         execute("interactive");
 
         InOrder inOrder = Mockito.inOrder(httpClient);
@@ -576,7 +578,7 @@ public void testInteractiveSetup() throws Exception {
     }
 
     public void testInteractivePasswordsFatFingers() throws Exception {
-        URL url = new URL(httpClient.getDefaultURL());
+        URL url = Urls.create(httpClient.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
 
         terminal.reset();
         if (usedKeyStore.hasPassword()) {
@@ -644,19 +646,19 @@ public void testWrongKeystorePassword() throws Exception {
     }
 
     private URL authenticateUrl(URL url) throws MalformedURLException, URISyntaxException {
-        return new URL(url, (url.toURI().getPath() + "/_security/_authenticate").replaceAll("/+", "/") + "?pretty");
+        return Urls.create(url, (url.toURI().getPath() + "/_security/_authenticate").replaceAll("/+", "/") + "?pretty", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
     }
 
     private URL passwordUrl(URL url, String user) throws MalformedURLException, URISyntaxException {
-        return new URL(url, (url.toURI().getPath() + "/_security/user/" + user + "/_password").replaceAll("/+", "/") + "?pretty");
+        return Urls.create(url, (url.toURI().getPath() + "/_security/user/" + user + "/_password").replaceAll("/+", "/") + "?pretty", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
     }
 
     private URL clusterHealthUrl(URL url) throws MalformedURLException, URISyntaxException {
-        return new URL(url, (url.toURI().getPath() + "/_cluster/health").replaceAll("/+", "/") + "?pretty");
+        return Urls.create(url, (url.toURI().getPath() + "/_cluster/health").replaceAll("/+", "/") + "?pretty", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
     }
 
     private URL queryXPackSecurityFeatureConfigURL(URL url) throws MalformedURLException, URISyntaxException {
-        return new URL(url, (url.toURI().getPath() + "/_xpack").replaceAll("/+", "/") + "?categories=features&human=false&pretty");
+        return Urls.create(url, (url.toURI().getPath() + "/_xpack").replaceAll("/+", "/") + "?categories=features&human=false&pretty", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
     }
 
     private HttpResponse createHttpResponse(final int httpStatus, final String responseJson) throws IOException {
diff --git a/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/VersionTests.java b/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/VersionTests.java
index 1e33fafbe56fe..c5ba572cfa25b 100644
--- a/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/VersionTests.java
+++ b/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/VersionTests.java
@@ -6,6 +6,8 @@
  */
 package org.elasticsearch.xpack.sql.client;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.xpack.sql.proto.SqlVersion;
 
@@ -73,7 +75,7 @@ public void testVersionFromFileJar() throws IOException {
         byte[] parts = randomVersion();
         Path jarPath = createDriverJar(parts);
 
-        URL fileUrl = new URL(jarPath.toUri().toURL().toString());
+        URL fileUrl = Urls.create(jarPath.toUri().toURL().toString(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         SqlVersion version = ClientVersion.extractVersion(fileUrl);
 
         assertEquals(parts[0], version.major);
@@ -86,7 +88,7 @@ public void testVersionFromJar() throws IOException {
         byte[] parts = randomVersion();
         Path jarPath = createDriverJar(parts);
 
-        URL jarUrl = new URL("jar:" + jarPath.toUri().toURL().toString() + JAR_PATH_SEPARATOR);
+        URL jarUrl = Urls.create("jar:" + jarPath.toUri().toURL().toString() + JAR_PATH_SEPARATOR, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         SqlVersion version = ClientVersion.extractVersion(jarUrl);
 
         assertEquals(parts[0], version.major);
@@ -119,9 +121,7 @@ public void testVersionFromJarInJar() throws IOException {
             }
         }
 
-        URL jarInJar = new URL(
-            "jar:" + jarPath.toUri().toURL().toString() + JAR_PATH_SEPARATOR + innerJarPath.getFileName() + JAR_PATH_SEPARATOR
-        );
+        URL jarInJar = Urls.create("jar:" + jarPath.toUri().toURL().toString() + JAR_PATH_SEPARATOR + innerJarPath.getFileName() + JAR_PATH_SEPARATOR, Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
 
         SqlVersion version = ClientVersion.extractVersion(jarInJar);
         assertEquals(parts[0], version.major);
diff --git a/x-pack/qa/security-tools-tests/src/test/java/org/elasticsearch/xpack/security/authc/esnative/tool/ResetPasswordToolTests.java b/x-pack/qa/security-tools-tests/src/test/java/org/elasticsearch/xpack/security/authc/esnative/tool/ResetPasswordToolTests.java
index c06f4573d57f0..b4d57cd55cc20 100644
--- a/x-pack/qa/security-tools-tests/src/test/java/org/elasticsearch/xpack/security/authc/esnative/tool/ResetPasswordToolTests.java
+++ b/x-pack/qa/security-tools-tests/src/test/java/org/elasticsearch/xpack/security/authc/esnative/tool/ResetPasswordToolTests.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.security.authc.esnative.tool;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import joptsimple.OptionSet;
 
 import com.google.common.jimfs.Configuration;
@@ -100,7 +102,7 @@ public void setup() throws Exception {
         this.client = mock(CommandLineHttpClient.class);
         when(client.getDefaultURL()).thenReturn("https://localhost:9200");
         user = randomFrom("elastic", "kibana_system", "nativeuser1");
-        URL url = new URL(client.getDefaultURL());
+        URL url = Urls.create(client.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         HttpResponse healthResponse = new HttpResponse(HttpURLConnection.HTTP_OK, Map.of("status", randomFrom("yellow", "green")));
         when(
             client.execute(
@@ -216,7 +218,7 @@ public void testFailureInteractiveModeDifferentPassword() throws Exception {
     }
 
     public void testFailureClusterUnhealthy() throws Exception {
-        final URL url = new URL(client.getDefaultURL());
+        final URL url = Urls.create(client.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         HttpResponse healthResponse = new HttpResponse(HttpURLConnection.HTTP_OK, Map.of("status", randomFrom("red")));
         when(
             client.execute(
@@ -239,7 +241,7 @@ public void testFailureClusterUnhealthy() throws Exception {
 
     public void testFailureUnableToChangePassword() throws Exception {
         terminal.addTextInput("y");
-        final URL url = new URL(client.getDefaultURL());
+        final URL url = Urls.create(client.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         HttpResponse changePasswordResponse = new HttpResponse(HttpURLConnection.HTTP_UNAVAILABLE, Map.of());
         when(
             client.execute(
@@ -261,7 +263,7 @@ public void testFailureUnableToChangePassword() throws Exception {
 
     public void testFailureClusterUnhealthyWithForce() throws Exception {
         terminal.addTextInput("y");
-        final URL url = new URL(client.getDefaultURL());
+        final URL url = Urls.create(client.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         HttpResponse healthResponse = new HttpResponse(HttpURLConnection.HTTP_OK, Map.of("status", randomFrom("red")));
         when(
             client.execute(
@@ -304,10 +306,10 @@ public void testInvalidInvocation() throws Exception {
     }
 
     private URL changePasswordUrl(URL url, String user) throws MalformedURLException, URISyntaxException {
-        return new URL(url, (url.toURI().getPath() + "/_security/user/" + user + "/_password").replaceAll("/+", "/") + "?pretty");
+        return Urls.create(url, (url.toURI().getPath() + "/_security/user/" + user + "/_password").replaceAll("/+", "/") + "?pretty", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
     }
 
     private URL clusterHealthUrl(URL url) throws MalformedURLException, URISyntaxException {
-        return new URL(url, (url.toURI().getPath() + "/_cluster/health").replaceAll("/+", "/") + "?pretty");
+        return Urls.create(url, (url.toURI().getPath() + "/_cluster/health").replaceAll("/+", "/") + "?pretty", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
     }
 }
diff --git a/x-pack/qa/security-tools-tests/src/test/java/org/elasticsearch/xpack/security/enrollment/tool/CreateEnrollmentTokenToolTests.java b/x-pack/qa/security-tools-tests/src/test/java/org/elasticsearch/xpack/security/enrollment/tool/CreateEnrollmentTokenToolTests.java
index 2becdd4b3c444..05be8633289ee 100644
--- a/x-pack/qa/security-tools-tests/src/test/java/org/elasticsearch/xpack/security/enrollment/tool/CreateEnrollmentTokenToolTests.java
+++ b/x-pack/qa/security-tools-tests/src/test/java/org/elasticsearch/xpack/security/enrollment/tool/CreateEnrollmentTokenToolTests.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.security.enrollment.tool;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import joptsimple.OptionSet;
 
 import com.google.common.jimfs.Configuration;
@@ -111,7 +113,7 @@ public void setup() throws Exception {
         this.client = mock(CommandLineHttpClient.class);
         when(client.getDefaultURL()).thenReturn("https://localhost:9200");
 
-        URL url = new URL(client.getDefaultURL());
+        URL url = Urls.create(client.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         HttpResponse healthResponse = new HttpResponse(HttpURLConnection.HTTP_OK, Map.of("status", randomFrom("yellow", "green")));
         when(
             client.execute(
@@ -206,7 +208,7 @@ public void testUserCanPassUrl() throws Exception {
 
     public void testUnhealthyCluster() throws Exception {
         String scope = randomBoolean() ? "node" : "kibana";
-        URL url = new URL(client.getDefaultURL());
+        URL url = Urls.create(client.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         HttpResponse healthResponse = new HttpResponse(HttpURLConnection.HTTP_OK, Map.of("status", randomFrom("red")));
         when(
             client.execute(
@@ -257,6 +259,6 @@ public void testUnableToCreateToken() throws Exception {
     }
 
     private URL clusterHealthUrl(URL url) throws MalformedURLException, URISyntaxException {
-        return new URL(url, (url.toURI().getPath() + "/_cluster/health").replaceAll("/+", "/") + "?pretty");
+        return Urls.create(url, (url.toURI().getPath() + "/_cluster/health").replaceAll("/+", "/") + "?pretty", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
     }
 }
diff --git a/x-pack/qa/security-tools-tests/src/test/java/org/elasticsearch/xpack/security/tool/BaseRunAsSuperuserCommandTests.java b/x-pack/qa/security-tools-tests/src/test/java/org/elasticsearch/xpack/security/tool/BaseRunAsSuperuserCommandTests.java
index 33fadccda079a..3cd70c5e546c4 100644
--- a/x-pack/qa/security-tools-tests/src/test/java/org/elasticsearch/xpack/security/tool/BaseRunAsSuperuserCommandTests.java
+++ b/x-pack/qa/security-tools-tests/src/test/java/org/elasticsearch/xpack/security/tool/BaseRunAsSuperuserCommandTests.java
@@ -7,6 +7,8 @@
 
 package org.elasticsearch.xpack.security.tool;
 
+import io.github.pixee.security.HostValidator;
+import io.github.pixee.security.Urls;
 import joptsimple.OptionSet;
 
 import com.google.common.jimfs.Configuration;
@@ -110,7 +112,7 @@ public void setup() throws Exception {
         this.client = mock(CommandLineHttpClient.class);
         when(client.getDefaultURL()).thenReturn("https://localhost:9200");
 
-        URL url = new URL(client.getDefaultURL());
+        URL url = Urls.create(client.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         HttpResponse healthResponse = new HttpResponse(HttpURLConnection.HTTP_OK, Map.of("status", randomFrom("yellow", "green")));
         when(
             client.execute(
@@ -169,7 +171,7 @@ public void testUsersRolesFileIsMissing() throws Exception {
     }
 
     public void testUnhealthyCluster() throws Exception {
-        URL url = new URL(client.getDefaultURL());
+        URL url = Urls.create(client.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         HttpResponse healthResponse = new HttpResponse(HttpURLConnection.HTTP_OK, Map.of("status", randomFrom("red")));
         when(
             client.execute(
@@ -199,7 +201,7 @@ public void testUnhealthyCluster() throws Exception {
     }
 
     public void testUnhealthyClusterWithForce() throws Exception {
-        URL url = new URL(client.getDefaultURL());
+        URL url = Urls.create(client.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         HttpResponse healthResponse = new HttpResponse(HttpURLConnection.HTTP_OK, Map.of("status", randomFrom("red")));
         when(
             client.execute(
@@ -219,7 +221,7 @@ public void testUnhealthyClusterWithForce() throws Exception {
     }
 
     public void testWillRetryOnUnauthorized() throws Exception {
-        URL url = new URL(client.getDefaultURL());
+        URL url = Urls.create(client.getDefaultURL(), Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
         HttpResponse unauthorizedResponse = new HttpResponse(HttpURLConnection.HTTP_UNAUTHORIZED, Map.of());
         when(
             client.execute(
@@ -282,7 +284,7 @@ private void assertNoUsersRoles() throws Exception {
     }
 
     private URL clusterHealthUrl(URL url) throws MalformedURLException, URISyntaxException {
-        return new URL(url, (url.toURI().getPath() + "/_cluster/health").replaceAll("/+", "/") + "?pretty");
+        return Urls.create(url, (url.toURI().getPath() + "/_cluster/health").replaceAll("/+", "/") + "?pretty", Urls.HTTP_PROTOCOLS, HostValidator.DENY_COMMON_INFRASTRUCTURE_TARGETS);
     }
 
     /**