This is an automated email from the ASF dual-hosted git repository.

nizhikov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new f9273aef880 IGNITE-28946 Statically configured 
IgniteMarshallerClassFilter (#13425)
f9273aef880 is described below

commit f9273aef8803031c534d2b0bdf0697328eea03d3
Author: Nikolay <[email protected]>
AuthorDate: Tue Aug 4 22:32:32 2026 +0300

    IGNITE-28946 Statically configured IgniteMarshallerClassFilter (#13425)
---
 .../ignite/marshaller/MarshallerContext.java       |   8 -
 .../apache/ignite/marshaller/MarshallerUtils.java  |  87 ++------
 .../org/apache/ignite/marshaller/Marshallers.java  |   9 -
 .../ignite/marshaller/MarshallersFactory.java      |   8 -
 .../optimized/OptimizedObjectInputStream.java      |   5 +-
 .../ignite/marshaller/MarshallersFactoryImpl.java  |  12 +-
 .../marshaller/jdk}/IgniteObjectInputFilter.java   |  16 +-
 .../ignite/marshaller/jdk/JdkMarshallerImpl.java   |  41 ++--
 .../jdk/JdkMarshallerObjectInputStream.java        |  12 +-
 modules/clients/pom.xml                            |   7 +
 .../client/suite/IgniteClientTestSuite.java        |   9 +-
 .../rest/JettyRestProcessorAbstractSelfTest.java   |  64 +-----
 .../rest/JettyRestProcessorClassFilterTest.java    | 121 ++++++++++
 .../rest/TcpRestUnmarshalVulnerabilityTest.java    | 196 ++++++++--------
 .../jdbc/thin/JdbcThinConnectionSelfTest.java      |   5 -
 .../client/ClientMarshallerBenchmarkTest.java      |  16 +-
 .../ignite/internal/GridKernalContextImpl.java     |   4 +-
 .../org/apache/ignite/internal/IgniteKernal.java   |   7 -
 .../ignite/internal/MarshallerContextImpl.java     |  34 +--
 .../marshaller/jdk/GridClientJdkMarshaller.java    |  35 +--
 .../optimized/GridClientOptimizedMarshaller.java   |   4 +-
 .../internal/jdbc/thin/JdbcThinConnection.java     |  13 +-
 .../ignite/internal/jdbc/thin/JdbcThinTcpIo.java   |   2 +-
 .../wal/reader/StandaloneGridKernalContext.java    |   3 +-
 .../processors/odbc/ClientListenerNioListener.java |   2 +-
 .../processors/platform/utils/PlatformUtils.java   |   2 +-
 .../rest/protocols/tcp/GridTcpRestParser.java      |  11 +-
 .../rest/protocols/tcp/GridTcpRestProtocol.java    |  15 +-
 .../ignite/stream/socket/SocketStreamer.java       |   3 +-
 .../test/config/class_list_exploit_included.txt    |   2 +-
 .../src/test/config/class_list_test_excluded.txt   |  17 --
 .../internal/MarshallerContextLockingSelfTest.java |   2 +-
 .../GridBinaryMarshallerCtxDisabledSelfTest.java   |   6 -
 .../binary/RawBinaryObjectExtractorTest.java       |   6 -
 .../cache/GridCacheEntryMemorySizeSelfTest.java    |   5 -
 .../DistributedMetaStorageClassloadingTest.java    |  96 ++------
 .../marshaller/MarshallerContextSelfTest.java      |   2 +-
 .../marshaller/MarshallerContextTestImpl.java      |   2 +-
 .../marshaller/ObjectInputStreamFilteringTest.java |  27 ---
 .../tcp/DiscoveryUnmarshalVulnerabilityTest.java   | 248 ++++++++++++---------
 .../SocketStreamerUnmarshalVulnerabilityTest.java  | 246 +++++++++++---------
 .../junits/GridTestKernalContext.java              |   1 -
 .../IgniteSpiDiscoverySelfTestSuite2.java          |   8 +-
 .../testsuites/IgniteStreamSelfTestSuite.java      |   7 +-
 .../internal/jackson/IgniteObjectMapper.java       |   7 +-
 .../internal/client/thin/TcpIgniteClient.java      |  13 +-
 46 files changed, 651 insertions(+), 795 deletions(-)

diff --git 
a/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java
 
b/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java
index 1cbc84464fc..4a1f9998f17 100644
--- 
a/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java
+++ 
b/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java
@@ -18,7 +18,6 @@
 package org.apache.ignite.marshaller;
 
 import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.marshaller.jdk.JdkMarshaller;
 
 /**
@@ -112,13 +111,6 @@ public interface MarshallerContext {
      */
     public boolean isSystemType(String typeName);
 
-    /**
-     * Returns class name filter.
-     *
-     * @return Class name filter.
-     */
-    public IgnitePredicate<String> classNameFilter();
-
     /**
      * @return  JDK marshaller instance.
      */
diff --git 
a/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
 
b/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
index 9248181aa07..428e0a673a7 100644
--- 
a/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
+++ 
b/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
@@ -24,17 +24,14 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.io.ObjectInputFilter;
 import java.net.URL;
 import java.util.Enumeration;
-import java.util.Objects;
 import java.util.function.Consumer;
-import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteCommonsSystemProperties;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.internal.ClassSet;
+import org.apache.ignite.internal.util.CommonUtils;
 
-import static 
org.apache.ignite.IgniteCommonsSystemProperties.IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION;
 import static 
org.apache.ignite.IgniteCommonsSystemProperties.IGNITE_MARSHALLER_BLACKLIST;
 
 /**
@@ -54,7 +51,8 @@ public class MarshallerUtils {
     public static final String DEFAULT_WHITELIST_CLS_NAMES_FILE = 
"META-INF/classnames-default-whitelist.properties";
 
     /** */
-    private static final Object MUX = new Object();
+    private static final IgniteMarshallerClassFilter 
IGNITE_MARSHALLER_CLASS_FILTER
+        = new IgniteMarshallerClassFilter(classWhiteList(), classBlackList());
 
     /**
      * Private constructor.
@@ -66,80 +64,44 @@ public class MarshallerUtils {
     /**
      * Returns class name filter for marshaller.
      *
-     * @param clsLdr Class loader.
      * @return Class name filter for marshaller.
      */
-    public static IgniteMarshallerClassFilter classNameFilter(ClassLoader 
clsLdr) throws IgniteCheckedException {
-        return new IgniteMarshallerClassFilter(classWhiteList(clsLdr), 
classBlackList(clsLdr));
+    public static IgniteMarshallerClassFilter classNameFilter() {
+        return IGNITE_MARSHALLER_CLASS_FILTER;
     }
 
     /**
-     * @param clsFilter Ignite marshaller class filter to which class 
validation will be delegated.
-     * @throws IgniteCheckedException if autoconfiguration failed.
-     */
-    public static void 
autoconfigureObjectInputFilter(IgniteMarshallerClassFilter clsFilter) throws 
IgniteCheckedException {
-        if 
(!IgniteCommonsSystemProperties.getBoolean(IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION,
 true))
-            return;
-
-        synchronized (MUX) {
-            ObjectInputFilter objFilter = 
ObjectInputFilter.Config.getSerialFilter();
-
-            if (objFilter == null)
-                ObjectInputFilter.Config.setSerialFilter(new 
IgniteObjectInputFilter(clsFilter));
-            else if (objFilter instanceof IgniteObjectInputFilter) {
-                IgniteObjectInputFilter igniteObjFilter = 
(IgniteObjectInputFilter)objFilter;
-
-                if (!Objects.equals(igniteObjFilter.classFilter(), clsFilter)) 
{
-                    throw new IgniteCheckedException("Failed to autoconfigure 
Ignite Object Input Filter for the current JVM" +
-                        " because it was already set by another Ignite 
instance which is running in the same JVM and is" +
-                        " configured with a different Marshaller Black or 
White lists.");
-                }
-            }
-            else {
-                throw new IgniteCheckedException("Failed to autoconfigure 
Ignite Object Input Filter for the current JVM as" +
-                    " it was already set via `jdk.serialFilter` JVM system 
property or programmatically. You can disable" +
-                    " Object Input Stream Filter autoconfiguration by setting 
`IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION`" +
-                    " system property to `false`. Note that in this case you 
must configure Java Serialization" +
-                    " Filtering manually to filter out classes defined by the 
`IGNITE_MARSHALLER_BLACKLIST` system property" +
-                    " [objectInputFilterClass=" + 
objFilter.getClass().getName() + ']');
-            }
-        }
-    }
-
-    /**
-     * @param clsLdr Class loader.
      * @return White list of classes.
      */
-    private static ClassSet classWhiteList(ClassLoader clsLdr) throws 
IgniteCheckedException {
+    private static ClassSet classWhiteList() {
         ClassSet clsSet = null;
 
         String fileName = 
IgniteCommonsSystemProperties.getString(IgniteCommonsSystemProperties.IGNITE_MARSHALLER_WHITELIST);
 
-        if (fileName != null) {
+        if (fileName != null && !fileName.isBlank()) {
             clsSet = new ClassSet();
 
-            addClassNames(JDK_CLS_NAMES_FILE, clsSet, clsLdr);
-            addClassNames(CLS_NAMES_FILE, clsSet, clsLdr);
-            addClassNames(DEFAULT_WHITELIST_CLS_NAMES_FILE, clsSet, clsLdr);
-            addClassNames(fileName, clsSet, clsLdr);
+            addClassNames(JDK_CLS_NAMES_FILE, clsSet, 
CommonUtils.gridClassLoader());
+            addClassNames(CLS_NAMES_FILE, clsSet, 
CommonUtils.gridClassLoader());
+            addClassNames(DEFAULT_WHITELIST_CLS_NAMES_FILE, clsSet, 
CommonUtils.gridClassLoader());
+            addClassNames(fileName, clsSet, CommonUtils.gridClassLoader());
         }
 
         return clsSet;
     }
 
     /**
-     * @param clsLdr Class loader.
      * @return Black list of classes.
      */
-    private static ClassSet classBlackList(ClassLoader clsLdr) throws 
IgniteCheckedException {
+    private static ClassSet classBlackList() {
         ClassSet clsSet = new ClassSet();
 
-        addClassNames(DEFAULT_BLACKLIST_CLS_NAMES_FILE, clsSet, clsLdr);
+        addClassNames(DEFAULT_BLACKLIST_CLS_NAMES_FILE, clsSet, 
CommonUtils.gridClassLoader());
 
         String blackListFileName = 
IgniteCommonsSystemProperties.getString(IGNITE_MARSHALLER_BLACKLIST);
 
-        if (blackListFileName != null)
-            addClassNames(blackListFileName, clsSet, clsLdr);
+        if (blackListFileName != null && !blackListFileName.isBlank())
+            addClassNames(blackListFileName, clsSet, 
CommonUtils.gridClassLoader());
 
         return clsSet;
     }
@@ -155,7 +117,7 @@ public class MarshallerUtils {
         String fileName,
         ClassSet clsSet,
         ClassLoader clsLdr
-    ) throws IgniteCheckedException {
+    ) {
         InputStream is = clsLdr.getResourceAsStream(fileName);
 
         if (is == null) {
@@ -163,7 +125,7 @@ public class MarshallerUtils {
                 is = new FileInputStream(new File(fileName));
             }
             catch (FileNotFoundException e) {
-                throw new IgniteCheckedException("File " + fileName + " not 
found.");
+                throw new IgniteException("File " + fileName + " not found.");
             }
         }
 
@@ -178,14 +140,14 @@ public class MarshallerUtils {
                         clsSet.add(s);
                     }
                     catch (IllegalArgumentException e) {
-                        throw new IgniteCheckedException("Exception occurred 
while reading list of classes" +
+                        throw new IgniteException("Exception occurred while 
reading list of classes" +
                             "[path=" + fileName + ", row=" + i + ", line=" + s 
+ ']', e);
                     }
                 }
             }
         }
         catch (IOException e) {
-            throw new IgniteCheckedException("Exception occurred while reading 
and creating list of classes " +
+            throw new IgniteException("Exception occurred while reading and 
creating list of classes " +
                 "[path=" + fileName + ']', e);
         }
     }
@@ -193,11 +155,10 @@ public class MarshallerUtils {
     /**
      * Find all system class names (for JDK or Ignite classes) and process 
them with a given consumer.
      *
-     * @param ldr Class loader.
      * @param proc Class processor (class name consumer).
      */
-    public static void processSystemClasses(ClassLoader ldr, Consumer<String> 
proc) throws IOException {
-        Enumeration<URL> urls = ldr.getResources(CLS_NAMES_FILE);
+    public static void processSystemClasses(Consumer<String> proc) throws 
IOException {
+        Enumeration<URL> urls = 
CommonUtils.gridClassLoader().getResources(CLS_NAMES_FILE);
 
         boolean foundClsNames = false;
 
@@ -209,13 +170,13 @@ public class MarshallerUtils {
 
         if (!foundClsNames)
             throw new IgniteException("Failed to load class names properties 
file packaged with ignite binaries " +
-                "[file=" + CLS_NAMES_FILE + ", ldr=" + ldr + ']');
+                "[file=" + CLS_NAMES_FILE + ", ldr=" + 
CommonUtils.gridClassLoader() + ']');
 
-        URL jdkClsNames = ldr.getResource(JDK_CLS_NAMES_FILE);
+        URL jdkClsNames = 
CommonUtils.gridClassLoader().getResource(JDK_CLS_NAMES_FILE);
 
         if (jdkClsNames == null)
             throw new IgniteException("Failed to load class names properties 
file packaged with ignite binaries " +
-                "[file=" + JDK_CLS_NAMES_FILE + ", ldr=" + ldr + ']');
+                "[file=" + JDK_CLS_NAMES_FILE + ", ldr=" + 
CommonUtils.gridClassLoader() + ']');
 
         processResource(jdkClsNames, proc);
     }
diff --git 
a/modules/binary/api/src/main/java/org/apache/ignite/marshaller/Marshallers.java
 
b/modules/binary/api/src/main/java/org/apache/ignite/marshaller/Marshallers.java
index 7323669e822..211ac1fa508 100644
--- 
a/modules/binary/api/src/main/java/org/apache/ignite/marshaller/Marshallers.java
+++ 
b/modules/binary/api/src/main/java/org/apache/ignite/marshaller/Marshallers.java
@@ -25,7 +25,6 @@ import org.apache.ignite.IgniteCommonsSystemProperties;
 import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
 import org.apache.ignite.internal.util.CommonUtils;
 import org.apache.ignite.internal.util.typedef.internal.A;
-import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.marshaller.jdk.JdkMarshaller;
 import org.jetbrains.annotations.Nullable;
 
@@ -61,14 +60,6 @@ public class Marshallers {
         return factory.jdk();
     }
 
-    /**
-     * @param clsFilter Class filter.
-     * @return Filtered instance of {@link JdkMarshaller}.
-     */
-    public static JdkMarshaller jdk(@Nullable IgnitePredicate<String> 
clsFilter) {
-        return factory.jdk(clsFilter);
-    }
-
     /** @return Optimized marshaller instance. */
     public static OptimizedMarshaller optimized() {
         return factory.optimized();
diff --git 
a/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallersFactory.java
 
b/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallersFactory.java
index 0c7809213ae..0a8564893ef 100644
--- 
a/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallersFactory.java
+++ 
b/modules/binary/api/src/main/java/org/apache/ignite/marshaller/MarshallersFactory.java
@@ -21,9 +21,7 @@ import java.io.Serializable;
 import java.util.ServiceLoader;
 import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
 import org.apache.ignite.internal.util.CommonUtils;
-import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.marshaller.jdk.JdkMarshaller;
-import org.jetbrains.annotations.Nullable;
 
 /**
  * Marshallers factory.
@@ -36,12 +34,6 @@ public interface MarshallersFactory {
     /** @return Default instance of {@link JdkMarshaller}. */
     public JdkMarshaller jdk();
 
-    /**
-     * @param clsFilter Class filter.
-     * @return Filtered instance of {@link JdkMarshaller}.
-     */
-    public JdkMarshaller jdk(@Nullable IgnitePredicate<String> clsFilter);
-
     /** @return Optimized marshaller instance. */
     public OptimizedMarshaller optimized();
 
diff --git 
a/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
 
b/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
index 08e0a367217..6b6f2a57515 100644
--- 
a/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
+++ 
b/modules/binary/impl/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
@@ -47,6 +47,7 @@ import org.apache.ignite.internal.util.GridUnsafe;
 import org.apache.ignite.internal.util.io.GridDataInput;
 import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.marshaller.MarshallerContext;
+import org.apache.ignite.marshaller.MarshallerUtils;
 import org.apache.ignite.marshaller.Marshallers;
 
 import static 
org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.ARRAY_LIST;
@@ -347,7 +348,7 @@ class OptimizedObjectInputStream extends ObjectInputStream {
                 OptimizedClassDescriptor desc = typeId == 0
                     ? classDescriptor(
                         clsMap,
-                        CommonUtils.forName(readUTF(), clsLdr, 
ctx.classNameFilter(), useCache),
+                        CommonUtils.forName(readUTF(), clsLdr, 
MarshallerUtils.classNameFilter(), useCache),
                         useCache,
                         ctx,
                         mapper)
@@ -545,7 +546,7 @@ class OptimizedObjectInputStream extends ObjectInputStream {
         // Must have 'Class.forName()' instead of clsLoader.loadClass()
         // due to weird ClassNotFoundExceptions for arrays of classes
         // in certain cases.
-        return CommonUtils.forName(desc.getName(), clsLdr, 
ctx.classNameFilter(), Marshallers.USE_CACHE.get());
+        return CommonUtils.forName(desc.getName(), clsLdr, 
MarshallerUtils.classNameFilter(), Marshallers.USE_CACHE.get());
     }
 
     /**
diff --git 
a/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/MarshallersFactoryImpl.java
 
b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/MarshallersFactoryImpl.java
index e75f8cab375..f44d85134ec 100644
--- 
a/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/MarshallersFactoryImpl.java
+++ 
b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/MarshallersFactoryImpl.java
@@ -19,26 +19,16 @@ package org.apache.ignite.marshaller;
 
 import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
 import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerImpl;
-import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.marshaller.jdk.JdkMarshaller;
 import org.apache.ignite.marshaller.jdk.JdkMarshallerImpl;
-import org.jetbrains.annotations.Nullable;
 
 /**
  * Marshallers factory implementation.
  */
 public class MarshallersFactoryImpl implements MarshallersFactory {
-    /** Singleton instance. */
-    private static final JdkMarshaller INSTANCE = new JdkMarshallerImpl();
-
     /** {@inheritDoc} */
     @Override public JdkMarshaller jdk() {
-        return INSTANCE;
-    }
-
-    /** {@inheritDoc} */
-    @Override public JdkMarshaller jdk(@Nullable IgnitePredicate<String> 
clsFilter) {
-        return clsFilter == null ? INSTANCE : new JdkMarshallerImpl(clsFilter);
+        return new JdkMarshallerImpl();
     }
 
     /** {@inheritDoc} */
diff --git 
a/modules/binary/api/src/main/java/org/apache/ignite/marshaller/IgniteObjectInputFilter.java
 
b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/IgniteObjectInputFilter.java
similarity index 72%
rename from 
modules/binary/api/src/main/java/org/apache/ignite/marshaller/IgniteObjectInputFilter.java
rename to 
modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/IgniteObjectInputFilter.java
index 583462d45fd..b3125666f33 100644
--- 
a/modules/binary/api/src/main/java/org/apache/ignite/marshaller/IgniteObjectInputFilter.java
+++ 
b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/IgniteObjectInputFilter.java
@@ -15,19 +15,16 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.marshaller;
+package org.apache.ignite.marshaller.jdk;
 
 import java.io.ObjectInputFilter;
+import org.apache.ignite.marshaller.IgniteMarshallerClassFilter;
+import org.apache.ignite.marshaller.MarshallerUtils;
 
 /** */
 public class IgniteObjectInputFilter implements ObjectInputFilter {
     /** */
-    private final IgniteMarshallerClassFilter clsFilter;
-
-    /** @param clsFilter Ignite marshaller class filter to which class 
validation will be delegated. */
-    public IgniteObjectInputFilter(IgniteMarshallerClassFilter clsFilter) {
-        this.clsFilter = clsFilter;
-    }
+    private final IgniteMarshallerClassFilter clsFilter = 
MarshallerUtils.classNameFilter();
 
     /** {@inheritDoc} */
     @Override public Status checkInput(FilterInfo filterInfo) {
@@ -38,9 +35,4 @@ public class IgniteObjectInputFilter implements 
ObjectInputFilter {
 
         return clsFilter.apply(cls.getName()) ? Status.ALLOWED : 
Status.REJECTED;
     }
-
-    /** @return Ignite marshaller class filter. */
-    public IgniteMarshallerClassFilter classFilter() {
-        return clsFilter;
-    }
 }
diff --git 
a/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerImpl.java
 
b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerImpl.java
index a7630a170e9..e2f6d37bb9a 100644
--- 
a/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerImpl.java
+++ 
b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerImpl.java
@@ -18,17 +18,21 @@
 package org.apache.ignite.marshaller.jdk;
 
 import java.io.InputStream;
+import java.io.ObjectInputFilter;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.OutputStream;
 import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteCommonsSystemProperties;
+import org.apache.ignite.IgniteException;
 import org.apache.ignite.internal.util.io.GridByteArrayInputStream;
 import org.apache.ignite.internal.util.io.GridByteArrayOutputStream;
 import org.apache.ignite.internal.util.typedef.internal.S;
-import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.marshaller.AbstractNodeNameAwareMarshaller;
 import org.jetbrains.annotations.Nullable;
 
+import static 
org.apache.ignite.IgniteCommonsSystemProperties.IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION;
+
 /**
  * Implementation of {@link org.apache.ignite.marshaller.Marshaller} based on 
JDK serialization mechanism.
  * <p>
@@ -66,23 +70,21 @@ import org.jetbrains.annotations.Nullable;
  * For information about Spring framework visit <a 
href="http://www.springframework.org/";>www.springframework.org</a>
  */
 public class JdkMarshallerImpl extends AbstractNodeNameAwareMarshaller 
implements JdkMarshaller {
-    /** Class name filter. */
-    private final IgnitePredicate<String> clsFilter;
-
-    /**
-     * Default constructor.
-     * Use this constructor with caution. It creates a JdkMarshaller instance 
that has class filtering DISABLED. Therefore,
-     * if it will be used on the server side to unmarshal user data received 
from the network, it may lead to security breaches.
-     */
-    public JdkMarshallerImpl() {
-        this(null);
-    }
-
-    /**
-     * @param clsFilter Class name filter.
-     */
-    public JdkMarshallerImpl(@Nullable IgnitePredicate<String> clsFilter) {
-        this.clsFilter = clsFilter;
+    static {
+        if 
(IgniteCommonsSystemProperties.getBoolean(IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION,
 true)) {
+            ObjectInputFilter objFilter = 
ObjectInputFilter.Config.getSerialFilter();
+
+            if (objFilter == null)
+                ObjectInputFilter.Config.setSerialFilter(new 
IgniteObjectInputFilter());
+            else if (!(objFilter instanceof IgniteObjectInputFilter)) {
+                throw new IgniteException("Failed to autoconfigure Ignite 
Object Input Filter for the current JVM as" +
+                    " it was already set via `jdk.serialFilter` JVM system 
property or programmatically. You can disable" +
+                    " Object Input Stream Filter autoconfiguration by setting 
`IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION`" +
+                    " system property to `false`. Note that in this case you 
must configure Java Serialization" +
+                    " Filtering manually to filter out classes defined by the 
`IGNITE_MARSHALLER_BLACKLIST` system property" +
+                    " [objectInputFilterClass=" + 
objFilter.getClass().getName() + ']');
+            }
+        }
     }
 
     /** {@inheritDoc} */
@@ -117,8 +119,7 @@ public class JdkMarshallerImpl extends 
AbstractNodeNameAwareMarshaller implement
         if (clsLdr == null)
             clsLdr = getClass().getClassLoader();
 
-        try (ObjectInputStream objIn = new JdkMarshallerObjectInputStream(
-            new JdkMarshallerInputStreamWrapper(in), clsLdr, clsFilter)) {
+        try (ObjectInputStream objIn = new JdkMarshallerObjectInputStream(new 
JdkMarshallerInputStreamWrapper(in), clsLdr)) {
             return (T)objIn.readObject();
         }
         catch (ClassNotFoundException e) {
diff --git 
a/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
 
b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
index 61ff5f59a6c..f1480fe0a10 100644
--- 
a/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
+++ 
b/modules/binary/impl/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
@@ -22,9 +22,8 @@ import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectStreamClass;
 import org.apache.ignite.internal.util.CommonUtils;
-import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.marshaller.MarshallerUtils;
 import org.apache.ignite.marshaller.Marshallers;
-import org.jetbrains.annotations.Nullable;
 
 /**
  * This class defines custom JDK object input stream.
@@ -33,22 +32,17 @@ class JdkMarshallerObjectInputStream extends 
ObjectInputStream {
     /** */
     private final ClassLoader clsLdr;
 
-    /** Class name filter. */
-    private final IgnitePredicate<String> clsFilter;
-
     /**
      * @param in Parent input stream.
      * @param clsLdr Custom class loader.
-     * @param clsFilter Class filter lambda.
      * @throws IOException If initialization failed.
      */
-    JdkMarshallerObjectInputStream(InputStream in, ClassLoader clsLdr, 
@Nullable IgnitePredicate<String> clsFilter) throws IOException {
+    JdkMarshallerObjectInputStream(InputStream in, ClassLoader clsLdr) throws 
IOException {
         super(in);
 
         assert clsLdr != null;
 
         this.clsLdr = clsLdr;
-        this.clsFilter = clsFilter;
 
         enableResolveObject(true);
     }
@@ -59,7 +53,7 @@ class JdkMarshallerObjectInputStream extends 
ObjectInputStream {
         // Must have 'Class.forName()' instead of clsLoader.loadClass()
         // due to weird ClassNotFoundExceptions for arrays of classes
         // in certain cases.
-        return CommonUtils.forName(desc.getName(), clsLdr, clsFilter, 
Marshallers.USE_CACHE.get());
+        return CommonUtils.forName(desc.getName(), clsLdr, 
MarshallerUtils.classNameFilter(), Marshallers.USE_CACHE.get());
     }
 
     /** {@inheritDoc} */
diff --git a/modules/clients/pom.xml b/modules/clients/pom.xml
index e299873bba9..578c898d9c3 100644
--- a/modules/clients/pom.xml
+++ b/modules/clients/pom.xml
@@ -138,6 +138,13 @@
             <artifactId>guava</artifactId>
             <scope>test</scope>
         </dependency>
+
+        <dependency>
+            <groupId>com.thoughtworks.xstream</groupId>
+            <artifactId>xstream</artifactId>
+            <version>${xstream.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
index 6fa841ef06c..dfa0cdc1a4f 100644
--- 
a/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
@@ -38,6 +38,7 @@ import 
org.apache.ignite.internal.processors.rest.JettyRestProcessorAuthenticato
 import 
org.apache.ignite.internal.processors.rest.JettyRestProcessorBaselineSelfTest;
 import 
org.apache.ignite.internal.processors.rest.JettyRestProcessorBeforeNodeStartSelfTest;
 import 
org.apache.ignite.internal.processors.rest.JettyRestProcessorCacheNodeFilterTest;
+import 
org.apache.ignite.internal.processors.rest.JettyRestProcessorClassFilterTest;
 import 
org.apache.ignite.internal.processors.rest.JettyRestProcessorGetAllAsArrayTest;
 import 
org.apache.ignite.internal.processors.rest.JettyRestProcessorSignedSelfTest;
 import 
org.apache.ignite.internal.processors.rest.JettyRestProcessorUnsignedSelfTest;
@@ -70,7 +71,12 @@ import org.junit.runners.Suite;
 
     // Test custom binary protocol with test client.
     RestBinaryProtocolSelfTest.class,
-    TcpRestUnmarshalVulnerabilityTest.class,
+    TcpRestUnmarshalVulnerabilityTest.NoListTest.class,
+    TcpRestUnmarshalVulnerabilityTest.WhiteListIncludedTest.class,
+    TcpRestUnmarshalVulnerabilityTest.WhiteListExcludedTest.class,
+    TcpRestUnmarshalVulnerabilityTest.BlackListIncludedTest.class,
+    TcpRestUnmarshalVulnerabilityTest.BlackListExcludedTest.class,
+    TcpRestUnmarshalVulnerabilityTest.BothListIncludedTest.class,
 
     // Test jetty rest processor
     JettyRestProcessorSignedSelfTest.class,
@@ -82,6 +88,7 @@ import org.junit.runners.Suite;
     JettyRestProcessorBaselineSelfTest.class,
     JettyRestProcessorBeforeNodeStartSelfTest.class,
     JettyRestProcessorCacheNodeFilterTest.class,
+    JettyRestProcessorClassFilterTest.class,
 
     // Test TCP rest processor with original memcache client.
     ClientMemcachedProtocolSelfTest.class,
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
index 967ab1141ad..f32cc698e69 100644
--- 
a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
@@ -77,13 +77,10 @@ import org.apache.ignite.lang.IgniteBiPredicate;
 import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.testframework.GridTestUtils;
-import org.apache.ignite.testframework.junits.WithSystemProperty;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
-import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION;
-import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_BLACKLIST;
 import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_USE_BINARY_ARRAYS;
 import static org.apache.ignite.cache.CacheMode.PARTITIONED;
 import static org.apache.ignite.cache.CacheMode.REPLICATED;
@@ -110,7 +107,6 @@ import static 
org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS
  */
 @SuppressWarnings("unchecked")
 @RunWith(Parameterized.class)
-@WithSystemProperty(key = IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION, 
value = "false")
 public abstract class JettyRestProcessorAbstractSelfTest extends 
JettyRestProcessorCommonSelfTest {
     /** */
     private static boolean memoryMetricsEnabled;
@@ -133,8 +129,6 @@ public abstract class JettyRestProcessorAbstractSelfTest 
extends JettyRestProces
 
     /** {@inheritDoc} */
     @Override protected void beforeTestsStarted() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
-        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
         System.setProperty(IGNITE_USE_BINARY_ARRAYS, 
Boolean.toString(useBinaryArrays));
 
         thirdPartyStore = new ConcurrentHashMap<>();
@@ -146,7 +140,6 @@ public abstract class JettyRestProcessorAbstractSelfTest 
extends JettyRestProces
 
     /** {@inheritDoc} */
     @Override protected void afterTestsStopped() throws Exception {
-        System.clearProperty(IGNITE_MARSHALLER_BLACKLIST);
         System.clearProperty(IGNITE_USE_BINARY_ARRAYS);
 
         super.afterTestsStopped();
@@ -181,7 +174,7 @@ public abstract class JettyRestProcessorAbstractSelfTest 
extends JettyRestProces
      * @param content Content to check.
      * @param err Error message.
      */
-    protected void assertResponseContainsError(String content, String err) 
throws IOException {
+    static void assertResponseContainsError(String content, String err) throws 
IOException {
         assertFalse(F.isEmpty(content));
         assertNotNull(err);
 
@@ -701,23 +694,6 @@ public abstract class JettyRestProcessorAbstractSelfTest 
extends JettyRestProces
         );
 
         assertResponseContainsError(ret, "Failed to convert value to specified 
type");
-
-        // Check forbidden type.
-        ForbiddenType forbidden = new ForbiddenType(new Exploit[] {
-            new Exploit(1),
-            new Exploit(2)
-        });
-
-        json = JSON_MAPPER.writeValueAsString(forbidden);
-
-        ret = content(DEFAULT_CACHE_NAME, GridRestCommand.CACHE_PUT,
-            "keyType", "int",
-            "key", "5",
-            "valueType", ForbiddenType.class.getName(),
-            "val", json
-        );
-
-        assertResponseContainsError(ret, "Deserialization of class " + 
Exploit.class.getName() + " is disallowed.");
     }
 
     /**
@@ -3140,44 +3116,6 @@ public abstract class JettyRestProcessorAbstractSelfTest 
extends JettyRestProces
         }
     }
 
-    /** */
-    private static class ForbiddenType {
-        /** Data. */
-        @JsonProperty
-        private Exploit[] data;
-
-        /** */
-        ForbiddenType() {
-            // No-op.
-        }
-
-        /**
-         * @param data Data.
-         */
-        ForbiddenType(Exploit[] data) {
-            this.data = data;
-        }
-    }
-
-    /** */
-    private static class Exploit {
-        /** Value. */
-        @JsonProperty
-        private int val = 10;
-
-        /**
-         * @param val Value
-         */
-        Exploit(int val) {
-            this.val = val;
-        }
-
-        /** */
-        Exploit() {
-            // No-op.
-        }
-    }
-
     /** */
     @JsonInclude(JsonInclude.Include.NON_NULL)
     private static class OuterClass {
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorClassFilterTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorClassFilterTest.java
new file mode 100644
index 00000000000..6e57ac19568
--- /dev/null
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorClassFilterTest.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ignite.internal.processors.rest;
+
+import java.util.Arrays;
+import java.util.List;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.junit.Test;
+
+import static 
org.apache.ignite.IgniteCommonsSystemProperties.IGNITE_MARSHALLER_BLACKLIST;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_JETTY_PORT;
+import static 
org.apache.ignite.internal.processors.rest.JettyRestProcessorAbstractSelfTest.assertResponseContainsError;
+
+/** */
+public class JettyRestProcessorClassFilterTest extends 
JettyRestProcessorCommonSelfTest {
+    /** */
+    public static final int RMT_PORT = 8089;
+
+    /** {@inheritDoc} */
+    @Override protected int gridCount() {
+        return 2;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected List<String> additionalRemoteJvmArgs() {
+        return Arrays.asList("-D" + IGNITE_MARSHALLER_BLACKLIST +
+            "=" + 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath(),
+            "-D" + IGNITE_JETTY_PORT + "=" + RMT_PORT);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected String restUrl() {
+        return "http://"; + LOC_HOST + ":" + RMT_PORT + "/ignite?";
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testPutIncorrectJson() throws Exception {
+        // Check forbidden type.
+        ForbiddenType forbidden = new ForbiddenType(new Exploit[] {
+            new Exploit(1),
+            new Exploit(2)
+        });
+
+        String json = JSON_MAPPER.writeValueAsString(forbidden);
+
+        String ret = content(DEFAULT_CACHE_NAME, GridRestCommand.CACHE_PUT,
+            "keyType", "int",
+            "key", "5",
+            "valueType", ForbiddenType.class.getName(),
+            "val", json
+        );
+
+        assertResponseContainsError(ret, "Deserialization of class " + 
Exploit.class.getName() + " is disallowed.");
+    }
+
+    /** {@inheritDoc} */
+    @Override protected boolean isMultiJvm() {
+        return true;
+    }
+
+    /** */
+    private static class ForbiddenType {
+        /** Data. */
+        @JsonProperty
+        private Exploit[] data;
+
+        /** */
+        ForbiddenType() {
+            // No-op.
+        }
+
+        /**
+         * @param data Data.
+         */
+        ForbiddenType(Exploit[] data) {
+            this.data = data;
+        }
+    }
+
+    /** */
+    private static class Exploit {
+        /** Value. */
+        @JsonProperty
+        private int val = 10;
+
+        /**
+         * @param val Value
+         */
+        Exploit(int val) {
+            this.val = val;
+        }
+
+        /** */
+        Exploit() {
+            // No-op.
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override protected String signature() {
+        return null;
+    }
+}
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/TcpRestUnmarshalVulnerabilityTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/TcpRestUnmarshalVulnerabilityTest.java
index 3a279ac94cb..23190a0b1f4 100644
--- 
a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/TcpRestUnmarshalVulnerabilityTest.java
+++ 
b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/TcpRestUnmarshalVulnerabilityTest.java
@@ -25,23 +25,22 @@ import java.io.ObjectInputStream;
 import java.io.OutputStream;
 import java.net.InetAddress;
 import java.net.Socket;
-import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
 import java.util.UUID;
-import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.ignite.Ignition;
 import org.apache.ignite.configuration.ConnectorConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
 import 
org.apache.ignite.internal.client.marshaller.jdk.GridClientJdkMarshaller;
 import 
org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest;
 import 
org.apache.ignite.internal.processors.rest.client.message.GridClientMessage;
-import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.internal.util.lang.GridAbsPredicate;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.testframework.GridTestUtils;
-import org.apache.ignite.testframework.junits.WithSystemProperty;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.junit.Test;
 
-import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION;
 import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_BLACKLIST;
 import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_WHITELIST;
 import static 
org.apache.ignite.internal.processors.rest.protocols.tcp.GridMemcachedMessage.IGNITE_HANDSHAKE_FLAG;
@@ -50,13 +49,9 @@ import static 
org.apache.ignite.internal.processors.rest.protocols.tcp.GridMemca
 /**
  * Tests for whitelist and blacklist ot avoiding deserialization vulnerability.
  */
-@WithSystemProperty(key = IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION, 
value = "false")
-public class TcpRestUnmarshalVulnerabilityTest extends GridCommonAbstractTest {
-    /** Marshaller. */
-    private static final GridClientJdkMarshaller MARSH = new 
GridClientJdkMarshaller();
-
-    /** Shared value. */
-    private static final AtomicBoolean SHARED = new AtomicBoolean();
+public abstract class TcpRestUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest {
+    /** */
+    static final String EXPLOIT_CACHE = "exploit-cache";
 
     /** Port. */
     private static int port;
@@ -68,109 +63,130 @@ public class TcpRestUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest {
     @Override protected IgniteConfiguration getConfiguration(String 
igniteInstanceName) throws Exception {
         IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
 
-        ConnectorConfiguration connCfg = new ConnectorConfiguration();
+        // First instance local, other remote.
+        // Want to connect to remote in tests.
+        if (!igniteInstanceName.equals(getTestIgniteInstanceName(0))) {
+            ConnectorConfiguration connCfg = new ConnectorConfiguration();
 
-        port = connCfg.getPort();
-        host = connCfg.getHost();
+            port = connCfg.getPort();
+            host = connCfg.getHost();
 
-        cfg.setConnectorConfiguration(connCfg);
+            cfg.setConnectorConfiguration(connCfg);
+        }
 
         return cfg;
     }
 
-    /** {@inheritDoc} */
-    @Override protected void beforeTest() throws Exception {
-        super.beforeTest();
-
-        SHARED.set(false);
-
-        System.clearProperty(IGNITE_MARSHALLER_WHITELIST);
-        System.clearProperty(IGNITE_MARSHALLER_BLACKLIST);
-
-        IgniteUtils.clearClassCache();
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testNoLists() throws Exception {
-        testExploit(true);
+    /** */
+    public static class NoListTest extends TcpRestUnmarshalVulnerabilityTest {
+        /** */
+        @Test
+        public void test() throws Exception {
+            testExploit(true);
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testWhiteListIncluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
+    /** */
+    public static class WhiteListIncludedTest extends 
TcpRestUnmarshalVulnerabilityTest {
+        /** */
+        @Test
+        public void test() throws Exception {
+            testExploit(true);
+        }
 
-        testExploit(true);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            return Arrays.asList(
+                "-D" + IGNITE_MARSHALLER_WHITELIST + "=" +
+                    
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath()
+            );
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testWhiteListExcluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
+    /** */
+    public static class WhiteListExcludedTest extends 
TcpRestUnmarshalVulnerabilityTest {
+        /** */
+        @Test
+        public void test() throws Exception {
+            testExploit(false);
+        }
 
-        testExploit(false);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            return Arrays.asList(
+                "-D" + IGNITE_MARSHALLER_WHITELIST + "=" +
+                    
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt").getPath()
+            );
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testBlackListIncluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+    /** */
+    public static class BlackListIncludedTest extends 
TcpRestUnmarshalVulnerabilityTest {
+        /** */
+        @Test
+        public void test() throws Exception {
+            testExploit(false);
+        }
 
-        testExploit(false);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            return Arrays.asList(
+                "-D" + IGNITE_MARSHALLER_BLACKLIST + "=" +
+                    
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath()
+            );
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testBlackListExcluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+    /** */
+    public static class BlackListExcludedTest extends 
TcpRestUnmarshalVulnerabilityTest {
+        /** */
+        @Test
+        public void test() throws Exception {
+            testExploit(true);
+        }
 
-        testExploit(true);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            return Arrays.asList(
+                "-D" + IGNITE_MARSHALLER_BLACKLIST + "=" +
+                    
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt").getPath()
+            );
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testBothListIncluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
+    /** */
+    public static class BothListIncludedTest extends 
TcpRestUnmarshalVulnerabilityTest {
+        /** */
+        @Test
+        public void test() throws Exception {
+            testExploit(false);
+        }
 
-        System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
-        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
 
-        testExploit(false);
+            return Arrays.asList(
+                "-D" + IGNITE_MARSHALLER_BLACKLIST + "=" + path,
+                "-D" + IGNITE_MARSHALLER_WHITELIST + "=" + path
+            );
+        }
     }
 
     /**
      * @param positive Positive.
      */
-    private void testExploit(boolean positive) throws Exception {
+    void testExploit(boolean positive) throws Exception {
         try {
-            startGrid();
+            IgniteEx loc = startGrid(0);
+
+            startGrid(1);
 
-            attack(marshal(new Exploit()).array());
+            attack(new GridClientJdkMarshaller().marshal(new Exploit(), 
0).array());
 
             boolean res = GridTestUtils.waitForCondition(new 
GridAbsPredicate() {
                 @Override public boolean apply() {
-                    return SHARED.get();
+                    return loc.cacheNames().contains(EXPLOIT_CACHE);
                 }
             }, 3000L);
 
@@ -184,13 +200,6 @@ public class TcpRestUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest {
         }
     }
 
-    /**
-     * @param obj Object.
-     */
-    private static ByteBuffer marshal(Object obj) throws IOException {
-        return MARSH.marshal(obj, 0);
-    }
-
     /**
      * @param data Data.
      */
@@ -233,7 +242,7 @@ public class TcpRestUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest {
          * @param is Input stream.
          */
         private void readObject(ObjectInputStream is) throws 
ClassNotFoundException, IOException {
-            SHARED.set(true);
+            Ignition.localIgnite().createCache(EXPLOIT_CACHE);
         }
 
         /** {@inheritDoc} */
@@ -276,4 +285,9 @@ public class TcpRestUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest {
             // No-op.
         }
     }
+
+    /** {@inheritDoc} */
+    @Override protected boolean isMultiJvm() {
+        return true;
+    }
 }
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java
index 086afcafeab..358d4317968 100644
--- 
a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java
+++ 
b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java
@@ -48,7 +48,6 @@ import 
org.apache.ignite.internal.jdbc.thin.JdbcThinConnection;
 import org.apache.ignite.internal.jdbc.thin.JdbcThinTcpIo;
 import org.apache.ignite.internal.util.lang.RunnableX;
 import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.marshaller.MarshallerContext;
 import org.apache.ignite.marshaller.jdk.JdkMarshaller;
 import org.apache.ignite.testframework.GridStringLogger;
@@ -2240,10 +2239,6 @@ public class JdbcThinConnectionSelfTest extends 
JdbcThinAbstractSelfTest {
                 return false;
             }
 
-            @Override public IgnitePredicate<String> classNameFilter() {
-                return null;
-            }
-
             @Override public JdkMarshaller jdkMarshaller() {
                 return null;
             }
diff --git 
a/modules/clients/src/test/java/org/apache/ignite/loadtests/client/ClientMarshallerBenchmarkTest.java
 
b/modules/clients/src/test/java/org/apache/ignite/loadtests/client/ClientMarshallerBenchmarkTest.java
index 632d93bf70e..8d28514b338 100644
--- 
a/modules/clients/src/test/java/org/apache/ignite/loadtests/client/ClientMarshallerBenchmarkTest.java
+++ 
b/modules/clients/src/test/java/org/apache/ignite/loadtests/client/ClientMarshallerBenchmarkTest.java
@@ -22,14 +22,11 @@ import java.nio.ByteBuffer;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
-import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.IgniteException;
 import org.apache.ignite.internal.client.marshaller.GridClientMarshaller;
 import 
org.apache.ignite.internal.client.marshaller.jdk.GridClientJdkMarshaller;
 import 
org.apache.ignite.internal.client.marshaller.optimized.GridClientOptimizedMarshaller;
 import 
org.apache.ignite.internal.processors.rest.client.message.GridClientCacheRequest;
 import org.apache.ignite.internal.util.typedef.X;
-import org.apache.ignite.marshaller.MarshallerUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -48,15 +45,10 @@ public class ClientMarshallerBenchmarkTest extends 
GridCommonAbstractTest {
     /**
      */
     public ClientMarshallerBenchmarkTest() {
-        try {
-            marshallers = new GridClientMarshaller[] {
-                new 
GridClientJdkMarshaller(MarshallerUtils.classNameFilter(this.getClass().getClassLoader())),
-                new GridClientOptimizedMarshaller()
-            };
-        }
-        catch (IgniteCheckedException e) {
-            throw new IgniteException(e);
-        }
+        marshallers = new GridClientMarshaller[]{
+            new GridClientJdkMarshaller(),
+            new GridClientOptimizedMarshaller()
+        };
     }
 
     /**
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
index f0616aaf5eb..8981207abf2 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
@@ -109,7 +109,6 @@ import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.internal.worker.WorkersRegistry;
-import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.maintenance.MaintenanceRegistry;
 import org.apache.ignite.plugin.PluginNotFoundException;
 import org.apache.ignite.plugin.PluginProvider;
@@ -427,7 +426,6 @@ public class GridKernalContextImpl implements 
GridKernalContext, Externalizable
         IgniteConfiguration cfg,
         GridKernalGateway gw,
         List<PluginProvider> plugins,
-        IgnitePredicate<String> clsFilter,
         WorkersRegistry workerRegistry,
         Thread.UncaughtExceptionHandler hnd,
         LongJVMPauseDetector pauseDetector
@@ -443,7 +441,7 @@ public class GridKernalContextImpl implements 
GridKernalContext, Externalizable
         this.hnd = hnd;
         this.pauseDetector = pauseDetector;
 
-        marshCtx = new MarshallerContextImpl(plugins, clsFilter);
+        marshCtx = new MarshallerContextImpl(plugins);
 
         defragMgr = new IgniteDefragmentationImpl(this);
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java 
b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index cdfeb8c455b..1330973d8c1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -201,10 +201,8 @@ import org.apache.ignite.lang.IgniteProductVersion;
 import org.apache.ignite.lifecycle.LifecycleAware;
 import org.apache.ignite.lifecycle.LifecycleBean;
 import org.apache.ignite.lifecycle.LifecycleEventType;
-import org.apache.ignite.marshaller.IgniteMarshallerClassFilter;
 import org.apache.ignite.marshaller.Marshaller;
 import org.apache.ignite.marshaller.MarshallerExclusions;
-import org.apache.ignite.marshaller.MarshallerUtils;
 import org.apache.ignite.marshaller.Marshallers;
 import org.apache.ignite.metric.IgniteMetrics;
 import org.apache.ignite.metric.MetricRegistry;
@@ -917,10 +915,6 @@ public class IgniteKernal implements IgniteEx, 
Externalizable {
 
         List<PluginProvider> plugins = U.allPluginProviders(cfg, true);
 
-        IgniteMarshallerClassFilter clsFilter = 
MarshallerUtils.classNameFilter(getClass().getClassLoader());
-
-        MarshallerUtils.autoconfigureObjectInputFilter(clsFilter);
-
         // Spin out SPIs & managers.
         try {
             ctx = new GridKernalContextImpl(log,
@@ -928,7 +922,6 @@ public class IgniteKernal implements IgniteEx, 
Externalizable {
                 cfg,
                 gw,
                 plugins,
-                clsFilter,
                 workerRegistry,
                 hnd,
                 longJVMPauseDetector
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java
index 2521be22a8e..0adf9f3c4a7 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java
@@ -59,7 +59,6 @@ import 
org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.marshaller.Marshaller;
 import org.apache.ignite.marshaller.MarshallerContext;
 import org.apache.ignite.marshaller.MarshallerExclusions;
@@ -101,11 +100,8 @@ public class MarshallerContextImpl implements 
MarshallerContext {
     /** */
     private boolean clientNode;
 
-    /** Class name filter. */
-    private final IgnitePredicate<String> clsFilter;
-
     /** JDK marshaller. */
-    private final JdkMarshaller jdkMarsh;
+    private final JdkMarshaller jdkMarsh = Marshallers.jdk();
 
     /**
      * Marshaller mapping file store directory. {@code null} used for standard 
folder, in this case folder is calculated
@@ -118,17 +114,12 @@ public class MarshallerContextImpl implements 
MarshallerContext {
      *
      * @param plugins Plugins.
      */
-    public MarshallerContextImpl(@Nullable Collection<PluginProvider> plugins, 
IgnitePredicate<String> clsFilter) {
-        this.clsFilter = clsFilter;
-        this.jdkMarsh = Marshallers.jdk(clsFilter);
-
+    public MarshallerContextImpl(@Nullable Collection<PluginProvider> plugins) 
{
         initializeCaches();
         initializeMarshallerExclusions();
 
         try {
-            ClassLoader ldr = U.gridClassLoader();
-
-            processSystemClasses(ldr, plugins, clsName -> {
+            processSystemClasses(plugins, clsName -> {
                 int typeId = clsName.hashCode();
 
                 MappedName oldClsName;
@@ -147,8 +138,8 @@ public class MarshallerContextImpl implements 
MarshallerContext {
                 sysTypesSet.add(clsName);
             });
 
-            checkHasClassName(GridDhtPartitionFullMap.class.getName(), ldr, 
CLS_NAMES_FILE);
-            checkHasClassName(HashMap.class.getName(), ldr, 
JDK_CLS_NAMES_FILE);
+            checkHasClassName(GridDhtPartitionFullMap.class.getName(), 
U.gridClassLoader(), CLS_NAMES_FILE);
+            checkHasClassName(HashMap.class.getName(), U.gridClassLoader(), 
JDK_CLS_NAMES_FILE);
         }
         catch (IOException e) {
             throw new IllegalStateException("Failed to initialize marshaller 
context.", e);
@@ -436,7 +427,7 @@ public class MarshallerContextImpl implements 
MarshallerContext {
         if (clsName == null)
             throw new ClassNotFoundException("Unknown type ID: " + typeId);
 
-        return U.forName(clsName, ldr, clsFilter);
+        return U.forName(clsName, ldr, MarshallerUtils.classNameFilter());
     }
 
     /** {@inheritDoc} */
@@ -531,11 +522,6 @@ public class MarshallerContextImpl implements 
MarshallerContext {
         return clsName;
     }
 
-    /** {@inheritDoc} */
-    @Override public IgnitePredicate<String> classNameFilter() {
-        return clsFilter;
-    }
-
     /** {@inheritDoc} */
     @Override public JdkMarshaller jdkMarshaller() {
         return jdkMarsh;
@@ -715,18 +701,16 @@ public class MarshallerContextImpl implements 
MarshallerContext {
     /**
      * Finds all system class names (JDK, Ignite and plugin classes) and 
processes them with the given consumer.
      *
-     * @param ldr Class loader.
      * @param plugins Plugins (may be {@code null}).
      * @param proc Class processor (class name consumer).
      * @throws IOException In case of error.
      */
-    private static void processSystemClasses(ClassLoader ldr, @Nullable 
Collection<PluginProvider> plugins,
-                                             Consumer<String> proc) throws 
IOException {
-        MarshallerUtils.processSystemClasses(ldr, proc);
+    private static void processSystemClasses(@Nullable 
Collection<PluginProvider> plugins, Consumer<String> proc) throws IOException {
+        MarshallerUtils.processSystemClasses(proc);
 
         if (plugins != null && !plugins.isEmpty()) {
             for (PluginProvider plugin : plugins) {
-                Enumeration<URL> pluginUrls = ldr.getResources("META-INF/" + 
plugin.name().toLowerCase()
+                Enumeration<URL> pluginUrls = 
U.gridClassLoader().getResources("META-INF/" + plugin.name().toLowerCase()
                     + ".classnames.properties");
 
                 while (pluginUrls.hasMoreElements())
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/jdk/GridClientJdkMarshaller.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/jdk/GridClientJdkMarshaller.java
index cda742d961a..529d251a875 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/jdk/GridClientJdkMarshaller.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/jdk/GridClientJdkMarshaller.java
@@ -28,7 +28,7 @@ import java.io.ObjectStreamClass;
 import java.nio.ByteBuffer;
 import org.apache.ignite.internal.client.marshaller.GridClientMarshaller;
 import org.apache.ignite.internal.util.io.GridByteArrayOutputStream;
-import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.marshaller.MarshallerUtils;
 
 /**
  * Simple marshaller that utilize JDK serialization features.
@@ -37,23 +37,6 @@ public class GridClientJdkMarshaller implements 
GridClientMarshaller {
     /** ID. */
     public static final byte ID = 2;
 
-    /** Class name filter. */
-    private final IgnitePredicate<String> clsFilter;
-
-    /**
-     * Default constructor.
-     */
-    public GridClientJdkMarshaller() {
-        this(null);
-    }
-
-    /**
-     * @param clsFilter Class filter.
-     */
-    public GridClientJdkMarshaller(IgnitePredicate<String> clsFilter) {
-        this.clsFilter = clsFilter;
-    }
-
     /** {@inheritDoc} */
     @Override public ByteBuffer marshal(Object obj, int off) throws 
IOException {
         GridByteArrayOutputStream bOut = new GridByteArrayOutputStream();
@@ -79,7 +62,7 @@ public class GridClientJdkMarshaller implements 
GridClientMarshaller {
     @Override public <T> T unmarshal(byte[] bytes) throws IOException {
         ByteArrayInputStream tmp = new ByteArrayInputStream(bytes);
 
-        ObjectInput in = new ClientJdkInputStream(tmp, clsFilter);
+        ObjectInput in = new ClientJdkInputStream(tmp);
 
         try {
             return (T)in.readObject();
@@ -93,24 +76,16 @@ public class GridClientJdkMarshaller implements 
GridClientMarshaller {
      * Wrapper with class resolving control.
      */
     private static class ClientJdkInputStream extends ObjectInputStream {
-        /** Class name filter. */
-        private final IgnitePredicate<String> clsFilter;
-
-        /**
-         * @param in Input stream.
-         * @param clsFilter Class filter.
-         */
-        public ClientJdkInputStream(InputStream in, IgnitePredicate<String> 
clsFilter) throws IOException {
+        /** */
+        public ClientJdkInputStream(InputStream in) throws IOException {
             super(in);
-
-            this.clsFilter = clsFilter;
         }
 
         /** {@inheritDoc} */
         @Override protected Class<?> resolveClass(ObjectStreamClass desc) 
throws IOException, ClassNotFoundException {
             String clsName = desc.getName();
 
-            if (clsFilter != null && !clsFilter.apply(clsName))
+            if (!MarshallerUtils.classNameFilter().apply(clsName))
                 throw new RuntimeException("Deserialization of class " + 
clsName + " is disallowed.");
 
             return super.resolveClass(desc);
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
index 2677959f0b4..6ec84c1f552 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
@@ -47,7 +47,7 @@ public class GridClientOptimizedMarshaller implements 
GridClientMarshaller {
     public GridClientOptimizedMarshaller() {
         opMarsh = Marshallers.optimized();
 
-        opMarsh.setContext(new MarshallerContextImpl(null, null));
+        opMarsh.setContext(new MarshallerContextImpl(null));
     }
 
     /**
@@ -58,7 +58,7 @@ public class GridClientOptimizedMarshaller implements 
GridClientMarshaller {
     public GridClientOptimizedMarshaller(@Nullable List<PluginProvider> 
plugins) {
         opMarsh = Marshallers.optimized();
 
-        opMarsh.setContext(new MarshallerContextImpl(plugins, null));
+        opMarsh.setContext(new MarshallerContextImpl(plugins));
     }
 
     /** {@inheritDoc} */
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
index 64e1fb2f45c..ab4c55c7b52 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java
@@ -125,7 +125,6 @@ import 
org.apache.ignite.internal.thread.context.concurrent.IgniteCompletableFut
 import org.apache.ignite.internal.util.HostAndPortRange;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.lang.IgniteProductVersion;
 import org.apache.ignite.logger.NullLogger;
 import org.apache.ignite.marshaller.MarshallerContext;
@@ -2422,12 +2421,15 @@ public class JdbcThinConnection implements Connection {
         /** */
         private final Set<String> sysTypes = new HashSet<>();
 
+        /** JDK marshaller. */
+        private final JdkMarshaller jdkMarsh = Marshallers.jdk();
+
         /**
          * Default constructor.
          */
         public JdbcMarshallerContext() {
             try {
-                processSystemClasses(U.gridClassLoader(), sysTypes::add);
+                processSystemClasses(sysTypes::add);
             }
             catch (IOException e) {
                 throw new IgniteException("Unable to initialize marshaller 
context", e);
@@ -2535,14 +2537,9 @@ public class JdbcThinConnection implements Connection {
             return sysTypes.contains(typeName);
         }
 
-        /** {@inheritDoc} */
-        @Override public IgnitePredicate<String> classNameFilter() {
-            return null;
-        }
-
         /** {@inheritDoc} */
         @Override public JdkMarshaller jdkMarshaller() {
-            return Marshallers.jdk();
+            return jdkMarsh;
         }
     }
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
index 8cad60ec143..4a3bf02a87c 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
@@ -273,7 +273,7 @@ public class JdbcThinTcpIo {
     private HandshakeResult handshake(ClientListenerProtocolVersion ver) 
throws IOException, SQLException {
         BinaryMarshaller marsh = new BinaryMarshaller();
 
-        marsh.setContext(new MarshallerContextImpl(null, null));
+        marsh.setContext(new MarshallerContextImpl(null));
 
         BinaryWriterEx writer = BinaryUtils.writer(U.binaryContext(marsh), 
BinaryStreams.outputStream(HANDSHAKE_MSG_SIZE), null);
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
index b6d1d5d6402..3b0acf2e65e 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
@@ -107,7 +107,6 @@ import 
org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.internal.worker.WorkersRegistry;
 import org.apache.ignite.maintenance.MaintenanceRegistry;
-import org.apache.ignite.marshaller.MarshallerUtils;
 import org.apache.ignite.plugin.PluginNotFoundException;
 import org.apache.ignite.plugin.PluginProvider;
 import org.apache.ignite.plugin.extensions.communication.MessageFactory;
@@ -203,7 +202,7 @@ public class StandaloneGridKernalContext implements 
GridKernalContext {
         this.ft = ft;
         this.marsh = new BinaryMarshaller();
 
-        marshallerCtx = new MarshallerContextImpl(null, 
MarshallerUtils.classNameFilter(getClass().getClassLoader()));
+        marshallerCtx = new MarshallerContextImpl(null);
         cfg = prepareIgniteConfiguration();
 
         try {
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java
index 4e1f32ba1ee..ed3eb4247c3 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java
@@ -358,7 +358,7 @@ public class ClientListenerNioListener extends 
GridNioServerListenerAdapter<Clie
     private void onHandshake(GridNioSession ses, ClientMessage msg) {
         BinaryMarshaller marsh = new BinaryMarshaller();
 
-        marsh.setContext(new MarshallerContextImpl(null, null));
+        marsh.setContext(new MarshallerContextImpl(null));
 
         BinaryReaderEx reader = BinaryUtils.reader(U.binaryContext(marsh), 
BinaryStreams.inputStream(msg.payload()), null, true);
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
index 3274a6f7382..18ae92a112c 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
@@ -882,7 +882,7 @@ public class PlatformUtils {
     public static GridBinaryMarshaller marshaller() {
         BinaryMarshaller marsh = new BinaryMarshaller();
 
-        marsh.setContext(new MarshallerContextImpl(null, null));
+        marsh.setContext(new MarshallerContextImpl(null));
 
         return new 
GridBinaryMarshaller(U.binaryContext(BinaryUtils.noopMetadataHandler(), marsh));
     }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestParser.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestParser.java
index 4ca84258c3b..6a1a863565e 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestParser.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestParser.java
@@ -69,7 +69,7 @@ import static 
org.apache.ignite.internal.util.nio.GridNioSessionMetaKey.PARSER_S
  */
 public class GridTcpRestParser implements GridNioParser {
     /** JDK marshaller. */
-    private final Marshaller marsh;
+    private final Marshaller marsh = Marshallers.jdk();
 
     /** Router client flag. */
     private final boolean routerClient;
@@ -78,16 +78,7 @@ public class GridTcpRestParser implements GridNioParser {
      * @param routerClient Router client flag.
      */
     public GridTcpRestParser(boolean routerClient) {
-        this(routerClient, Marshallers.jdk());
-    }
-
-    /**
-     * @param routerClient Router client flag.
-     * @param marsh Marshaller.
-     */
-    public GridTcpRestParser(boolean routerClient, Marshaller marsh) {
         this.routerClient = routerClient;
-        this.marsh = marsh;
     }
 
     /** {@inheritDoc} */
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
index d8825397806..b0d3502b250 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
@@ -27,7 +27,6 @@ import javax.cache.configuration.Factory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLException;
 import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.IgniteException;
 import org.apache.ignite.configuration.ConnectorConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.GridKernalContext;
@@ -47,8 +46,6 @@ import org.apache.ignite.internal.util.nio.GridNioServer;
 import org.apache.ignite.internal.util.nio.GridNioServerListener;
 import org.apache.ignite.internal.util.nio.ssl.GridNioSslFilter;
 import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgnitePredicate;
-import org.apache.ignite.marshaller.MarshallerUtils;
 import org.apache.ignite.plugin.PluginProvider;
 import org.apache.ignite.spi.IgnitePortProtocol;
 import org.jetbrains.annotations.Nullable;
@@ -88,7 +85,7 @@ public class GridTcpRestProtocol extends 
GridRestProtocolAdapter {
 
         lsnr = new GridTcpRestNioListener(log, this, hnd, ctx);
 
-        GridNioParser parser = new GridTcpRestParser(false, 
ctx.marshallerContext().jdkMarshaller());
+        GridNioParser parser = new GridTcpRestParser(false);
 
         try {
             host = resolveRestTcpHost(ctx.config());
@@ -149,15 +146,7 @@ public class GridTcpRestProtocol extends 
GridRestProtocolAdapter {
 
         marshMap.put(GridClientOptimizedMarshaller.ID, optMarsh);
         marshMap.put(GridClientZipOptimizedMarshaller.ID, new 
GridClientZipOptimizedMarshaller(optMarsh, providers));
-
-        try {
-            IgnitePredicate<String> clsFilter = 
MarshallerUtils.classNameFilter(getClass().getClassLoader());
-
-            marshMap.put(GridClientJdkMarshaller.ID, new 
GridClientJdkMarshaller(clsFilter));
-        }
-        catch (IgniteCheckedException e) {
-            throw new IgniteException(e);
-        }
+        marshMap.put(GridClientJdkMarshaller.ID, new 
GridClientJdkMarshaller());
 
         lsnr.marshallers(marshMap);
     }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/stream/socket/SocketStreamer.java
 
b/modules/core/src/main/java/org/apache/ignite/stream/socket/SocketStreamer.java
index e4587555f3f..2aa8dc126d4 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/stream/socket/SocketStreamer.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/stream/socket/SocketStreamer.java
@@ -24,7 +24,6 @@ import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteDataStreamer;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.util.nio.GridBufferedParser;
 import org.apache.ignite.internal.util.nio.GridDelimitedParser;
 import org.apache.ignite.internal.util.nio.GridNioCodecFilter;
@@ -228,7 +227,7 @@ public class SocketStreamer<T, K, V> extends 
StreamAdapter<T, K, V> {
          * @param igniteInstanceName Ignite instance name.
          */
         private DefaultConverter(@Nullable String igniteInstanceName) {
-            marsh = 
Marshallers.jdk(((IgniteKernal)ignite).context().marshallerContext().classNameFilter());
+            marsh = Marshallers.jdk();
 
             marsh.nodeName(igniteInstanceName);
         }
diff --git a/modules/core/src/test/config/class_list_exploit_included.txt 
b/modules/core/src/test/config/class_list_exploit_included.txt
index b461d53280d..fe3e9fb25d0 100644
--- a/modules/core/src/test/config/class_list_exploit_included.txt
+++ b/modules/core/src/test/config/class_list_exploit_included.txt
@@ -18,4 +18,4 @@
 org.apache.ignite.spi.discovery.tcp.DiscoveryUnmarshalVulnerabilityTest$Exploit
 
org.apache.ignite.stream.socket.SocketStreamerUnmarshalVulnerabilityTest$Exploit
 
org.apache.ignite.internal.processors.rest.TcpRestUnmarshalVulnerabilityTest$Exploit
-org.apache.ignite.internal.processors.rest.JettyRestProcessorAbstractSelfTest$Exploit
\ No newline at end of file
+org.apache.ignite.internal.processors.rest.JettyRestProcessorClassFilterTest$Exploit
\ No newline at end of file
diff --git a/modules/core/src/test/config/class_list_test_excluded.txt 
b/modules/core/src/test/config/class_list_test_excluded.txt
deleted file mode 100644
index 787ed899f08..00000000000
--- a/modules/core/src/test/config/class_list_test_excluded.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-org.apache.ignite.internal.processors.metastorage.DistributedMetaStorageClassloadingTest$BamboozleClass
\ No newline at end of file
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java
index f160816432a..db9ad8a07bc 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java
@@ -148,7 +148,7 @@ public class MarshallerContextLockingSelfTest extends 
GridCommonAbstractTest {
         public void executeTest(GridTestLog4jLogger log, GridKernalContext 
ctx) throws Exception {
             counter.incrementAndGet();
 
-            MarshallerContextImpl marshallerCtx = new 
MarshallerContextImpl(null, null);
+            MarshallerContextImpl marshallerCtx = new 
MarshallerContextImpl(null);
 
             marshallerCtx.setMarshallerMappingFileStoreDir(new 
SharedFileTree(U.defaultWorkDirectory()).marshaller());
             marshallerCtx.onMarshallerProcessorStarted(ctx, null);
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryMarshallerCtxDisabledSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryMarshallerCtxDisabledSelfTest.java
index e300dfc7532..57056aee620 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryMarshallerCtxDisabledSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryMarshallerCtxDisabledSelfTest.java
@@ -29,7 +29,6 @@ import org.apache.ignite.binary.BinaryWriter;
 import org.apache.ignite.binary.Binarylizable;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.marshaller.MarshallerContext;
 import org.apache.ignite.marshaller.Marshallers;
 import org.apache.ignite.marshaller.jdk.JdkMarshaller;
@@ -122,11 +121,6 @@ public class GridBinaryMarshallerCtxDisabledSelfTest 
extends GridCommonAbstractT
             return false;
         }
 
-        /** {@inheritDoc} */
-        @Override public IgnitePredicate<String> classNameFilter() {
-            return null;
-        }
-
         /** {@inheritDoc} */
         @Override public JdkMarshaller jdkMarshaller() {
             return Marshallers.jdk();
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/binary/RawBinaryObjectExtractorTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/binary/RawBinaryObjectExtractorTest.java
index 364dbdc43dd..721dbe731de 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/binary/RawBinaryObjectExtractorTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/binary/RawBinaryObjectExtractorTest.java
@@ -31,7 +31,6 @@ import 
org.apache.ignite.internal.binary.builder.BinaryObjectBuilders;
 import 
org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses.TestObjectAllTypes;
 import org.apache.ignite.internal.binary.streams.BinaryStreams;
 import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.marshaller.MarshallerContext;
 import org.apache.ignite.marshaller.Marshallers;
 import org.apache.ignite.marshaller.jdk.JdkMarshaller;
@@ -153,11 +152,6 @@ public class RawBinaryObjectExtractorTest extends 
GridCommonAbstractTest {
             return false;
         }
 
-        /** {@inheritDoc} */
-        @Override public IgnitePredicate<String> classNameFilter() {
-            return null;
-        }
-
         /** {@inheritDoc} */
         @Override public JdkMarshaller jdkMarshaller() {
             return Marshallers.jdk();
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheEntryMemorySizeSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheEntryMemorySizeSelfTest.java
index 3bd7c18923a..d2826f42f9e 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheEntryMemorySizeSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheEntryMemorySizeSelfTest.java
@@ -30,7 +30,6 @@ import org.apache.ignite.configuration.NearCacheConfiguration;
 import 
org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry;
 import 
org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry;
 import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.marshaller.Marshaller;
 import org.apache.ignite.marshaller.MarshallerContext;
 import org.apache.ignite.marshaller.Marshallers;
@@ -156,10 +155,6 @@ public class GridCacheEntryMemorySizeSelfTest extends 
GridCommonAbstractTest {
                 return false;
             }
 
-            @Override public IgnitePredicate<String> classNameFilter() {
-                return null;
-            }
-
             @Override public JdkMarshaller jdkMarshaller() {
                 return Marshallers.jdk();
             }
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/metastorage/DistributedMetaStorageClassloadingTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/metastorage/DistributedMetaStorageClassloadingTest.java
index 1083a7d1a96..c690cb5f6b1 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/metastorage/DistributedMetaStorageClassloadingTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/metastorage/DistributedMetaStorageClassloadingTest.java
@@ -24,20 +24,16 @@ import org.apache.ignite.failure.FailureContext;
 import org.apache.ignite.failure.FailureHandler;
 import org.apache.ignite.internal.IgniteEx;
 import 
org.apache.ignite.internal.processors.metastorage.persistence.DistributedMetaStorageImpl;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.testframework.junits.WithSystemProperty;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
-import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION;
-import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_BLACKLIST;
+import static 
org.apache.ignite.testframework.GridTestUtils.assertThrowsWithCause;
 
 /**
  * Test for {@link DistributedMetaStorageImpl} issues with classloading.
  */
-@WithSystemProperty(key = IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION, 
value = "false")
 public class DistributedMetaStorageClassloadingTest extends 
GridCommonAbstractTest {
     /** Failure handler that keeps count of failures (initialized before every 
test). */
     private CountingFailureHandler failureHandler;
@@ -46,6 +42,9 @@ public class DistributedMetaStorageClassloadingTest extends 
GridCommonAbstractTe
     @Override protected IgniteConfiguration getConfiguration(String 
igniteInstanceName) throws Exception {
         IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
 
+        if (cfg.isClientMode())
+            cfg.setClassLoader(getExternalClassLoader());
+
         cfg.setConsistentId(igniteInstanceName);
 
         return cfg;
@@ -63,65 +62,29 @@ public class DistributedMetaStorageClassloadingTest extends 
GridCommonAbstractTe
         failureHandler = new CountingFailureHandler();
     }
 
-    /**
-     * Test that receiving data of unknown class into distributed metastorage 
doesn't lead to failure.
-     *
-     * Description:
-     * Start server node with exclusion of certain BamboozleClass (this is 
done via system property
-     * which adds class filter to class loader).
-     * Start client node and write new instance of BamboozleClass to the 
distributed metastorage to test that
-     * new value is not marshalled.
-     * Write another instance of BamboozleClass (with different value of 
fields) to test that
-     * old value is not unmarshalled.
-     * There must be no failures and all 2 grids must be alive.
-     *
-     * @throws Exception If failed.
-     */
+    /** Test that receiving data of unknown class into distributed metastorage 
doesn't lead to failure. */
     @Test
     public void testWontFailReceivingDataOfUnknownClass() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_test_excluded.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
         startGrid(1);
-        System.clearProperty(IGNITE_MARSHALLER_BLACKLIST);
 
         IgniteEx client = startClientGrid(0);
 
-        client.context().distributedMetastorage().write("hey", new 
BamboozleClass(0));
-        client.context().distributedMetastorage().write("hey", new 
BamboozleClass(1));
+        client.context().distributedMetastorage().write("hey", 
serverUnknown("one"));
+        client.context().distributedMetastorage().write("hey", 
serverUnknown("two"));
 
         assertEquals(0, failureHandler.getCount());
     }
 
-    /**
-     * Test that reading data of unknown class from distributed metastorage 
doesn't lead to failure.
-     *
-     * Description:
-     * Start server node with exclusion of certain BamboozleClass (this is 
done via system property
-     * which adds class filter to class loader).
-     * Start client node and write new instance of BamboozleClass to the 
distributed metastorage.
-     * Try reading data of BamboozleClass
-     *
-     * @throws Exception If failed.
-     */
+    /** Test that reading data of unknown class from distributed metastorage 
doesn't lead to failure. */
     @Test
     public void testWontFailReadingDataOfUnknownClass() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_test_excluded.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
         IgniteEx ignite = startGrid(1);
-        System.clearProperty(IGNITE_MARSHALLER_BLACKLIST);
 
         IgniteEx client = startClientGrid(0);
 
-        client.context().distributedMetastorage().write("hey", new 
BamboozleClass(0));
+        client.context().distributedMetastorage().write("hey", 
serverUnknown("0"));
 
-        try {
-            Serializable hey = 
ignite.context().distributedMetastorage().read("hey");
-        }
-        catch (Exception ignored) {
-            // Ignore.
-        }
+        assertThrowsWithCause(() -> 
ignite.context().distributedMetastorage().read("hey"), 
ClassNotFoundException.class);
 
         assertEquals(0, failureHandler.getCount());
     }
@@ -141,24 +104,13 @@ public class DistributedMetaStorageClassloadingTest 
extends GridCommonAbstractTe
      */
     @Test
     public void testFailListeningForDataOfUnknownClass() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_test_excluded.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
         IgniteEx ignite = startGrid(1);
-        System.clearProperty(IGNITE_MARSHALLER_BLACKLIST);
 
         IgniteEx client = startClientGrid(0);
 
-        ignite.context().distributedMetastorage().listen("hey"::equals, (key, 
oldVal, newVal) -> {
-            System.out.println(newVal);
-        });
+        ignite.context().distributedMetastorage().listen("hey"::equals, (key, 
oldVal, newVal) -> System.out.println(newVal));
 
-        try {
-            client.context().distributedMetastorage().write("hey", new 
BamboozleClass(0));
-        }
-        catch (Exception ignored) {
-            // Ignore.
-        }
+        client.context().distributedMetastorage().write("hey", 
serverUnknown("0"));
 
         assertEquals(1, failureHandler.getCount());
     }
@@ -169,24 +121,6 @@ public class DistributedMetaStorageClassloadingTest 
extends GridCommonAbstractTe
         stopAllGrids();
     }
 
-    /**
-     * Class that would be excluded on the certain npde.
-     */
-    public static final class BamboozleClass implements Serializable {
-        /** */
-        private final int i;
-
-        /** */
-        public BamboozleClass(int i) {
-            this.i = i;
-        }
-
-        /** */
-        public int getI() {
-            return i;
-        }
-    }
-
     /**
      * Failure handler that only keeps count of failures.
      */
@@ -211,4 +145,10 @@ public class DistributedMetaStorageClassloadingTest 
extends GridCommonAbstractTe
         }
     }
 
+    /** */
+    private static Serializable serverUnknown(String name) throws Exception {
+        return 
(Serializable)getExternalClassLoader().loadClass("org.apache.ignite.tests.p2p.cache.Person")
+            .getConstructor(String.class).newInstance(name);
+    }
+
 }
diff --git 
a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java
index f140e37efc8..920a78b9033 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java
@@ -266,7 +266,7 @@ public class MarshallerContextSelfTest extends 
GridCommonAbstractTest {
 
     /** */
     private @NotNull MarshallerContextImpl marshallerContext() throws 
IgniteCheckedException {
-        MarshallerContextImpl mctx = new MarshallerContextImpl(null, null);
+        MarshallerContextImpl mctx = new MarshallerContextImpl(null);
 
         mctx.setMarshallerMappingFileStoreDir(sharedFileTree().marshaller());
         mctx.onMarshallerProcessorStarted(ctx, null);
diff --git 
a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java
 
b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java
index ae023eb84d5..12f598c1c16 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java
@@ -43,7 +43,7 @@ public class MarshallerContextTestImpl extends 
MarshallerContextImpl {
      * @param excluded Excluded classes.
      */
     public MarshallerContextTestImpl(@Nullable List<PluginProvider> plugins, 
Collection<String> excluded) {
-        super(plugins, null);
+        super(plugins);
 
         this.excluded = excluded;
     }
diff --git 
a/modules/core/src/test/java/org/apache/ignite/marshaller/ObjectInputStreamFilteringTest.java
 
b/modules/core/src/test/java/org/apache/ignite/marshaller/ObjectInputStreamFilteringTest.java
index e381382fdf9..fd0363410bc 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/marshaller/ObjectInputStreamFilteringTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/marshaller/ObjectInputStreamFilteringTest.java
@@ -20,7 +20,6 @@ package org.apache.ignite.marshaller;
 import java.util.HashMap;
 import java.util.Map;
 import javax.management.BadAttributeValueExpException;
-import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.Ignition;
 import org.apache.ignite.client.ClientConnectionException;
 import org.apache.ignite.client.IgniteClient;
@@ -28,15 +27,12 @@ import org.apache.ignite.configuration.ClientConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.Order;
 import org.apache.ignite.internal.dto.IgniteDataTransferObject;
-import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.ListeningTestLogger;
 import org.apache.ignite.testframework.LogListener;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.junit.Test;
 
-import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_BLACKLIST;
-
 /** */
 public class ObjectInputStreamFilteringTest extends GridCommonAbstractTest {
     /** */
@@ -104,29 +100,6 @@ public class ObjectInputStreamFilteringTest extends 
GridCommonAbstractTest {
         }
     }
 
-    /** */
-    @Test
-    public void testMultipleIgniteInstancesWithDifferentBlackLists() throws 
Exception {
-        startGrid(0);
-
-        String blackListPath = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, blackListPath);
-
-        try {
-            GridTestUtils.assertThrowsAnyCause(
-                log,
-                () -> startGrid(1),
-                IgniteCheckedException.class,
-                "Failed to autoconfigure Ignite Object Input Filter for the 
current JVM because it was already set" +
-                    " by another Ignite instance which is running in the same 
JVM"
-            );
-        }
-        finally {
-            System.clearProperty(IGNITE_MARSHALLER_BLACKLIST);
-        }
-    }
-
     /** */
     public static class Holder extends IgniteDataTransferObject {
         /** */
diff --git 
a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/DiscoveryUnmarshalVulnerabilityTest.java
 
b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/DiscoveryUnmarshalVulnerabilityTest.java
index a146d0f2fd9..f0c4fa25f9f 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/DiscoveryUnmarshalVulnerabilityTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/DiscoveryUnmarshalVulnerabilityTest.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.spi.discovery.tcp;
 
 import java.io.BufferedOutputStream;
+import java.io.File;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.OutputStream;
@@ -25,19 +26,25 @@ import java.io.Serializable;
 import java.net.InetAddress;
 import java.net.Socket;
 import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.Ignition;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.CoreMessagesProvider;
 import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.direct.DirectMessageWriter;
 import org.apache.ignite.internal.managers.communication.IgniteMessageFactory;
 import org.apache.ignite.internal.managers.communication.MessageMarshalling;
 import 
org.apache.ignite.internal.plugin.AbstractMarshallableMessageFactoryProvider;
 import org.apache.ignite.internal.processors.cache.CacheObjectContext;
-import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.marshaller.Marshallers;
+import org.apache.ignite.plugin.AbstractTestPluginProvider;
+import org.apache.ignite.plugin.ExtensionRegistry;
+import org.apache.ignite.plugin.PluginContext;
 import org.apache.ignite.plugin.extensions.communication.MessageFactory;
 import 
org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider;
 import org.apache.ignite.plugin.extensions.communication.MessageMarshaller;
@@ -47,11 +54,9 @@ import 
org.apache.ignite.plugin.extensions.communication.MessageWriter;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.ListeningTestLogger;
 import org.apache.ignite.testframework.LogListener;
-import org.apache.ignite.testframework.junits.WithSystemProperty;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.junit.Test;
 
-import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION;
 import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_BLACKLIST;
 import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_WHITELIST;
 import static org.apache.ignite.testframework.GridTestUtils.loadMarshaller;
@@ -60,25 +65,12 @@ import static 
org.apache.ignite.testframework.GridTestUtils.loadSerializer;
 /**
  * Tests for whitelist and blacklist ot avoiding deserialization vulnerability.
  */
-@WithSystemProperty(key = IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION, 
value = "false")
-public class DiscoveryUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest {
-    /** Shared value. */
-    private static final AtomicBoolean SHARED = new AtomicBoolean();
-
+public abstract class DiscoveryUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest {
     /** */
-    private LogListener lsnr;
-
-    /** {@inheritDoc} */
-    @Override protected void beforeTest() throws Exception {
-        super.beforeTest();
-
-        SHARED.set(false);
-
-        System.clearProperty(IGNITE_MARSHALLER_WHITELIST);
-        System.clearProperty(IGNITE_MARSHALLER_BLACKLIST);
+    public static final String EXPLOIT_CACHE = "exploit-cache";
 
-        IgniteUtils.clearClassCache();
-    }
+    /** */
+    LogListener lsnr;
 
     /** {@inheritDoc} */
     @Override protected void afterTest() throws Exception {
@@ -87,115 +79,143 @@ public class DiscoveryUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest
 
     /** {@inheritDoc} */
     @Override protected IgniteConfiguration getConfiguration(String 
igniteInstanceName) throws Exception {
-        MessageFactoryProvider msgFactoryProvider = new 
AbstractMarshallableMessageFactoryProvider() {
-            @Override public void registerAll(IgniteMessageFactory factory) {
-                factory.register(
-                    (short)(CoreMessagesProvider.MAX_MESSAGE_ID + 1),
-                    new MessageSerializerWrapper(),
-                    new MessageMarshallerWrapper(this));
-            }
-        };
-
         IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
 
-        TestTcpDiscoverySpi discoSpi = new TestTcpDiscoverySpi();
-        discoSpi.messageFactory(msgFactoryProvider);
-
         lsnr = LogListener.matches("Invalid message type").build();
 
-        return cfg.setDiscoverySpi(discoSpi)
+        return cfg
+            .setPluginProviders(new TestMessageFactoryPlugin())
             .setGridLogger(new ListeningTestLogger(log, lsnr));
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testNoLists() throws Exception {
-        testExploit(true);
+    /** */
+    public static class NoListsTest extends 
DiscoveryUnmarshalVulnerabilityTest {
+        /** @throws Exception If failed. */
+        @Test
+        public void testNoLists() throws Exception {
+            testExploit(true);
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testWhiteListIncluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
+    /** */
+    public static class WhiteListIncludedTest extends 
DiscoveryUnmarshalVulnerabilityTest {
+        /** @throws Exception If failed. */
+        @Test
+        public void test() throws Exception {
+            testExploit(true);
+        }
 
-        testExploit(true);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            return Arrays.asList(
+                "-D" + IGNITE_MARSHALLER_WHITELIST +
+                    "=" + 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt")
+            );
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testWhiteListExcluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
+    /** */
+    public static class WhiteListExcludedTest extends 
DiscoveryUnmarshalVulnerabilityTest {
+        /** @throws Exception If failed. */
+        @Test
+        public void test() throws Exception {
+            testExploit(false);
+        }
 
-        testExploit(false);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            return Arrays.asList(
+                "-D" + IGNITE_MARSHALLER_WHITELIST +
+                    "=" + 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt")
+            );
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testBlackListIncluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+    /** */
+    public static class BlackListIncludedTest extends 
DiscoveryUnmarshalVulnerabilityTest {
+        /** @throws Exception If failed. */
+        @Test
+        public void test() throws Exception {
+            testExploit(false);
+        }
 
-        testExploit(false);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            return Arrays.asList(
+                "-D" + IGNITE_MARSHALLER_BLACKLIST +
+                    "=" + 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt")
+            );
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testBlackListExcluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+    /** */
+    public static class BlackListExcludedTest extends 
DiscoveryUnmarshalVulnerabilityTest {
+        /** @throws Exception If failed. */
+        @Test
+        public void test() throws Exception {
+            testExploit(true);
+        }
 
-        testExploit(true);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            return Arrays.asList(
+                "-D" + IGNITE_MARSHALLER_BLACKLIST +
+                    "=" + 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt")
+            );
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testBothListIncluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
+    /** */
+    public static class BothListIncludedTest extends 
DiscoveryUnmarshalVulnerabilityTest {
+        /** @throws Exception If failed. */
+        @Test
+        public void test() throws Exception {
+            testExploit(false);
+        }
 
-        System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
-        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            File path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt");
 
-        testExploit(false);
+            return Arrays.asList(
+                "-D" + IGNITE_MARSHALLER_WHITELIST + "=" + path,
+                "-D" + IGNITE_MARSHALLER_BLACKLIST + "=" + path
+            );
+        }
     }
 
     /** */
-    @Test
-    public void testExploitDirectly() throws Exception {
-        startGrid();
+    public static class ExploitDirectlyTest extends 
DiscoveryUnmarshalVulnerabilityTest {
+        /** */
+        @Test
+        public void test() throws Exception {
+            IgniteEx srv = startGrid(0);
+
+            startGrid(1);
 
-        attack(Marshallers.jdk().marshal(new Exploit()));
+            attack(Marshallers.jdk().marshal(new Exploit()));
 
-        assertTrue("Invalid message type MUST occur", 
lsnr.check(getTestTimeout()));
-        assertFalse(SHARED.get());
+            assertTrue("Invalid message type MUST occur", 
lsnr.check(getTestTimeout()));
+            assertFalse(srv.cacheNames().contains(EXPLOIT_CACHE));
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override protected boolean isMultiJvm() {
+        return true;
     }
 
     /**
      * @param positive Positive.
      */
-    private void testExploit(boolean positive) throws Exception {
-        startGrid();
+    void testExploit(boolean positive) throws Exception {
+        IgniteEx srv = startGrid(0);
+
+        startGrid(1);
 
         attack(serializedMessage());
 
-        boolean res = GridTestUtils.waitForCondition(SHARED::get, 5000);
+        boolean res = GridTestUtils.waitForCondition(() -> 
srv.cacheNames().contains(EXPLOIT_CACHE), 5000);
 
         if (positive)
             assertTrue(res);
@@ -208,11 +228,11 @@ public class DiscoveryUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest
     /**
      * @param data Data.
      */
-    private void attack(byte[] data) throws IOException {
+    void attack(byte[] data) throws IOException {
         InetAddress addr = InetAddress.getLoopbackAddress();
 
         try (
-            Socket sock = new Socket(addr, 47500);
+            Socket sock = new Socket(addr, 47501);
             OutputStream oos = new BufferedOutputStream(sock.getOutputStream())
         ) {
             oos.write(U.IGNITE_HEADER);
@@ -224,14 +244,14 @@ public class DiscoveryUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest
     private byte[] serializedMessage() throws IgniteCheckedException {
         ByteBuffer buf = ByteBuffer.allocate(4096);
 
-        MessageFactory msgFactory = 
((TcpDiscoverySpi)grid().configuration().getDiscoverySpi()).messageFactory();
+        MessageFactory msgFactory = 
((TcpDiscoverySpi)grid(0).configuration().getDiscoverySpi()).messageFactory();
 
         DirectMessageWriter writer = new DirectMessageWriter(msgFactory);
         writer.setBuffer(buf);
 
         ExploitMessage msg = new ExploitMessage(new Exploit());
 
-        MessageMarshalling.marshal(msg, grid().context(), null);
+        MessageMarshalling.marshal(msg, grid(0).context(), null);
 
         writer.writeMessage(msg);
 
@@ -244,7 +264,7 @@ public class DiscoveryUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest
          * @param is Input stream.
          */
         private void readObject(ObjectInputStream is) throws 
ClassNotFoundException, IOException {
-            SHARED.set(true);
+            Ignition.localIgnite().createCache(EXPLOIT_CACHE);
         }
     }
 
@@ -284,20 +304,12 @@ public class DiscoveryUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest
 
     /** Lazily-initialized {@link MessageMarshaller} wrapper resolved from the 
plugin provider. */
     private static class MessageMarshallerWrapper implements 
MessageMarshaller<ExploitMessage> {
-        /** */
-        private final AbstractMarshallableMessageFactoryProvider provider;
-
         /** */
         private final AtomicBoolean init = new AtomicBoolean(true);
 
         /** */
         private MessageMarshaller<ExploitMessage> marsh;
 
-        /** */
-        private 
MessageMarshallerWrapper(AbstractMarshallableMessageFactoryProvider provider) {
-            this.provider = provider;
-        }
-
         /** {@inheritDoc} */
         @Override public void marshal(ExploitMessage msg, GridKernalContext 
kctx, CacheObjectContext nested)
             throws IgniteCheckedException {
@@ -324,7 +336,29 @@ public class DiscoveryUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest
         /** */
         private void initIfNecessary() {
             if (init.get() && init.compareAndSet(true, false))
-                marsh = loadMarshaller(ExploitMessage.class, U.field(provider, 
"dfltMarsh"));
+                marsh = loadMarshaller(ExploitMessage.class, 
Marshallers.jdk());
+        }
+    }
+
+    /** */
+    public static class TestMessageFactoryPlugin extends 
AbstractTestPluginProvider {
+        /** {@inheritDoc} */
+        @Override public void initExtensions(PluginContext ctx, 
ExtensionRegistry registry) {
+            registry.registerExtension(MessageFactoryProvider.class, new 
AbstractMarshallableMessageFactoryProvider() {
+                /** {@inheritDoc} */
+                @Override public void registerAll(IgniteMessageFactory 
factory) {
+                    factory.register(
+                        (short)(CoreMessagesProvider.MAX_MESSAGE_ID + 1),
+                        new MessageSerializerWrapper(),
+                        new MessageMarshallerWrapper());
+                }
+            });
+            super.initExtensions(ctx, registry);
+        }
+
+        /** {@inheritDoc} */
+        @Override public String name() {
+            return "MessageFactoryPlugin";
         }
     }
 }
diff --git 
a/modules/core/src/test/java/org/apache/ignite/stream/socket/SocketStreamerUnmarshalVulnerabilityTest.java
 
b/modules/core/src/test/java/org/apache/ignite/stream/socket/SocketStreamerUnmarshalVulnerabilityTest.java
index 4c8e3abeb61..d34fd0b4aca 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/stream/socket/SocketStreamerUnmarshalVulnerabilityTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/stream/socket/SocketStreamerUnmarshalVulnerabilityTest.java
@@ -25,36 +25,35 @@ import java.io.Serializable;
 import java.net.InetAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.util.Arrays;
+import java.util.List;
 import java.util.Map;
-import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteDataStreamer;
-import org.apache.ignite.IgniteException;
+import org.apache.ignite.Ignition;
 import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.util.lang.GridAbsPredicate;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiTuple;
+import org.apache.ignite.lang.IgniteCallable;
 import org.apache.ignite.marshaller.Marshaller;
 import org.apache.ignite.marshaller.Marshallers;
 import org.apache.ignite.stream.StreamSingleTupleExtractor;
 import org.apache.ignite.testframework.GridTestUtils;
-import org.apache.ignite.testframework.junits.WithSystemProperty;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.junit.Test;
 
-import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION;
 import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_BLACKLIST;
 import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHALLER_WHITELIST;
 
 /**
  * Tests for whitelist and blacklist ot avoiding deserialization vulnerability.
  */
-@WithSystemProperty(key = IGNITE_ENABLE_OBJECT_INPUT_FILTER_AUTOCONFIGURATION, 
value = "false")
-public class SocketStreamerUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest {
-    /** Shared value. */
-    private static final AtomicBoolean SHARED = new AtomicBoolean();
+public abstract class SocketStreamerUnmarshalVulnerabilityTest extends 
GridCommonAbstractTest {
+    /** */
+    public static final String EXPLOIT_CACHE = "exploit-cache";
 
     /** Port. */
     private static int port;
@@ -72,117 +71,109 @@ public class SocketStreamerUnmarshalVulnerabilityTest 
extends GridCommonAbstract
         return cfg;
     }
 
-    /** {@inheritDoc} */
-    @Override protected void beforeTest() throws Exception {
-        super.beforeTest();
-
-        SHARED.set(false);
-
-        System.clearProperty(IGNITE_MARSHALLER_WHITELIST);
-        System.clearProperty(IGNITE_MARSHALLER_BLACKLIST);
-
-        IgniteUtils.clearClassCache();
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testNoLists() throws Exception {
-        testExploit(true);
+    /** */
+    public static class NoListsTest extends 
SocketStreamerUnmarshalVulnerabilityTest {
+        /** @throws Exception If failed. */
+        @Test
+        public void test() throws Exception {
+            testExploit(true);
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testWhiteListIncluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
+    /** */
+    public static class WhiteListIncludedTest extends 
SocketStreamerUnmarshalVulnerabilityTest {
+        /** @throws Exception If failed. */
+        @Test
+        public void test() throws Exception {
+            testExploit(true);
+        }
 
-        testExploit(true);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            return Arrays.asList("-D" + IGNITE_MARSHALLER_WHITELIST +
+                "=" + 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath());
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testWhiteListExcluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
+    /** */
+    public static class WhiteListExcludedTest extends 
SocketStreamerUnmarshalVulnerabilityTest {
+        /** @throws Exception If failed. */
+        @Test
+        public void test() throws Exception {
+            testExploit(false);
+        }
 
-        testExploit(false);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            return Arrays.asList("-D" + IGNITE_MARSHALLER_WHITELIST +
+                "=" + 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt").getPath());
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testBlackListIncluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+    /** */
+    public static class BlackListIncludedTest extends 
SocketStreamerUnmarshalVulnerabilityTest {
+        /** @throws Exception If failed. */
+        @Test
+        public void test() throws Exception {
+            testExploit(false);
+        }
 
-        testExploit(false);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            return Arrays.asList("-D" + IGNITE_MARSHALLER_BLACKLIST +
+                "=" + 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath());
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testBlackListExcluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt").getPath();
-
-        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+    /** */
+    public static class BlackListExcludedTest extends 
SocketStreamerUnmarshalVulnerabilityTest {
+        /** @throws Exception If failed. */
+        @Test
+        public void test() throws Exception {
+            testExploit(true);
+        }
 
-        testExploit(true);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            return Arrays.asList("-D" + IGNITE_MARSHALLER_BLACKLIST +
+                "=" + 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_excluded.txt").getPath());
+        }
     }
 
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testBothListIncluded() throws Exception {
-        String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
+    /** */
+    public static class BothListIncludedTest extends 
SocketStreamerUnmarshalVulnerabilityTest {
+        /** @throws Exception If failed. */
+        @Test
+        public void test() throws Exception {
+            testExploit(false);
+        }
 
-        System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
-        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+        /** {@inheritDoc} */
+        @Override protected List<String> additionalRemoteJvmArgs() {
+            String path = 
U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
 
-        testExploit(false);
+            return Arrays.asList(
+                "-D" + IGNITE_MARSHALLER_BLACKLIST + "=" + path,
+                "-D" + IGNITE_MARSHALLER_WHITELIST + "=" + path
+            );
+        }
     }
 
     /**
      * @param positive Positive.
      */
-    private void testExploit(boolean positive) throws Exception {
+    void testExploit(boolean positive) throws Exception {
         try {
-            Ignite ignite = startGrid();
+            Ignite ignite = startGrid(0);
 
-            SocketStreamer<Exploit, Integer, String> sockStmr = null;
+            ignite.cache(DEFAULT_CACHE_NAME).put(1, port);
 
-            try (IgniteDataStreamer<Integer, String> stmr = 
ignite.dataStreamer(DEFAULT_CACHE_NAME)) {
-                stmr.allowOverwrite(true);
-                stmr.autoFlushFrequency(10);
+            IgniteEx rmt = startGrid(1);
 
-                sockStmr = new SocketStreamer<>();
+            
ignite.compute(ignite.cluster().forNodeId(rmt.localNode().id())).callAsync(new 
StartSocketRunnable());
 
-                sockStmr.setIgnite(ignite);
-
-                sockStmr.setStreamer(stmr);
-
-                sockStmr.setPort(port);
-
-                sockStmr.setSingleTupleExtractor(new 
StreamSingleTupleExtractor<Exploit, Integer, String>() {
-                    @Override public Map.Entry<Integer, String> 
extract(Exploit msg) {
-                        return new IgniteBiTuple<>(1, "val");
-                    }
-                });
-
-                sockStmr.start();
-
-                try (Socket sock = new Socket(InetAddress.getLocalHost(), 
port);
+            assertTrue(GridTestUtils.waitForCondition(() -> {
+                try (Socket sock = new Socket(InetAddress.getLocalHost(), 
(Integer)ignite.cache(DEFAULT_CACHE_NAME).get(1));
                      OutputStream os = new 
BufferedOutputStream(sock.getOutputStream())) {
                     Marshaller marsh = Marshallers.jdk();
 
@@ -194,26 +185,26 @@ public class SocketStreamerUnmarshalVulnerabilityTest 
extends GridCommonAbstract
                     os.write(msg.length);
 
                     os.write(msg);
+
+                    return true;
                 }
                 catch (IOException | IgniteCheckedException e) {
-                    throw new IgniteException(e);
+                    e.printStackTrace();
+                    return false;
                 }
 
-                boolean res = GridTestUtils.waitForCondition(new 
GridAbsPredicate() {
-                    @Override public boolean apply() {
-                        return SHARED.get();
-                    }
-                }, 3000L);
+            }, 10_000));
 
-                if (positive)
-                    assertTrue(res);
-                else
-                    assertFalse(res);
-            }
-            finally {
-                if (sockStmr != null)
-                    sockStmr.stop();
-            }
+            boolean res = GridTestUtils.waitForCondition(new 
GridAbsPredicate() {
+                @Override public boolean apply() {
+                    return ignite.cacheNames().contains(EXPLOIT_CACHE);
+                }
+            }, 3000L);
+
+            if (positive)
+                assertTrue(res);
+            else
+                assertFalse(res);
         }
         finally {
             stopAllGrids();
@@ -226,7 +217,42 @@ public class SocketStreamerUnmarshalVulnerabilityTest 
extends GridCommonAbstract
          * @param is Input stream.
          */
         private void readObject(ObjectInputStream is) throws 
ClassNotFoundException, IOException {
-            SHARED.set(true);
+            Ignition.localIgnite().createCache(EXPLOIT_CACHE);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override protected boolean isMultiJvm() {
+        return true;
+    }
+
+    /** */
+    private static class StartSocketRunnable implements IgniteCallable<Void> {
+        /** {@inheritDoc} */
+        @Override public Void call() throws Exception {
+            IgniteEx loc = (IgniteEx)Ignition.localIgnite();
+
+            SocketStreamer<Exploit, Integer, String> sockStmr;
+
+            try (IgniteDataStreamer<Integer, String> stmr = 
loc.dataStreamer(DEFAULT_CACHE_NAME)) {
+                stmr.allowOverwrite(true);
+                stmr.autoFlushFrequency(10);
+
+                sockStmr = new SocketStreamer<>();
+
+                sockStmr.setIgnite(loc);
+                sockStmr.setStreamer(stmr);
+                
sockStmr.setPort((Integer)loc.cache(DEFAULT_CACHE_NAME).get(1));
+                sockStmr.setSingleTupleExtractor(new 
StreamSingleTupleExtractor<Exploit, Integer, String>() {
+                    @Override public Map.Entry<Integer, String> 
extract(Exploit msg) {
+                        return new IgniteBiTuple<>(1, "val");
+                    }
+                });
+
+                sockStmr.start();
+            }
+
+            return null;
         }
     }
 }
diff --git 
a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java
 
b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java
index 4edca1efe3b..a2528c205b5 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java
@@ -74,7 +74,6 @@ public class GridTestKernalContext extends 
GridKernalContextImpl {
                     Arrays.asList(cfg.getPluginProviders()) : 
U.allPluginProviders(),
                 null,
                 null,
-                null,
                 new LongJVMPauseDetector(cfg.getIgniteInstanceName() == null ? 
"test-ignite-kernal" : cfg.getIgniteInstanceName(), log)
         );
 
diff --git 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite2.java
 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite2.java
index 7d827a4d3ac..206020d5747 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite2.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite2.java
@@ -90,7 +90,13 @@ import org.junit.runners.Suite;
     TcpDiscoverySslSelfTest.class,
     TcpDiscoverySslTrustedUntrustedTest.class,
     IgniteDiscoveryCacheReuseSelfTest.class,
-    DiscoveryUnmarshalVulnerabilityTest.class,
+    DiscoveryUnmarshalVulnerabilityTest.NoListsTest.class,
+    DiscoveryUnmarshalVulnerabilityTest.WhiteListIncludedTest.class,
+    DiscoveryUnmarshalVulnerabilityTest.WhiteListExcludedTest.class,
+    DiscoveryUnmarshalVulnerabilityTest.BlackListIncludedTest.class,
+    DiscoveryUnmarshalVulnerabilityTest.BlackListExcludedTest.class,
+    DiscoveryUnmarshalVulnerabilityTest.BothListIncludedTest.class,
+    DiscoveryUnmarshalVulnerabilityTest.ExploitDirectlyTest.class,
     FilterDataForClientNodeDiscoveryTest.class,
     IgniteMetricsOverflowTest.class,
     DiscoverySpiDataExchangeTest.class,
diff --git 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteStreamSelfTestSuite.java
 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteStreamSelfTestSuite.java
index 35565433db2..5d6a5625c05 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteStreamSelfTestSuite.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteStreamSelfTestSuite.java
@@ -28,7 +28,12 @@ import org.junit.runners.Suite;
 @RunWith(Suite.class)
 @Suite.SuiteClasses({
     SocketStreamerSelfTest.class,
-    SocketStreamerUnmarshalVulnerabilityTest.class,
+    SocketStreamerUnmarshalVulnerabilityTest.NoListsTest.class,
+    SocketStreamerUnmarshalVulnerabilityTest.WhiteListIncludedTest.class,
+    SocketStreamerUnmarshalVulnerabilityTest.WhiteListExcludedTest.class,
+    SocketStreamerUnmarshalVulnerabilityTest.BlackListIncludedTest.class,
+    SocketStreamerUnmarshalVulnerabilityTest.BlackListExcludedTest.class,
+    SocketStreamerUnmarshalVulnerabilityTest.BothListIncludedTest.class,
 })
 public class IgniteStreamSelfTestSuite {
 }
diff --git 
a/modules/json/src/main/java/org/apache/ignite/internal/jackson/IgniteObjectMapper.java
 
b/modules/json/src/main/java/org/apache/ignite/internal/jackson/IgniteObjectMapper.java
index 7d26d1c7d2e..0904fa6b96d 100644
--- 
a/modules/json/src/main/java/org/apache/ignite/internal/jackson/IgniteObjectMapper.java
+++ 
b/modules/json/src/main/java/org/apache/ignite/internal/jackson/IgniteObjectMapper.java
@@ -52,6 +52,7 @@ import 
org.apache.ignite.internal.visor.util.VisorExceptionWrapper;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.marshaller.MarshallerUtils;
 
 /**
  * Custom object mapper for HTTP REST API.
@@ -95,11 +96,7 @@ public class IgniteObjectMapper extends ObjectMapper {
 
         if (ctx != null) {
             module.addDeserializer(BinaryObject.class, new 
IgniteBinaryObjectJsonDeserializer(ctx));
-
-            IgnitePredicate<String> clsFilter = 
ctx.marshallerContext().classNameFilter();
-
-            if (clsFilter != null)
-                setDefaultTyping(new 
RestrictedTypeResolverBuilder(clsFilter).init(JsonTypeInfo.Id.CLASS, null));
+            setDefaultTyping(new 
RestrictedTypeResolverBuilder(MarshallerUtils.classNameFilter()).init(JsonTypeInfo.Id.CLASS,
 null));
         }
 
         configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
diff --git 
a/modules/thin-client/impl/src/main/java/org/apache/ignite/internal/client/thin/TcpIgniteClient.java
 
b/modules/thin-client/impl/src/main/java/org/apache/ignite/internal/client/thin/TcpIgniteClient.java
index 3aca5f9fde6..a7d06a8be4d 100644
--- 
a/modules/thin-client/impl/src/main/java/org/apache/ignite/internal/client/thin/TcpIgniteClient.java
+++ 
b/modules/thin-client/impl/src/main/java/org/apache/ignite/internal/client/thin/TcpIgniteClient.java
@@ -74,7 +74,6 @@ import 
org.apache.ignite.internal.processors.platform.client.IgniteClientExcepti
 import org.apache.ignite.internal.util.CommonUtils;
 import org.apache.ignite.internal.util.GridArgumentCheck;
 import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.logger.NullLogger;
 import org.apache.ignite.marshaller.MarshallerContext;
 import org.apache.ignite.marshaller.MarshallerUtils;
@@ -787,12 +786,15 @@ public class TcpIgniteClient implements IgniteClient {
         /** System types. */
         private final Collection<String> sysTypes = new HashSet<>();
 
+        /** JDK marshaller. */
+        private final JdkMarshaller jdkMarsh = Marshallers.jdk();
+
         /**
          * Default constructor.
          */
         public ClientMarshallerContext() {
             try {
-                
MarshallerUtils.processSystemClasses(CommonUtils.gridClassLoader(), 
sysTypes::add);
+                MarshallerUtils.processSystemClasses(sysTypes::add);
             }
             catch (IOException e) {
                 throw new IllegalStateException("Failed to initialize 
marshaller context.", e);
@@ -903,14 +905,9 @@ public class TcpIgniteClient implements IgniteClient {
             return sysTypes.contains(typeName);
         }
 
-        /** {@inheritDoc} */
-        @Override public IgnitePredicate<String> classNameFilter() {
-            return null;
-        }
-
         /** {@inheritDoc} */
         @Override public JdkMarshaller jdkMarshaller() {
-            return Marshallers.jdk();
+            return jdkMarsh;
         }
 
         /**

Reply via email to