From 84a490e9d6e6e2de09d14167e5719b467fc24e59 Mon Sep 17 00:00:00 2001 From: Kirill Anisimov Date: Tue, 9 Jun 2026 12:07:00 +0700 Subject: [PATCH 1/5] IGNITE-28743: Block remote HTTP/HTTPS/FTP URLs in resolveSpringUrl to prevent RCE via JDBC cfg:// --- .../ignite/internal/util/IgniteUtils.java | 40 +++++++++ .../internal/util/IgniteUtilsSelfTest.java | 89 +++++++++++++++++++ 2 files changed, 129 insertions(+) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index 1513346138589..e0d40d85503aa 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -387,6 +387,21 @@ public abstract class IgniteUtils extends CommonUtils { /** Ignite Work Directory. */ public static final String IGNITE_WORK_DIR = System.getenv(IgniteSystemProperties.IGNITE_WORK_DIR); + /** + * System property to allow remote HTTP/HTTPS URLs when loading Spring XML configuration. + * Remote URLs are blocked by default to prevent RCE via attacker-controlled Spring XML. + * FTP is always blocked regardless of this property due to MITM risk. + */ + public static final String IGNITE_ALLOW_REMOTE_SPRING_CFG_URL = "ignite.spring.cfg.allowRemoteUrl"; + + /** URL schemes that load remote content and are blocked by default in Spring configuration. */ + private static final Set REMOTE_CFG_SCHEMES = Collections.unmodifiableSet( + new HashSet<>(Arrays.asList("http", "https", "ftp", "ftps"))); + + /** URL schemes that are always blocked regardless of system property due to security risk. */ + private static final Set ALWAYS_BLOCKED_CFG_SCHEMES = Collections.unmodifiableSet( + new HashSet<>(Arrays.asList("ftp", "ftps"))); + /** Random is used to get random server node to authentication from client node. */ private static final Random RND = new Random(System.currentTimeMillis()); @@ -2600,6 +2615,31 @@ public static URL resolveSpringUrl(String springCfgPath) throws IgniteCheckedExc try { url = new URL(springCfgPath); + + String scheme = url.getProtocol().toLowerCase(); + + if (REMOTE_CFG_SCHEMES.contains(scheme)) { + // FTP is always blocked — unencrypted, susceptible to MITM + if (ALWAYS_BLOCKED_CFG_SCHEMES.contains(scheme)) + throw new IgniteCheckedException( + "Spring configuration URLs with scheme '" + scheme + "' are always blocked " + + "due to security risk (unencrypted transfer, MITM vulnerability). " + + "Use HTTPS or a local file/classpath reference instead. " + + "Provided host: " + url.getHost() + ); + + // HTTP/HTTPS blocked by default, allowed via system property + boolean allowRemote = Boolean.getBoolean(IGNITE_ALLOW_REMOTE_SPRING_CFG_URL); + + if (!allowRemote) + throw new IgniteCheckedException( + "Remote Spring configuration URLs (http/https) are not allowed by default " + + "to prevent remote code execution via attacker-controlled Spring XML. " + + "Provided host: " + url.getHost() + ". " + + "To allow remote URLs set system property: -D" + + IGNITE_ALLOW_REMOTE_SPRING_CFG_URL + "=true" + ); + } } catch (MalformedURLException e) { url = resolveIgniteUrl(springCfgPath); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/util/IgniteUtilsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/util/IgniteUtilsSelfTest.java index 19f6ad17c38d8..6ed838c68ec67 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/util/IgniteUtilsSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/util/IgniteUtilsSelfTest.java @@ -1615,6 +1615,95 @@ public void testLongToBytes() { } } + /** + * Test that remote HTTP URL in Spring cfg is blocked by default. + */ + @Test + public void testResolveSpringUrlBlocksHttpByDefault() { + assertThrows(log, () -> { + IgniteUtils.resolveSpringUrl("http://attacker.example.com/evil.xml"); + return null; + }, IgniteCheckedException.class, "Remote Spring configuration URLs"); + } + + /** + * Test that remote HTTPS URL in Spring cfg is blocked by default. + */ + @Test + public void testResolveSpringUrlBlocksHttpsByDefault() { + assertThrows(log, () -> { + IgniteUtils.resolveSpringUrl("https://attacker.example.com/evil.xml"); + return null; + }, IgniteCheckedException.class, "Remote Spring configuration URLs"); + } + + /** + * Test that remote FTP URL in Spring cfg is blocked by default. + */ + @Test + public void testResolveSpringUrlBlocksFtpByDefault() { + assertThrows(log, () -> { + IgniteUtils.resolveSpringUrl("ftp://attacker.example.com/evil.xml"); + return null; + }, IgniteCheckedException.class, "always blocked"); + } + + /** + * Test that error message contains guidance on how to enable remote URLs. + */ + @Test + public void testResolveSpringUrlErrorMessageContainsGuidance() { + try { + IgniteUtils.resolveSpringUrl("http://attacker.example.com/evil.xml"); + fail("Expected IgniteCheckedException"); + } + catch (IgniteCheckedException e) { + assertTrue( + "Error message should contain system property name", + e.getMessage().contains(IgniteUtils.IGNITE_ALLOW_REMOTE_SPRING_CFG_URL) + ); + assertFalse( + "Error message should not contain full URL to avoid credential leak", + e.getMessage().contains("http://attacker.example.com/evil.xml") + ); + assertTrue( + "Error message should contain host", + e.getMessage().contains("attacker.example.com") + ); + } + } + + /** + * Test that remote HTTP URL is allowed when system property is set. + */ + @Test + @WithSystemProperty(key = "ignite.spring.cfg.allowRemoteUrl", value = "true") + public void testResolveSpringUrlAllowsHttpWhenPropertySet() { + // Should not throw — validation passes when flag is true. + // Will throw MalformedURLException or connection error, not our security check. + try { + IgniteUtils.resolveSpringUrl("http://127.0.0.1:1/nonexistent.xml"); + } + catch (IgniteCheckedException e) { + assertFalse( + "Should not throw security exception when flag is enabled", + e.getMessage().contains("Remote Spring configuration URLs") + ); + } + } + + /** + * Test that FTP is always blocked even when remote URL property is set. + */ + @Test + @WithSystemProperty(key = "ignite.spring.cfg.allowRemoteUrl", value = "true") + public void testResolveSpringUrlFtpAlwaysBlocked() { + assertThrows(log, () -> { + IgniteUtils.resolveSpringUrl("ftp://attacker.example.com/evil.xml"); + return null; + }, IgniteCheckedException.class, "always blocked"); + } + /** */ private byte[] asByteArray(String text) { String[] split = text.split("-"); From 27d5cc3c96a5c1f5796f843b7cf169a3a6311607 Mon Sep 17 00:00:00 2001 From: Kirill Anisimov Date: Tue, 9 Jun 2026 12:37:44 +0700 Subject: [PATCH 2/5] IGNITE-28743 Validate URL scheme in resolveSpringUrl --- .../apache/ignite/IgniteSystemProperties.java | 9 +++++++++ .../ignite/internal/util/IgniteUtils.java | 11 ++--------- .../internal/util/IgniteUtilsSelfTest.java | 18 ++++-------------- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java index b1c36a9015827..8c52a124ede20 100644 --- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java +++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java @@ -1967,6 +1967,15 @@ public final class IgniteSystemProperties extends IgniteCommonsSystemProperties @SystemProperty(value = "Packages list to expose in configuration view") public static final String IGNITE_CONFIGURATION_VIEW_PACKAGES = "IGNITE_CONFIGURATION_VIEW_PACKAGES"; + + /** + * System property to allow remote HTTP/HTTPS URLs when loading Spring XML configuration. + * Remote URLs are blocked by default to prevent RCE via attacker-controlled Spring XML. + * FTP is always blocked regardless of this property due to MITM risk. + */ + @SystemProperty(value = "Allow remote HTTP/HTTPS URLs when loading Spring XML configuration") + public static final String IGNITE_ALLOW_REMOTE_SPRING_CFG_URL = "ignite.spring.cfg.allowRemoteUrl"; + /** * Enforces singleton. */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index e0d40d85503aa..fd18f13a161e0 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -387,13 +387,6 @@ public abstract class IgniteUtils extends CommonUtils { /** Ignite Work Directory. */ public static final String IGNITE_WORK_DIR = System.getenv(IgniteSystemProperties.IGNITE_WORK_DIR); - /** - * System property to allow remote HTTP/HTTPS URLs when loading Spring XML configuration. - * Remote URLs are blocked by default to prevent RCE via attacker-controlled Spring XML. - * FTP is always blocked regardless of this property due to MITM risk. - */ - public static final String IGNITE_ALLOW_REMOTE_SPRING_CFG_URL = "ignite.spring.cfg.allowRemoteUrl"; - /** URL schemes that load remote content and are blocked by default in Spring configuration. */ private static final Set REMOTE_CFG_SCHEMES = Collections.unmodifiableSet( new HashSet<>(Arrays.asList("http", "https", "ftp", "ftps"))); @@ -2629,7 +2622,7 @@ public static URL resolveSpringUrl(String springCfgPath) throws IgniteCheckedExc ); // HTTP/HTTPS blocked by default, allowed via system property - boolean allowRemote = Boolean.getBoolean(IGNITE_ALLOW_REMOTE_SPRING_CFG_URL); + boolean allowRemote = Boolean.getBoolean(IgniteSystemProperties.IGNITE_ALLOW_REMOTE_SPRING_CFG_URL); if (!allowRemote) throw new IgniteCheckedException( @@ -2637,7 +2630,7 @@ public static URL resolveSpringUrl(String springCfgPath) throws IgniteCheckedExc "to prevent remote code execution via attacker-controlled Spring XML. " + "Provided host: " + url.getHost() + ". " + "To allow remote URLs set system property: -D" + - IGNITE_ALLOW_REMOTE_SPRING_CFG_URL + "=true" + IgniteSystemProperties.IGNITE_ALLOW_REMOTE_SPRING_CFG_URL + "=true" ); } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/util/IgniteUtilsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/util/IgniteUtilsSelfTest.java index 6ed838c68ec67..e0149ef69bd41 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/util/IgniteUtilsSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/util/IgniteUtilsSelfTest.java @@ -1615,17 +1615,6 @@ public void testLongToBytes() { } } - /** - * Test that remote HTTP URL in Spring cfg is blocked by default. - */ - @Test - public void testResolveSpringUrlBlocksHttpByDefault() { - assertThrows(log, () -> { - IgniteUtils.resolveSpringUrl("http://attacker.example.com/evil.xml"); - return null; - }, IgniteCheckedException.class, "Remote Spring configuration URLs"); - } - /** * Test that remote HTTPS URL in Spring cfg is blocked by default. */ @@ -1649,10 +1638,11 @@ public void testResolveSpringUrlBlocksFtpByDefault() { } /** - * Test that error message contains guidance on how to enable remote URLs. + * Test that remote HTTP URL in Spring cfg is blocked by default + * and error message contains guidance on how to enable remote URLs. */ @Test - public void testResolveSpringUrlErrorMessageContainsGuidance() { + public void testResolveSpringUrlBlocksHttpByDefault() { try { IgniteUtils.resolveSpringUrl("http://attacker.example.com/evil.xml"); fail("Expected IgniteCheckedException"); @@ -1660,7 +1650,7 @@ public void testResolveSpringUrlErrorMessageContainsGuidance() { catch (IgniteCheckedException e) { assertTrue( "Error message should contain system property name", - e.getMessage().contains(IgniteUtils.IGNITE_ALLOW_REMOTE_SPRING_CFG_URL) + e.getMessage().contains(IgniteSystemProperties.IGNITE_ALLOW_REMOTE_SPRING_CFG_URL) ); assertFalse( "Error message should not contain full URL to avoid credential leak", From 7313a322b47a58c5d8b156b54d2bffd40e52ad18 Mon Sep 17 00:00:00 2001 From: Kirill Anisimov Date: Mon, 15 Jun 2026 12:12:23 +0700 Subject: [PATCH 3/5] IGNITE-28743 Add jdbc tests --- .../jdbc2/JdbcConnectionSelfTest.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java index b8056bfaca7a8..96f1bdc727402 100644 --- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java @@ -296,4 +296,67 @@ public void testSqlHints() throws Exception { assertTrue(((JdbcConnection)conn).skipReducerOnUpdate()); } } + + /** + * Test that JDBC cfg:// URL with remote HTTP location is blocked by default to prevent RCE. + */ + @Test + public void testRemoteHttpCfgUrlIsBlocked() { + final String url = CFG_URL_PREFIX + "http://attacker.example.com/evil.xml"; + + GridTestUtils.assertThrows( + log, + new Callable() { + @Override public Object call() throws Exception { + try (Connection conn = DriverManager.getConnection(url)) { + return conn; + } + } + }, + SQLException.class, + "Remote Spring configuration URLs" + ); + } + + /** + * Test that JDBC cfg:// URL with remote HTTPS location is blocked by default to prevent RCE. + */ + @Test + public void testRemoteHttpsCfgUrlIsBlocked() { + final String url = CFG_URL_PREFIX + "https://attacker.example.com/evil.xml"; + + GridTestUtils.assertThrows( + log, + new Callable() { + @Override public Object call() throws Exception { + try (Connection conn = DriverManager.getConnection(url)) { + return conn; + } + } + }, + SQLException.class, + "Remote Spring configuration URLs" + ); + } + + /** + * Test that JDBC cfg:// URL with FTP location is always blocked. + */ + @Test + public void testFtpCfgUrlIsAlwaysBlocked() { + final String url = CFG_URL_PREFIX + "ftp://attacker.example.com/evil.xml"; + + GridTestUtils.assertThrows( + log, + new Callable() { + @Override public Object call() throws Exception { + try (Connection conn = DriverManager.getConnection(url)) { + return conn; + } + } + }, + SQLException.class, + "always blocked" + ); + } } From b53b230913dbbddcc8e9550225d318efcbc79ce8 Mon Sep 17 00:00:00 2001 From: Kirill Anisimov Date: Mon, 22 Jun 2026 14:29:23 +0700 Subject: [PATCH 4/5] IGNITE-28743 Combine three tests into one --- .../jdbc2/JdbcConnectionSelfTest.java | 73 +++++-------------- 1 file changed, 17 insertions(+), 56 deletions(-) diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java index 96f1bdc727402..0e69395df736e 100644 --- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java @@ -20,6 +20,7 @@ import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; +import java.util.Arrays; import java.util.UUID; import java.util.concurrent.Callable; import org.apache.ignite.configuration.CacheConfiguration; @@ -298,65 +299,25 @@ public void testSqlHints() throws Exception { } /** - * Test that JDBC cfg:// URL with remote HTTP location is blocked by default to prevent RCE. + * Test that JDBC cfg:// URL with remote HTTP, HTTPS, and FTP location is blocked. */ @Test - public void testRemoteHttpCfgUrlIsBlocked() { - final String url = CFG_URL_PREFIX + "http://attacker.example.com/evil.xml"; + public void testRemoteCfgUrlsAreBlocked() { + for (String scheme : Arrays.asList("http", "https", "ftp", "ftps")) { + final String url = CFG_URL_PREFIX + scheme + "://attacker.example.com/evil.xml"; - GridTestUtils.assertThrows( - log, - new Callable() { - @Override public Object call() throws Exception { - try (Connection conn = DriverManager.getConnection(url)) { - return conn; - } - } - }, - SQLException.class, - "Remote Spring configuration URLs" - ); - } - - /** - * Test that JDBC cfg:// URL with remote HTTPS location is blocked by default to prevent RCE. - */ - @Test - public void testRemoteHttpsCfgUrlIsBlocked() { - final String url = CFG_URL_PREFIX + "https://attacker.example.com/evil.xml"; - - GridTestUtils.assertThrows( - log, - new Callable() { - @Override public Object call() throws Exception { - try (Connection conn = DriverManager.getConnection(url)) { - return conn; - } - } - }, - SQLException.class, - "Remote Spring configuration URLs" - ); - } - - /** - * Test that JDBC cfg:// URL with FTP location is always blocked. - */ - @Test - public void testFtpCfgUrlIsAlwaysBlocked() { - final String url = CFG_URL_PREFIX + "ftp://attacker.example.com/evil.xml"; - - GridTestUtils.assertThrows( - log, - new Callable() { - @Override public Object call() throws Exception { - try (Connection conn = DriverManager.getConnection(url)) { - return conn; + GridTestUtils.assertThrows( + log, + new Callable() { + @Override public Object call() throws Exception { + try (Connection conn = DriverManager.getConnection(url)) { + return conn; + } } - } - }, - SQLException.class, - "always blocked" - ); + }, + SQLException.class, + null + ); + } } } From 7eb58fb1f1a590c53a77fb0ee05d1bba5b29d917 Mon Sep 17 00:00:00 2001 From: Kirill Anisimov Date: Mon, 22 Jun 2026 14:39:01 +0700 Subject: [PATCH 5/5] IGNITE-28743 Add a test that verifies that no security-exception is thrown when the flag is enabled --- .../jdbc2/JdbcConnectionSelfTest.java | 155 +++++++++++------- 1 file changed, 97 insertions(+), 58 deletions(-) diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java index 0e69395df736e..6ac3cca69ece6 100644 --- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcConnectionSelfTest.java @@ -27,6 +27,7 @@ import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.testframework.GridTestUtils; +import org.apache.ignite.testframework.junits.WithSystemProperty; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.jetbrains.annotations.NotNull; import org.junit.Test; @@ -37,10 +38,14 @@ * Connection test. */ public class JdbcConnectionSelfTest extends GridCommonAbstractTest { - /** Custom cache name. */ + /** + * Custom cache name. + */ private static final String CUSTOM_CACHE_NAME = "custom-cache"; - /** Grid count. */ + /** + * Grid count. + */ private static final int GRID_CNT = 2; /** @@ -50,8 +55,11 @@ protected String configURL() { return "modules/clients/src/test/config/jdbc-config.xml"; } - /** {@inheritDoc} */ - @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + /** + * {@inheritDoc} + */ + @Override + protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); cfg.setCacheConfiguration(cacheConfiguration(DEFAULT_CACHE_NAME), cacheConfiguration(CUSTOM_CACHE_NAME)); @@ -72,8 +80,11 @@ private CacheConfiguration cacheConfiguration(@NotNull String name) throws Excep return cfg; } - /** {@inheritDoc} */ - @Override protected void beforeTestsStarted() throws Exception { + /** + * {@inheritDoc} + */ + @Override + protected void beforeTestsStarted() throws Exception { startGridsMultiThreaded(GRID_CNT); } @@ -86,12 +97,12 @@ public void testDefaults() throws Exception { try (Connection conn = DriverManager.getConnection(url)) { assertNotNull(conn); - assertTrue(((JdbcConnection)conn).ignite().configuration().isClientMode()); + assertTrue(((JdbcConnection) conn).ignite().configuration().isClientMode()); } try (Connection conn = DriverManager.getConnection(url + '/')) { assertNotNull(conn); - assertTrue(((JdbcConnection)conn).ignite().configuration().isClientMode()); + assertTrue(((JdbcConnection) conn).ignite().configuration().isClientMode()); } } @@ -125,7 +136,8 @@ public void testWrongNodeId() throws Exception { GridTestUtils.assertThrows( log, new Callable() { - @Override public Object call() throws Exception { + @Override + public Object call() throws Exception { try (Connection conn = DriverManager.getConnection(url)) { return conn; } @@ -150,7 +162,8 @@ public void testClientNodeId() throws Exception { GridTestUtils.assertThrows( log, new Callable() { - @Override public Object call() throws Exception { + @Override + public Object call() throws Exception { try (Connection conn = DriverManager.getConnection(url)) { return conn; } @@ -181,16 +194,17 @@ public void testWrongCache() throws Exception { final String url = CFG_URL_PREFIX + "cache=wrongCacheName@" + configURL(); GridTestUtils.assertThrows( - log, - new Callable() { - @Override public Object call() throws Exception { - try (Connection conn = DriverManager.getConnection(url)) { - return conn; + log, + new Callable() { + @Override + public Object call() throws Exception { + try (Connection conn = DriverManager.getConnection(url)) { + return conn; + } } - } - }, - SQLException.class, - "Client is invalid. Probably cache name is wrong." + }, + SQLException.class, + "Client is invalid. Probably cache name is wrong." ); } @@ -210,16 +224,17 @@ public void testClose() throws Exception { assertTrue(conn.isClosed()); GridTestUtils.assertThrows( - log, - new Callable() { - @Override public Object call() throws Exception { - conn.isValid(2); + log, + new Callable() { + @Override + public Object call() throws Exception { + conn.isValid(2); - return null; - } - }, - SQLException.class, - "Connection is closed." + return null; + } + }, + SQLException.class, + "Connection is closed." ); } } @@ -266,35 +281,35 @@ public void testTxAllowedRollback() throws Exception { @Test public void testSqlHints() throws Exception { try (final Connection conn = DriverManager.getConnection(CFG_URL_PREFIX + "enforceJoinOrder=true@" - + configURL())) { - assertTrue(((JdbcConnection)conn).isEnforceJoinOrder()); - assertFalse(((JdbcConnection)conn).isDistributedJoins()); - assertFalse(((JdbcConnection)conn).isCollocatedQuery()); - assertFalse(((JdbcConnection)conn).skipReducerOnUpdate()); + + configURL())) { + assertTrue(((JdbcConnection) conn).isEnforceJoinOrder()); + assertFalse(((JdbcConnection) conn).isDistributedJoins()); + assertFalse(((JdbcConnection) conn).isCollocatedQuery()); + assertFalse(((JdbcConnection) conn).skipReducerOnUpdate()); } try (final Connection conn = DriverManager.getConnection(CFG_URL_PREFIX + "distributedJoins=true@" - + configURL())) { - assertFalse(((JdbcConnection)conn).isEnforceJoinOrder()); - assertTrue(((JdbcConnection)conn).isDistributedJoins()); - assertFalse(((JdbcConnection)conn).isCollocatedQuery()); - assertFalse(((JdbcConnection)conn).skipReducerOnUpdate()); + + configURL())) { + assertFalse(((JdbcConnection) conn).isEnforceJoinOrder()); + assertTrue(((JdbcConnection) conn).isDistributedJoins()); + assertFalse(((JdbcConnection) conn).isCollocatedQuery()); + assertFalse(((JdbcConnection) conn).skipReducerOnUpdate()); } try (final Connection conn = DriverManager.getConnection(CFG_URL_PREFIX + "collocated=true@" - + configURL())) { - assertFalse(((JdbcConnection)conn).isEnforceJoinOrder()); - assertFalse(((JdbcConnection)conn).isDistributedJoins()); - assertTrue(((JdbcConnection)conn).isCollocatedQuery()); - assertFalse(((JdbcConnection)conn).skipReducerOnUpdate()); + + configURL())) { + assertFalse(((JdbcConnection) conn).isEnforceJoinOrder()); + assertFalse(((JdbcConnection) conn).isDistributedJoins()); + assertTrue(((JdbcConnection) conn).isCollocatedQuery()); + assertFalse(((JdbcConnection) conn).skipReducerOnUpdate()); } try (final Connection conn = DriverManager.getConnection(CFG_URL_PREFIX + "skipReducerOnUpdate=true@" - + configURL())) { - assertFalse(((JdbcConnection)conn).isEnforceJoinOrder()); - assertFalse(((JdbcConnection)conn).isDistributedJoins()); - assertFalse(((JdbcConnection)conn).isCollocatedQuery()); - assertTrue(((JdbcConnection)conn).skipReducerOnUpdate()); + + configURL())) { + assertFalse(((JdbcConnection) conn).isEnforceJoinOrder()); + assertFalse(((JdbcConnection) conn).isDistributedJoins()); + assertFalse(((JdbcConnection) conn).isCollocatedQuery()); + assertTrue(((JdbcConnection) conn).skipReducerOnUpdate()); } } @@ -307,17 +322,41 @@ public void testRemoteCfgUrlsAreBlocked() { final String url = CFG_URL_PREFIX + scheme + "://attacker.example.com/evil.xml"; GridTestUtils.assertThrows( - log, - new Callable() { - @Override public Object call() throws Exception { - try (Connection conn = DriverManager.getConnection(url)) { - return conn; + log, + new Callable() { + @Override + public Object call() throws Exception { + try (Connection conn = DriverManager.getConnection(url)) { + return conn; + } } - } - }, - SQLException.class, - null + }, + SQLException.class, + null ); } } -} + + /** + * Test that JDBC cfg:// URL with remote HTTP location is allowed when system property is set. + */ + @Test + @WithSystemProperty(key = "ignite.spring.cfg.allowRemoteUrl", value = "true") + public void testRemoteHttpCfgUrlAllowedWhenFlagSet() { + final String url = CFG_URL_PREFIX + "http://127.0.0.1:1/nonexistent.xml"; + + GridTestUtils.assertThrows( + log, + new Callable() { + @Override + public Object call() throws Exception { + try (Connection conn = DriverManager.getConnection(url)) { + return conn; + } + } + }, + SQLException.class, + null + ); + } +} \ No newline at end of file