Procházet zdrojové kódy

[8.x][Entitlements] Add URLConnection instrumentation (#123965)

* [Entitlements] Add URLConnection instrumentation (#123503)

* [Entitlements] Add URLConnection instrumentation for ftp, http and https protocols (#123802)
Lorenzo Dematté před 7 měsíci
rodič
revize
7e464133e3

+ 201 - 1
libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java

@@ -314,9 +314,209 @@ public interface EntitlementChecker {
 
     void check$java_net_Socket$connect(Class<?> callerClass, Socket that, SocketAddress endpoint, int backlog);
 
-    // Network miscellanea
+    // URLConnection (java.net + sun.net.www)
+
+    void check$java_net_URL$openConnection(Class<?> callerClass, java.net.URL that);
+
     void check$java_net_URL$openConnection(Class<?> callerClass, java.net.URL that, Proxy proxy);
 
+    void check$java_net_URL$openStream(Class<?> callerClass, java.net.URL that);
+
+    void check$java_net_URL$getContent(Class<?> callerClass, java.net.URL that);
+
+    void check$java_net_URL$getContent(Class<?> callerClass, java.net.URL that, Class<?>[] classes);
+
+    void check$java_net_URLConnection$getContentLength(Class<?> callerClass, java.net.URLConnection that);
+
+    void check$java_net_URLConnection$getContentLengthLong(Class<?> callerClass, java.net.URLConnection that);
+
+    void check$java_net_URLConnection$getContentType(Class<?> callerClass, java.net.URLConnection that);
+
+    void check$java_net_URLConnection$getContentEncoding(Class<?> callerClass, java.net.URLConnection that);
+
+    void check$java_net_URLConnection$getExpiration(Class<?> callerClass, java.net.URLConnection that);
+
+    void check$java_net_URLConnection$getDate(Class<?> callerClass, java.net.URLConnection that);
+
+    void check$java_net_URLConnection$getLastModified(Class<?> callerClass, java.net.URLConnection that);
+
+    void check$java_net_URLConnection$getHeaderFieldInt(Class<?> callerClass, java.net.URLConnection that, String name, int defaultValue);
+
+    void check$java_net_URLConnection$getHeaderFieldLong(Class<?> callerClass, java.net.URLConnection that, String name, long defaultValue);
+
+    void check$java_net_URLConnection$getHeaderFieldDate(Class<?> callerClass, java.net.URLConnection that, String name, long defaultValue);
+
+    void check$java_net_URLConnection$getContent(Class<?> callerClass, java.net.URLConnection that);
+
+    void check$java_net_URLConnection$getContent(Class<?> callerClass, java.net.URLConnection that, Class<?>[] classes);
+
+    void check$java_net_HttpURLConnection$getResponseCode(Class<?> callerClass, java.net.HttpURLConnection that);
+
+    void check$java_net_HttpURLConnection$getResponseMessage(Class<?> callerClass, java.net.HttpURLConnection that);
+
+    void check$java_net_HttpURLConnection$getHeaderFieldDate(
+        Class<?> callerClass,
+        java.net.HttpURLConnection that,
+        String name,
+        long defaultValue
+    );
+
+    // Using java.net.URLConnection for "that" as sun.net.www.* is not exported
+    void check$sun_net_www_URLConnection$getHeaderField(Class<?> callerClass, java.net.URLConnection that, String name);
+
+    void check$sun_net_www_URLConnection$getHeaderFields(Class<?> callerClass, java.net.URLConnection that);
+
+    void check$sun_net_www_URLConnection$getHeaderFieldKey(Class<?> callerClass, java.net.URLConnection that, int n);
+
+    void check$sun_net_www_URLConnection$getHeaderField(Class<?> callerClass, java.net.URLConnection that, int n);
+
+    void check$sun_net_www_URLConnection$getContentType(Class<?> callerClass, java.net.URLConnection that);
+
+    void check$sun_net_www_URLConnection$getContentLength(Class<?> callerClass, java.net.URLConnection that);
+
+    void check$sun_net_www_protocol_ftp_FtpURLConnection$connect(Class<?> callerClass, java.net.URLConnection that);
+
+    void check$sun_net_www_protocol_ftp_FtpURLConnection$getInputStream(Class<?> callerClass, java.net.URLConnection that);
+
+    void check$sun_net_www_protocol_ftp_FtpURLConnection$getOutputStream(Class<?> callerClass, java.net.URLConnection that);
+
+    void check$sun_net_www_protocol_http_HttpURLConnection$$openConnectionCheckRedirects(Class<?> callerClass, java.net.URLConnection c);
+
+    void check$sun_net_www_protocol_http_HttpURLConnection$connect(Class<?> callerClass, java.net.HttpURLConnection that);
+
+    void check$sun_net_www_protocol_http_HttpURLConnection$getOutputStream(Class<?> callerClass, java.net.HttpURLConnection that);
+
+    void check$sun_net_www_protocol_http_HttpURLConnection$getInputStream(Class<?> callerClass, java.net.HttpURLConnection that);
+
+    void check$sun_net_www_protocol_http_HttpURLConnection$getErrorStream(Class<?> callerClass, java.net.HttpURLConnection that);
+
+    void check$sun_net_www_protocol_http_HttpURLConnection$getHeaderField(
+        Class<?> callerClass,
+        java.net.HttpURLConnection that,
+        String name
+    );
+
+    void check$sun_net_www_protocol_http_HttpURLConnection$getHeaderFields(Class<?> callerClass, java.net.HttpURLConnection that);
+
+    void check$sun_net_www_protocol_http_HttpURLConnection$getHeaderField(Class<?> callerClass, java.net.HttpURLConnection that, int n);
+
+    void check$sun_net_www_protocol_http_HttpURLConnection$getHeaderFieldKey(Class<?> callerClass, java.net.HttpURLConnection that, int n);
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$connect(Class<?> callerClass, javax.net.ssl.HttpsURLConnection that);
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getOutputStream(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getInputStream(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getErrorStream(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getHeaderField(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that,
+        String name
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getHeaderFields(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getHeaderField(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that,
+        int n
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getHeaderFieldKey(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that,
+        int n
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getResponseCode(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getResponseMessage(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getContentLength(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getContentLengthLong(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getContentType(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getContentEncoding(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getExpiration(Class<?> callerClass, javax.net.ssl.HttpsURLConnection that);
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getDate(Class<?> callerClass, javax.net.ssl.HttpsURLConnection that);
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getLastModified(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getHeaderFieldInt(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that,
+        String name,
+        int defaultValue
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getHeaderFieldLong(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that,
+        String name,
+        long defaultValue
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getHeaderFieldDate(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that,
+        String name,
+        long defaultValue
+    );
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getContent(Class<?> callerClass, javax.net.ssl.HttpsURLConnection that);
+
+    void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getContent(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that,
+        Class<?>[] classes
+    );
+
+    void check$sun_net_www_protocol_https_AbstractDelegateHttpsURLConnection$connect(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    );
+
+    // Network miscellanea
+
     // HttpClient#send and sendAsync are abstract, so we instrument their internal implementations
     void check$jdk_internal_net_http_HttpClientImpl$send(
         Class<?> callerClass,

+ 14 - 0
libs/entitlement/qa/entitled-plugin/src/main/java/org/elasticsearch/entitlement/qa/entitled/EntitledActions.java

@@ -12,6 +12,8 @@ package org.elasticsearch.entitlement.qa.entitled;
 import org.elasticsearch.core.SuppressForbidden;
 
 import java.io.IOException;
+import java.net.URI;
+import java.net.URLConnection;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -57,4 +59,16 @@ public final class EntitledActions {
     public static Path createTempSymbolicLink() throws IOException {
         return Files.createSymbolicLink(readDir().resolve("entitlements-link-" + random.nextLong()), readWriteDir());
     }
+
+    public static URLConnection createHttpURLConnection() throws IOException {
+        return URI.create("http://127.0.0.1:12345/").toURL().openConnection();
+    }
+
+    public static URLConnection createHttpsURLConnection() throws IOException {
+        return URI.create("https://127.0.0.1:12345/").toURL().openConnection();
+    }
+
+    public static URLConnection createFtpURLConnection() throws IOException {
+        return URI.create("ftp://127.0.0.1:12345/").toURL().openConnection();
+    }
 }

+ 0 - 8
libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/NetworkAccessCheckActions.java

@@ -18,8 +18,6 @@ import java.net.Proxy;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.SocketException;
-import java.net.URI;
-import java.net.URISyntaxException;
 import java.nio.ByteBuffer;
 import java.nio.channels.AsynchronousServerSocketChannel;
 import java.nio.channels.AsynchronousSocketChannel;
@@ -75,12 +73,6 @@ class NetworkAccessCheckActions {
         }
     }
 
-    static void urlOpenConnectionWithProxy() throws URISyntaxException, IOException {
-        var url = new URI("http://localhost").toURL();
-        var urlConnection = url.openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(0)));
-        assert urlConnection != null;
-    }
-
     static void createLDAPCertStore() {
         try {
             // We pass down null params to provoke a InvalidAlgorithmParameterException

+ 1 - 1
libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/RestEntitlementsCheckAction.java

@@ -143,7 +143,6 @@ public class RestEntitlementsCheckAction extends BaseRestHandler {
             entry("server_socket_bind", forPlugins(NetworkAccessCheckActions::serverSocketBind)),
             entry("server_socket_accept", forPlugins(NetworkAccessCheckActions::serverSocketAccept)),
 
-            entry("url_open_connection_proxy", forPlugins(NetworkAccessCheckActions::urlOpenConnectionWithProxy)),
             entry("http_client_send", forPlugins(VersionSpecificNetworkChecks::httpClientSend)),
             entry("http_client_send_async", forPlugins(VersionSpecificNetworkChecks::httpClientSendAsync)),
             entry("create_ldap_cert_store", forPlugins(NetworkAccessCheckActions::createLDAPCertStore)),
@@ -195,6 +194,7 @@ public class RestEntitlementsCheckAction extends BaseRestHandler {
         getTestEntries(PathActions.class),
         getTestEntries(SpiActions.class),
         getTestEntries(SystemActions.class),
+        getTestEntries(URLConnectionNetworkActions.class),
         getTestEntries(VersionSpecificManageThreadsActions.class),
         getTestEntries(VersionSpecificNioFileSystemActions.class)
     )

+ 432 - 0
libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/URLConnectionNetworkActions.java

@@ -0,0 +1,432 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the "Elastic License
+ * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+package org.elasticsearch.entitlement.qa.test;
+
+import org.elasticsearch.core.CheckedConsumer;
+import org.elasticsearch.core.SuppressForbidden;
+import org.elasticsearch.entitlement.qa.entitled.EntitledActions;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.ConnectException;
+import java.net.HttpURLConnection;
+import java.net.InetSocketAddress;
+import java.net.MalformedURLException;
+import java.net.Proxy;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import javax.net.ssl.HttpsURLConnection;
+
+import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.PLUGINS;
+
+@SuppressWarnings("unused") // everything is called via reflection
+class URLConnectionNetworkActions {
+
+    private static final URL HTTP_URL;
+
+    static {
+        try {
+            HTTP_URL = URI.create("http://127.0.0.1/").toURL();
+        } catch (MalformedURLException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static void withPlainNetworkConnection(CheckedConsumer<HttpURLConnection, Exception> connectionConsumer) throws Exception {
+        // Create a HttpURLConnection with minimal overrides to test calling directly into URLConnection methods as much as possible
+        var conn = new HttpURLConnection(HTTP_URL) {
+            @Override
+            public void connect() {}
+
+            @Override
+            public void disconnect() {}
+
+            @Override
+            public boolean usingProxy() {
+                return false;
+            }
+
+            @Override
+            public InputStream getInputStream() throws IOException {
+                // Mock an attempt to call connect
+                throw new ConnectException();
+            }
+        };
+
+        try {
+            connectionConsumer.accept(conn);
+        } catch (java.net.ConnectException e) {
+            // It's OK, it means we passed entitlement checks, and we tried to connect
+        }
+    }
+
+    private static void withJdkHttpConnection(CheckedConsumer<HttpURLConnection, Exception> connectionConsumer) throws Exception {
+        var conn = EntitledActions.createHttpURLConnection();
+        // Be sure we got the connection implementation we want
+        assert HttpURLConnection.class.isAssignableFrom(conn.getClass());
+        try {
+            connectionConsumer.accept((HttpURLConnection) conn);
+        } catch (java.net.ConnectException e) {
+            // It's OK, it means we passed entitlement checks, and we tried to connect
+        }
+    }
+
+    private static void withJdkHttpsConnection(CheckedConsumer<HttpsURLConnection, Exception> connectionConsumer) throws Exception {
+        var conn = EntitledActions.createHttpsURLConnection();
+        // Be sure we got the connection implementation we want
+        assert HttpsURLConnection.class.isAssignableFrom(conn.getClass());
+        try {
+            connectionConsumer.accept((HttpsURLConnection) conn);
+        } catch (java.net.ConnectException e) {
+            // It's OK, it means we passed entitlement checks, and we tried to connect
+        }
+    }
+
+    private static void withJdkFtpConnection(CheckedConsumer<URLConnection, Exception> connectionConsumer) throws Exception {
+        var conn = EntitledActions.createFtpURLConnection();
+        // Be sure we got the connection implementation we want
+        assert conn.getClass().getSimpleName().equals("FtpURLConnection");
+        try {
+            connectionConsumer.accept(conn);
+        } catch (java.net.ConnectException e) {
+            // It's OK, it means we passed entitlement checks, and we tried to connect
+        }
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void urlOpenConnection() throws Exception {
+        URI.create("http://127.0.0.1:12345/").toURL().openConnection();
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    @SuppressForbidden(reason = "just testing, not a real connection")
+    static void urlOpenConnectionWithProxy() throws URISyntaxException, IOException {
+        var url = new URI("http://localhost").toURL();
+        var urlConnection = url.openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(0)));
+        assert urlConnection != null;
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void urlOpenStream() throws Exception {
+        try {
+            URI.create("http://127.0.0.1:12345/").toURL().openStream().close();
+        } catch (java.net.ConnectException e) {
+            // It's OK, it means we passed entitlement checks, and we tried to connect
+        }
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void urlGetContent() throws Exception {
+        try {
+            URI.create("http://127.0.0.1:12345/").toURL().getContent();
+        } catch (java.net.ConnectException e) {
+            // It's OK, it means we passed entitlement checks, and we tried to connect
+        }
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void urlGetContentWithClasses() throws Exception {
+        try {
+            URI.create("http://127.0.0.1:12345/").toURL().getContent(new Class<?>[] { String.class });
+        } catch (java.net.ConnectException e) {
+            // It's OK, it means we passed entitlement checks, and we tried to connect
+        }
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void baseUrlConnectionGetContentLength() throws Exception {
+        withPlainNetworkConnection(URLConnection::getContentLength);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpConnectionGetContentLength() throws Exception {
+        withJdkHttpConnection(URLConnection::getContentLength);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void baseUrlConnectionGetContentType() throws Exception {
+        withPlainNetworkConnection(URLConnection::getContentType);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpConnectionGetContentType() throws Exception {
+        withJdkHttpConnection(URLConnection::getContentType);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void baseUrlConnectionGetContentEncoding() throws Exception {
+        withPlainNetworkConnection(URLConnection::getContentEncoding);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpConnectionGetContentEncoding() throws Exception {
+        withJdkHttpConnection(URLConnection::getContentEncoding);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void baseUrlConnectionGetExpiration() throws Exception {
+        withPlainNetworkConnection(URLConnection::getExpiration);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpConnectionGetExpiration() throws Exception {
+        withJdkHttpConnection(URLConnection::getExpiration);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void baseUrlConnectionGetDate() throws Exception {
+        withPlainNetworkConnection(URLConnection::getDate);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpConnectionGetDate() throws Exception {
+        withJdkHttpConnection(URLConnection::getDate);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void baseUrlConnectionGetLastModified() throws Exception {
+        withPlainNetworkConnection(URLConnection::getLastModified);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpConnectionGetLastModified() throws Exception {
+        withJdkHttpConnection(URLConnection::getLastModified);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void baseUrlConnectionGetHeaderFieldInt() throws Exception {
+        withPlainNetworkConnection(conn -> conn.getHeaderFieldInt("field", 0));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpConnectionGetHeaderFieldInt() throws Exception {
+        withJdkHttpConnection(conn -> conn.getHeaderFieldInt("field", 0));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void baseUrlConnectionGetHeaderFieldLong() throws Exception {
+        withPlainNetworkConnection(conn -> conn.getHeaderFieldLong("field", 0));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpConnectionGetHeaderFieldLong() throws Exception {
+        withJdkHttpConnection(conn -> conn.getHeaderFieldLong("field", 0));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void baseUrlConnectionGetContent() throws Exception {
+        withPlainNetworkConnection(URLConnection::getContent);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpConnectionGetContent() throws Exception {
+        withJdkHttpConnection(URLConnection::getContent);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void baseUrlConnectionGetContentWithClasses() throws Exception {
+        withPlainNetworkConnection(conn -> conn.getContent(new Class<?>[] { String.class }));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpConnectionGetContentWithClasses() throws Exception {
+        withJdkHttpConnection(conn -> conn.getContent(new Class<?>[] { String.class }));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunFtpURLConnectionConnect() throws Exception {
+        withJdkFtpConnection(URLConnection::connect);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunFtpURLConnectionGetInputStream() throws Exception {
+        withJdkFtpConnection(URLConnection::getInputStream);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunFtpURLConnectionGetOutputStream() throws Exception {
+        withJdkFtpConnection(URLConnection::getOutputStream);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void baseHttpURLConnectionGetResponseCode() throws Exception {
+        withPlainNetworkConnection(HttpURLConnection::getResponseCode);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void baseHttpURLConnectionGetResponseMessage() throws Exception {
+        withPlainNetworkConnection(HttpURLConnection::getResponseMessage);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void baseHttpURLConnectionGetHeaderFieldDate() throws Exception {
+        withPlainNetworkConnection(conn -> conn.getHeaderFieldDate("date", 0));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpURLConnectionConnect() throws Exception {
+        withJdkHttpConnection(HttpURLConnection::connect);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpURLConnectionGetOutputStream() throws Exception {
+        withJdkHttpConnection(httpURLConnection -> {
+            httpURLConnection.setDoOutput(true);
+            httpURLConnection.getOutputStream();
+        });
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpURLConnectionGetInputStream() throws Exception {
+        withJdkHttpConnection(HttpURLConnection::getInputStream);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpURLConnectionGetErrorStream() throws Exception {
+        withJdkHttpConnection(HttpURLConnection::getErrorStream);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpURLConnectionGetHeaderFieldWithName() throws Exception {
+        withJdkHttpConnection(conn -> conn.getHeaderField("date"));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpURLConnectionGetHeaderFields() throws Exception {
+        withJdkHttpConnection(HttpURLConnection::getHeaderFields);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpURLConnectionGetHeaderFieldWithIndex() throws Exception {
+        withJdkHttpConnection(conn -> conn.getHeaderField(0));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpURLConnectionGetHeaderFieldKey() throws Exception {
+        withJdkHttpConnection(conn -> conn.getHeaderFieldKey(0));
+    }
+
+    // https
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplConnect() throws Exception {
+        withJdkHttpsConnection(HttpsURLConnection::connect);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetOutputStream() throws Exception {
+        withJdkHttpsConnection(httpsURLConnection -> {
+            httpsURLConnection.setDoOutput(true);
+            httpsURLConnection.getOutputStream();
+        });
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetInputStream() throws Exception {
+        withJdkHttpsConnection(HttpsURLConnection::getInputStream);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetErrorStream() throws Exception {
+        withJdkHttpsConnection(HttpsURLConnection::getErrorStream);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetHeaderFieldWithName() throws Exception {
+        withJdkHttpsConnection(httpsURLConnection -> httpsURLConnection.getHeaderField("date"));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetHeaderFields() throws Exception {
+        withJdkHttpsConnection(HttpsURLConnection::getHeaderFields);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetHeaderFieldWithIndex() throws Exception {
+        withJdkHttpsConnection(httpsURLConnection -> httpsURLConnection.getHeaderField(0));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetHeaderFieldKey() throws Exception {
+        withJdkHttpsConnection(httpsURLConnection -> httpsURLConnection.getHeaderFieldKey(0));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetResponseCode() throws Exception {
+        withJdkHttpsConnection(HttpsURLConnection::getResponseCode);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetResponseMessage() throws Exception {
+        withJdkHttpsConnection(HttpsURLConnection::getResponseMessage);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetContentLength() throws Exception {
+        withJdkHttpsConnection(HttpsURLConnection::getContentLength);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImpl$getContentLengthLong() throws Exception {
+        withJdkHttpsConnection(HttpsURLConnection::getContentLengthLong);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetContentType() throws Exception {
+        withJdkHttpsConnection(HttpsURLConnection::getContentType);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetContentEncoding() throws Exception {
+        withJdkHttpsConnection(HttpsURLConnection::getContentEncoding);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetExpiration() throws Exception {
+        withJdkHttpsConnection(HttpsURLConnection::getExpiration);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetDate() throws Exception {
+        withJdkHttpsConnection(HttpsURLConnection::getDate);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetLastModified() throws Exception {
+        withJdkHttpsConnection(HttpsURLConnection::getLastModified);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetHeaderFieldInt() throws Exception {
+        withJdkHttpsConnection(httpsURLConnection -> httpsURLConnection.getHeaderFieldInt("content-length", -1));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetHeaderFieldLong() throws Exception {
+        withJdkHttpsConnection(httpsURLConnection -> httpsURLConnection.getHeaderFieldLong("content-length", -1));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetHeaderFieldDate() throws Exception {
+        withJdkHttpsConnection(httpsURLConnection -> httpsURLConnection.getHeaderFieldDate("date", 0));
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetContent() throws Exception {
+        withJdkHttpsConnection(HttpsURLConnection::getContent);
+    }
+
+    @EntitlementTest(expectedAccess = PLUGINS)
+    static void sunHttpsURLConnectionImplGetContentWithClasses() throws Exception {
+        withJdkHttpsConnection(httpsURLConnection -> httpsURLConnection.getContent(new Class<?>[] { String.class }));
+    }
+}

+ 1 - 0
libs/entitlement/qa/src/javaRestTest/java/org/elasticsearch/entitlement/qa/EntitlementsTestRule.java

@@ -34,6 +34,7 @@ class EntitlementsTestRule implements TestRule {
     // entitlements that test methods may use, see EntitledActions
     private static final PolicyBuilder ENTITLED_POLICY = (builder, tempDir) -> {
         builder.value("manage_threads");
+        builder.value("outbound_network");
         builder.value(
             Map.of(
                 "files",

+ 479 - 1
libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java

@@ -29,6 +29,7 @@ import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.DatagramSocketImplFactory;
 import java.net.FileNameMap;
+import java.net.HttpURLConnection;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.MulticastSocket;
@@ -631,13 +632,490 @@ public class ElasticsearchEntitlementChecker implements EntitlementChecker {
         policyManager.checkOutboundNetworkAccess(callerClass);
     }
 
+    @Override
+    public void check$java_net_URL$openConnection(Class<?> callerClass, java.net.URL that) {
+        if (isNetworkUrl(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
     @Override
     public void check$java_net_URL$openConnection(Class<?> callerClass, URL that, Proxy proxy) {
-        if (proxy.type() != Proxy.Type.DIRECT) {
+        if (proxy.type() != Proxy.Type.DIRECT || isNetworkUrl(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$java_net_URL$openStream(Class<?> callerClass, java.net.URL that) {
+        if (isNetworkUrl(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$java_net_URL$getContent(Class<?> callerClass, java.net.URL that) {
+        if (isNetworkUrl(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$java_net_URL$getContent(Class<?> callerClass, java.net.URL that, Class<?>[] classes) {
+        if (isNetworkUrl(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    // We have to use class names for sun.net.www classes as java.base does not export them
+    private static final List<String> ADDITIONAL_NETWORK_URL_CONNECT_CLASS_NAMES = List.of(
+        "sun.net.www.protocol.ftp.FtpURLConnection",
+        "sun.net.www.protocol.mailto.MailToURLConnection"
+    );
+
+    private static final Set<String> NETWORK_PROTOCOLS = Set.of("http", "https", "ftp", "mailto");
+
+    private static boolean isNetworkUrl(java.net.URL url) {
+        return NETWORK_PROTOCOLS.contains(url.getProtocol());
+    }
+
+    private static boolean isNetworkUrlConnection(java.net.URLConnection urlConnection) {
+        var connectionClass = urlConnection.getClass();
+        return HttpURLConnection.class.isAssignableFrom(connectionClass)
+            || ADDITIONAL_NETWORK_URL_CONNECT_CLASS_NAMES.contains(connectionClass.getName());
+    }
+
+    @Override
+    public void check$java_net_URLConnection$getContentLength(Class<?> callerClass, java.net.URLConnection that) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$java_net_URLConnection$getContentLengthLong(Class<?> callerClass, java.net.URLConnection that) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$java_net_URLConnection$getContentType(Class<?> callerClass, java.net.URLConnection that) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$java_net_URLConnection$getContentEncoding(Class<?> callerClass, java.net.URLConnection that) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$java_net_URLConnection$getExpiration(Class<?> callerClass, java.net.URLConnection that) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$java_net_URLConnection$getDate(Class<?> callerClass, java.net.URLConnection that) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$java_net_URLConnection$getLastModified(Class<?> callerClass, java.net.URLConnection that) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$java_net_URLConnection$getHeaderFieldInt(
+        Class<?> callerClass,
+        java.net.URLConnection that,
+        String name,
+        int defaultValue
+    ) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$java_net_URLConnection$getHeaderFieldLong(
+        Class<?> callerClass,
+        java.net.URLConnection that,
+        String name,
+        long defaultValue
+    ) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$java_net_URLConnection$getHeaderFieldDate(
+        Class<?> callerClass,
+        java.net.URLConnection that,
+        String name,
+        long defaultValue
+    ) {
+        if (isNetworkUrlConnection(that)) {
             policyManager.checkOutboundNetworkAccess(callerClass);
         }
     }
 
+    @Override
+    public void check$java_net_URLConnection$getContent(Class<?> callerClass, java.net.URLConnection that) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$java_net_URLConnection$getContent(Class<?> callerClass, java.net.URLConnection that, Class<?>[] classes) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$java_net_HttpURLConnection$getResponseCode(Class<?> callerClass, java.net.HttpURLConnection that) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$java_net_HttpURLConnection$getResponseMessage(Class<?> callerClass, java.net.HttpURLConnection that) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$java_net_HttpURLConnection$getHeaderFieldDate(
+        Class<?> callerClass,
+        java.net.HttpURLConnection that,
+        String name,
+        long defaultValue
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    // Using java.net.URLConnection for "that" as sun.net.www.URLConnection is not exported
+    @Override
+    public void check$sun_net_www_URLConnection$getHeaderField(Class<?> callerClass, java.net.URLConnection that, String name) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$sun_net_www_URLConnection$getHeaderFields(Class<?> callerClass, java.net.URLConnection that) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$sun_net_www_URLConnection$getHeaderFieldKey(Class<?> callerClass, java.net.URLConnection that, int n) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$sun_net_www_URLConnection$getHeaderField(Class<?> callerClass, java.net.URLConnection that, int n) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$sun_net_www_URLConnection$getContentType(Class<?> callerClass, java.net.URLConnection that) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$sun_net_www_URLConnection$getContentLength(Class<?> callerClass, java.net.URLConnection that) {
+        if (isNetworkUrlConnection(that)) {
+            policyManager.checkOutboundNetworkAccess(callerClass);
+        }
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_ftp_FtpURLConnection$connect(Class<?> callerClass, java.net.URLConnection that) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_ftp_FtpURLConnection$getInputStream(Class<?> callerClass, java.net.URLConnection that) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_ftp_FtpURLConnection$getOutputStream(Class<?> callerClass, java.net.URLConnection that) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_http_HttpURLConnection$$openConnectionCheckRedirects(
+        Class<?> callerClass,
+        java.net.URLConnection c
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_http_HttpURLConnection$connect(Class<?> callerClass, java.net.HttpURLConnection that) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_http_HttpURLConnection$getOutputStream(Class<?> callerClass, java.net.HttpURLConnection that) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_http_HttpURLConnection$getInputStream(Class<?> callerClass, java.net.HttpURLConnection that) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_http_HttpURLConnection$getErrorStream(Class<?> callerClass, java.net.HttpURLConnection that) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_http_HttpURLConnection$getHeaderField(
+        Class<?> callerClass,
+        java.net.HttpURLConnection that,
+        String name
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_http_HttpURLConnection$getHeaderFields(Class<?> callerClass, java.net.HttpURLConnection that) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_http_HttpURLConnection$getHeaderField(
+        Class<?> callerClass,
+        java.net.HttpURLConnection that,
+        int n
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_http_HttpURLConnection$getHeaderFieldKey(
+        Class<?> callerClass,
+        java.net.HttpURLConnection that,
+        int n
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$connect(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getOutputStream(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getInputStream(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getErrorStream(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getHeaderField(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that,
+        String name
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getHeaderFields(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getHeaderField(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that,
+        int n
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getHeaderFieldKey(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that,
+        int n
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getResponseCode(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getResponseMessage(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getContentLength(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getContentLengthLong(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getContentType(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getContentEncoding(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getExpiration(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getDate(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getLastModified(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getHeaderFieldInt(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that,
+        String name,
+        int defaultValue
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getHeaderFieldLong(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that,
+        String name,
+        long defaultValue
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getHeaderFieldDate(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that,
+        String name,
+        long defaultValue
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getContent(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_HttpsURLConnectionImpl$getContent(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that,
+        Class<?>[] classes
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
+    @Override
+    public void check$sun_net_www_protocol_https_AbstractDelegateHttpsURLConnection$connect(
+        Class<?> callerClass,
+        javax.net.ssl.HttpsURLConnection that
+    ) {
+        policyManager.checkOutboundNetworkAccess(callerClass);
+    }
+
     @Override
     public void check$jdk_internal_net_http_HttpClientImpl$send(
         Class<?> callerClass,

+ 1 - 0
modules/repository-azure/src/main/plugin-metadata/entitlement-policy.yaml

@@ -9,6 +9,7 @@ io.netty.common:
     - path: "/proc/sys/net/core/somaxconn"
       mode: read
 com.azure.identity:
+  - outbound_network
   - files:
     - relative_path: "storage-azure/" #/config/storage-azure/azure-federated-token
       relative_to: config

+ 1 - 0
modules/repository-gcs/src/main/plugin-metadata/entitlement-policy.yaml

@@ -1,2 +1,3 @@
 ALL-UNNAMED:
   - set_https_connection_properties # required by google-http-client
+  - outbound_network

+ 1 - 0
plugins/discovery-gce/src/main/plugin-metadata/entitlement-policy.yaml

@@ -1,2 +1,3 @@
 ALL-UNNAMED:
   - set_https_connection_properties # required by google-http-client
+  - outbound_network

+ 2 - 0
x-pack/plugin/ml-package-loader/src/main/plugin-metadata/entitlement-policy.yaml

@@ -0,0 +1,2 @@
+ALL-UNNAMED:
+  - outbound_network