You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2018/01/25 09:33:43 UTC

ignite git commit: ignite-6643 Marshalling improvements

Repository: ignite
Updated Branches:
  refs/heads/master ce96e4f3e -> 340569b8f


ignite-6643 Marshalling improvements


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/340569b8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/340569b8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/340569b8

Branch: refs/heads/master
Commit: 340569b8f4e14a4cb61a9407ed2d9aa4a20bdf49
Parents: ce96e4f
Author: Andrey Gura <ag...@apache.org>
Authored: Mon Jan 22 22:41:54 2018 +0300
Committer: Andrey Gura <ag...@apache.org>
Committed: Thu Jan 25 12:29:47 2018 +0300

----------------------------------------------------------------------
 .../apache/ignite/IgniteSystemProperties.java   |  60 +----
 .../org/apache/ignite/internal/ClassSet.java    | 108 +++++++++
 .../ignite/internal/GridKernalContextImpl.java  |   6 +-
 .../apache/ignite/internal/IgniteKernal.java    | 107 ++++++++-
 .../ignite/internal/MarshallerContextImpl.java  |  33 ++-
 .../GridClientOptimizedMarshaller.java          |   4 +-
 .../optimized/OptimizedMarshallerUtils.java     |   4 -
 .../optimized/OptimizedObjectInputStream.java   |   5 +-
 .../optimized/OptimizedObjectOutputStream.java  |   3 +-
 .../wal/reader/StandaloneGridKernalContext.java |   2 +-
 .../platform/utils/PlatformUtils.java           |   2 +-
 .../rest/protocols/tcp/GridTcpRestParser.java   |  15 +-
 .../rest/protocols/tcp/GridTcpRestProtocol.java |  31 +--
 .../ignite/internal/util/IgniteUtils.java       |  15 ++
 .../ignite/marshaller/MarshallerContext.java    |  14 ++
 .../ignite/marshaller/MarshallerUtils.java      |   6 +
 .../ignite/marshaller/jdk/JdkMarshaller.java    |  20 +-
 .../jdk/JdkMarshallerObjectInputStream.java     |   9 +-
 .../spi/discovery/tcp/TcpDiscoverySpi.java      |   8 +-
 .../org/apache/ignite/stream/StreamAdapter.java |   2 +-
 .../ignite/stream/socket/SocketStreamer.java    |   8 +-
 .../test/config/class_list_exploit_excluded.txt |  18 ++
 .../test/config/class_list_exploit_included.txt |  19 ++
 .../apache/ignite/internal/ClassSetTest.java    |  71 ++++++
 .../MarshallerContextLockingSelfTest.java       |   2 +-
 ...GridBinaryMarshallerCtxDisabledSelfTest.java |  12 +
 .../cache/GridCacheEntryMemorySizeSelfTest.java |  11 +-
 .../marshaller/MarshallerContextSelfTest.java   |  10 +-
 .../marshaller/MarshallerContextTestImpl.java   |   2 +-
 .../DiscoveryUnmarshalVulnerabilityTest.java    | 180 +++++++++++++++
 ...ocketStreamerUnmarshalVulnerabilityTest.java | 222 +++++++++++++++++++
 .../junits/GridTestKernalContext.java           |   3 +-
 .../ignite/testsuites/IgniteBasicTestSuite.java |   3 +
 .../IgniteSpiDiscoverySelfTestSuite.java        |   3 +
 .../testsuites/IgniteStreamSelfTestSuite.java   |   2 +
 35 files changed, 894 insertions(+), 126 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
index 9cd031d..7761292 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@ -28,7 +28,6 @@ import org.apache.ignite.cluster.ClusterGroup;
 import org.apache.ignite.configuration.DataStorageConfiguration;
 import org.apache.ignite.internal.client.GridClient;
 import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
-import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.stream.StreamTransformer;
 import org.jetbrains.annotations.Nullable;
 
@@ -222,11 +221,6 @@ public final class IgniteSystemProperties {
     public static final String IGNITE_MAX_COMPLETED_TX_COUNT = "IGNITE_MAX_COMPLETED_TX_COUNT";
 
     /**
-     * Concurrency level for all concurrent hash maps created by Ignite.
-     */
-    public static final String IGNITE_MAP_CONCURRENCY_LEVEL = "IGNITE_MAP_CONCURRENCY_LEVEL";
-
-    /**
      * Transactions that take more time, than value of this property, will be output to log
      * with warning level. {@code 0} (default value) disables warning on slow transactions.
      */
@@ -320,13 +314,6 @@ public final class IgniteSystemProperties {
     /** Ttl of removed cache entries (ms). */
     public static final String IGNITE_CACHE_REMOVED_ENTRIES_TTL = "IGNITE_CACHE_REMOVED_ENTRIES_TTL";
 
-    /** Maximum amount of concurrent updates per system thread in atomic caches in case of PRIMARY_SYNC or FULL_ASYNC
-     * write synchronization mode. If this limit is exceeded then update will be performed with FULL_SYNC
-     * synchronization mode. If value is {@code 0} then limit is unbounded.
-     */
-    public static final String IGNITE_ATOMIC_CACHE_MAX_CONCURRENT_DHT_UPDATES =
-        "IGNITE_ATOMIC_CACHE_MAX_CONCURRENT_DHT_UPDATES";
-
     /**
      * Comma separated list of addresses in format "10.100.22.100:45000,10.100.22.101:45000".
      * Makes sense only for {@link org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder}.
@@ -479,9 +466,6 @@ public final class IgniteSystemProperties {
     /** Number of cache operation retries in case of topology exceptions. */
     public static final String IGNITE_CACHE_RETRIES_COUNT = "IGNITE_CACHE_RETRIES_COUNT";
 
-    /** Number of times pending cache objects will be dumped to the log in case of partition exchange timeout. */
-    public static final String IGNITE_DUMP_PENDING_OBJECTS_THRESHOLD = "IGNITE_DUMP_PENDING_OBJECTS_THRESHOLD";
-
     /** If this property is set to {@code true} then Ignite will log thread dump in case of partition exchange timeout. */
     public static final String IGNITE_THREAD_DUMP_ON_EXCHANGE_TIMEOUT = "IGNITE_THREAD_DUMP_ON_EXCHANGE_TIMEOUT";
 
@@ -524,6 +508,12 @@ public final class IgniteSystemProperties {
     public static final String IGNITE_BINARY_MARSHALLER_USE_STRING_SERIALIZATION_VER_2 =
         "IGNITE_BINARY_MARSHALLER_USE_STRING_SERIALIZATION_VER_2";
 
+    /** Defines path to the file that contains list of classes allowed to safe deserialization.*/
+    public static final String IGNITE_MARSHALLER_WHITELIST = "IGNITE_MARSHALLER_WHITELIST";
+
+    /** Defines path to the file that contains list of classes disallowed to safe deserialization.*/
+    public static final String IGNITE_MARSHALLER_BLACKLIST = "IGNITE_MARSHALLER_BLACKLIST";
+
     /**
      * If set to {@code true}, then default selected keys set is used inside
      * {@code GridNioServer} which lead to some extra garbage generation when
@@ -689,16 +679,7 @@ public final class IgniteSystemProperties {
      */
     public static final String IGNITE_FORCE_START_JAVA7 = "IGNITE_FORCE_START_JAVA7";
 
-    /** Returns true for system properties only avoiding sending sensitive information. */
-    private static final IgnitePredicate<Map.Entry<String, String>> PROPS_FILTER = new IgnitePredicate<Map.Entry<String, String>>() {
-        @Override public boolean apply(final Map.Entry<String, String> entry) {
-            final String key = entry.getKey();
-
-            return key.startsWith("java.") || key.startsWith("os.") || key.startsWith("user.");
-        }
-    };
-
-     /**
+    /**
      * When set to {@code true}, Ignite switches to compatibility mode with versions that don't
      * support service security permissions. In this case security permissions will be ignored
      * (if they set).
@@ -740,11 +721,6 @@ public final class IgniteSystemProperties {
     public static final String IGNITE_ENABLE_FORCIBLE_NODE_KILL = "IGNITE_ENABLE_FORCIBLE_NODE_KILL";
 
     /**
-     *
-     */
-    public static final String IGNITE_WAL_ARCHIVE_COMPACT_SKIP_DELTA_RECORD = "IGNITE_WAL_ARCHIVE_COMPACT_SKIP_DELTA_RECORD";
-
-    /**
      * Tasks stealing will be started if tasks queue size per data-streamer thread exceeds this threshold.
      * <p>
      * Default value is {@code 4}.
@@ -1023,26 +999,4 @@ public final class IgniteSystemProperties {
 
         return sysProps;
     }
-
-    /**
-     * Does the same as {@link #snapshot()} but filters out
-     * possible sensitive user data.
-     *
-     * @return Snapshot of system properties.
-     */
-    @SuppressWarnings("unchecked")
-    public static Properties safeSnapshot() {
-        final Properties props = snapshot();
-
-        final Iterator<Map.Entry<Object, Object>> iter = props.entrySet().iterator();
-
-        while (iter.hasNext()) {
-            final Map.Entry entry = iter.next();
-
-            if (!PROPS_FILTER.apply(entry))
-                iter.remove();
-        }
-
-        return props;
-    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/ClassSet.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/ClassSet.java b/modules/core/src/main/java/org/apache/ignite/internal/ClassSet.java
new file mode 100644
index 0000000..400984d
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/ClassSet.java
@@ -0,0 +1,108 @@
+/*
+ * 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;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.IllegalFormatException;
+import java.util.Map;
+
+/**
+ * Set of classes represented as prefix tree.
+ * {@code *} symbol is allowed and indicates that all packages and classes are included.
+ */
+public class ClassSet {
+    /** Corresponds to {@code *} symbol. */
+    private static final Map<String, Node> ALL = Collections.emptyMap();
+
+    /** Root. */
+    private Node root = new Node();
+
+    /**
+     * Adds class name to the set.
+     *
+     * @param clsName Class name.
+     */
+    public void add(String clsName) {
+        String[] tokens = clsName.split("\\.");
+
+        Node cur = root;
+
+        for (int i = 0; i < tokens.length; i++) {
+            if (cur.children == ALL)
+                return;
+
+            if (tokens[i].equals("*")) {
+                if (i != tokens.length - 1)
+                    throw new IllegalArgumentException("Incorrect class name format.");
+
+                cur.children = ALL;
+
+                return;
+            }
+
+            if (cur.children == null)
+                cur.children = new HashMap<>();
+
+            Node n = cur.children.get(tokens[i]);
+
+            if (n == null) {
+                n = new Node();
+
+                cur.children.put(tokens[i], n);
+            }
+
+            cur = n;
+        }
+    }
+
+    /**
+     * @param clsName Class name.
+     */
+    public boolean contains(String clsName) {
+        String[] tokens = clsName.split("\\.");
+
+        Node cur = root;
+
+        for (int i = 0; i < tokens.length; i++) {
+            if (cur.children == ALL)
+                return true;
+
+            if (cur.children == null)
+                return false;
+
+            Node n = cur.children.get(tokens[i]);
+
+            if (n == null)
+                return false;
+
+            if (i == tokens.length - 1)
+                return true;
+
+            cur = n;
+        }
+
+        return false;
+    }
+
+    /** */
+    private static class Node {
+        /** Children. */
+        private Map<String, Node> children;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
----------------------------------------------------------------------
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 9a315e7..3f064fa 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
@@ -91,6 +91,7 @@ import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 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.lang.IgnitePredicate;
 import org.apache.ignite.plugin.PluginNotFoundException;
 import org.apache.ignite.plugin.PluginProvider;
 import org.apache.ignite.thread.IgniteStripedThreadPoolExecutor;
@@ -441,7 +442,8 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
         ExecutorService qryExecSvc,
         ExecutorService schemaExecSvc,
         @Nullable Map<String, ? extends ExecutorService> customExecSvcs,
-        List<PluginProvider> plugins
+        List<PluginProvider> plugins,
+        IgnitePredicate<String> clsFilter
     ) {
         assert grid != null;
         assert cfg != null;
@@ -467,7 +469,7 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
         this.schemaExecSvc = schemaExecSvc;
         this.customExecSvcs = customExecSvcs;
 
-        marshCtx = new MarshallerContextImpl(plugins);
+        marshCtx = new MarshallerContextImpl(plugins, clsFilter);
 
         try {
             spring = SPRING.create(false);

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
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 16698b5..3094963 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
@@ -17,10 +17,14 @@
 
 package org.apache.ignite.internal;
 
+import java.io.BufferedReader;
 import java.io.Externalizable;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.InvalidObjectException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
@@ -259,6 +263,8 @@ import static org.apache.ignite.internal.IgniteVersionUtils.VER;
 import static org.apache.ignite.internal.IgniteVersionUtils.VER_STR;
 import static org.apache.ignite.lifecycle.LifecycleEventType.AFTER_NODE_START;
 import static org.apache.ignite.lifecycle.LifecycleEventType.BEFORE_NODE_START;
+import static org.apache.ignite.marshaller.MarshallerUtils.CLS_NAMES_FILE;
+import static org.apache.ignite.marshaller.MarshallerUtils.JDK_CLS_NAMES_FILE;
 
 /**
  * Ignite kernal.
@@ -834,7 +840,8 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
                 qryExecSvc,
                 schemaExecSvc,
                 customExecSvcs,
-                plugins
+                plugins,
+                classNameFilter()
             );
 
             cfg.getMarshaller().setContext(ctx.marshallerContext());
@@ -1685,6 +1692,104 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
     }
 
     /**
+     * Returns class name filter for marshaller.
+     * @return Class name filter for marshaller.
+     */
+    private IgnitePredicate<String> classNameFilter() throws IgniteCheckedException {
+        ClassSet whiteList = classWhiteList();
+        ClassSet blackList = classBlackList();
+
+        return new IgnitePredicate<String>() {
+            @Override public boolean apply(String s) {
+                // Allows all primitive arrays and checks arrays' type.
+                if ((blackList != null || whiteList != null) && s.charAt(0) == '[') {
+                    if (s.charAt(1) == 'L' && s.length() > 2)
+                        s = s.substring(2, s.length() - 1);
+                    else
+                        return true;
+                }
+
+                return (blackList == null || !blackList.contains(s)) && (whiteList == null || whiteList.contains(s));
+            }
+        };
+    }
+
+    /**
+     * @return White list of classes.
+     */
+    private ClassSet classWhiteList() throws IgniteCheckedException {
+        ClassSet clsSet = null;
+
+        String fileName = IgniteSystemProperties.getString(IgniteSystemProperties.IGNITE_MARSHALLER_WHITELIST);
+
+        if (fileName != null) {
+            clsSet = new ClassSet();
+
+            addClassNames(JDK_CLS_NAMES_FILE, clsSet);
+            addClassNames(CLS_NAMES_FILE, clsSet);
+            addClassNames(fileName, clsSet);
+        }
+
+        return clsSet;
+    }
+
+    /**
+     * @return Black list of classes.
+     */
+    private ClassSet classBlackList() throws IgniteCheckedException {
+        ClassSet clsSet = null;
+
+        String blackListFileName = IgniteSystemProperties.getString(IgniteSystemProperties.IGNITE_MARSHALLER_BLACKLIST);
+
+        if (blackListFileName != null)
+            addClassNames(blackListFileName, clsSet = new ClassSet());
+
+        return clsSet;
+    }
+
+
+    /**
+     * Reads class names from resource referred by given system property name and returns set of classes.
+     * @param fileName File name containing list of classes.
+     * @param clsSet Class set for update.
+     * @return Set of classes.
+     */
+    private void addClassNames(String fileName, ClassSet clsSet) throws IgniteCheckedException {
+        InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileName);
+
+        if (is == null) {
+            try {
+                is = new FileInputStream(new File(fileName));
+            }
+            catch (FileNotFoundException e) {
+                throw new IgniteCheckedException("File " + fileName + " not found.");
+            }
+        }
+
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
+            String line;
+
+            for (int i = 1; (line = reader.readLine()) != null; i++) {
+                String s = line.trim();
+
+                if (!s.isEmpty() && s.charAt(0) != '#' && s.charAt(0) != '[') {
+                    try {
+                        clsSet.add(s);
+                    }
+                    catch (IllegalArgumentException e) {
+                        throw new IgniteCheckedException("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 " +
+                "[path=" + fileName + ']', e);
+        }
+    }
+
+    /**
      * Add helper.
      *
      * @param helper Helper.

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/MarshallerContextImpl.java
----------------------------------------------------------------------
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 08661a3..d82ab17 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
@@ -50,25 +50,23 @@ import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
 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.MarshallerContext;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
 import org.apache.ignite.plugin.PluginProvider;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
 
 import static org.apache.ignite.internal.MarshallerPlatformIds.JAVA_ID;
+import static org.apache.ignite.marshaller.MarshallerUtils.CLS_NAMES_FILE;
+import static org.apache.ignite.marshaller.MarshallerUtils.JDK_CLS_NAMES_FILE;
 
 /**
  * Marshaller context implementation.
  */
 public class MarshallerContextImpl implements MarshallerContext {
     /** */
-    private static final String CLS_NAMES_FILE = "META-INF/classnames.properties";
-
-    /** */
-    private static final String JDK_CLS_NAMES_FILE = "META-INF/classnames-jdk.properties";
-
-    /** */
     private final Map<Integer, MappedName> sysTypesMap = new HashMap<>();
 
     /** */
@@ -89,6 +87,12 @@ public class MarshallerContextImpl implements MarshallerContext {
     /** */
     private boolean clientNode;
 
+    /** Class name filter. */
+    private final IgnitePredicate<String> clsFilter;
+
+    /** JDK marshaller. */
+    private final JdkMarshaller jdkMarsh;
+
     /**
      * Marshaller mapping file store directory. {@code null} used for standard folder, in this case folder is calculated
      * from work directory. Non null value may be used to setup custom directory from outside
@@ -100,7 +104,10 @@ public class MarshallerContextImpl implements MarshallerContext {
      *
      * @param plugins Plugins.
      */
-    public MarshallerContextImpl(@Nullable Collection<PluginProvider> plugins) {
+    public MarshallerContextImpl(@Nullable Collection<PluginProvider> plugins, IgnitePredicate<String> clsFilter) {
+        this.clsFilter = clsFilter;
+        this.jdkMarsh = new JdkMarshaller(clsFilter);
+
         initializeCaches();
 
         try {
@@ -330,7 +337,7 @@ public class MarshallerContextImpl implements MarshallerContext {
         if (clsName == null)
             throw new ClassNotFoundException("Unknown type ID: " + typeId);
 
-        return U.forName(clsName, ldr);
+        return U.forName(clsName, ldr, clsFilter);
     }
 
     /** {@inheritDoc} */
@@ -385,6 +392,16 @@ public class MarshallerContextImpl implements MarshallerContext {
         return clsName;
     }
 
+    /** {@inheritDoc} */
+    @Override public IgnitePredicate<String> classNameFilter() {
+        return clsFilter;
+    }
+
+    /** {@inheritDoc} */
+    @Override public JdkMarshaller jdkMarshaller() {
+        return jdkMarsh;
+    }
+
     /**
      * @param platformId Platform id.
      * @param typeId Type id.

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
----------------------------------------------------------------------
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 257b34c..2af1841 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
@@ -117,14 +117,14 @@ public class GridClientOptimizedMarshaller implements GridClientMarshaller {
     private static class ClientMarshallerContext extends MarshallerContextImpl {
         /** */
         public ClientMarshallerContext() {
-            super(null);
+            super(null, null);
         }
 
         /**
          * @param plugins Plugins.
          */
         public ClientMarshallerContext(@Nullable List<PluginProvider> plugins) {
-            super(plugins);
+            super(plugins, null);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerUtils.java
index f9a6df9..aa4bfd6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerUtils.java
@@ -33,7 +33,6 @@ import org.apache.ignite.IgniteException;
 import org.apache.ignite.internal.util.GridUnsafe;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.marshaller.MarshallerContext;
-import org.apache.ignite.marshaller.jdk.JdkMarshaller;
 
 import static org.apache.ignite.internal.MarshallerPlatformIds.JAVA_ID;
 
@@ -152,9 +151,6 @@ class OptimizedMarshallerUtils {
     /** UTF-8 character name. */
     static final Charset UTF_8 = Charset.forName("UTF-8");
 
-    /** JDK marshaller. */
-    static final JdkMarshaller JDK_MARSH = new JdkMarshaller();
-
     static {
         long mapOff;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
index 93a6f6f..0bd7cc0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectInputStream.java
@@ -70,7 +70,6 @@ import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshalle
 import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.INT;
 import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.INT_ARR;
 import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.JDK;
-import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.JDK_MARSH;
 import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LINKED_HASH_MAP;
 import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LINKED_HASH_SET;
 import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LINKED_LIST;
@@ -227,7 +226,7 @@ class OptimizedObjectInputStream extends ObjectInputStream {
 
             case JDK:
                 try {
-                    return JDK_MARSH.unmarshal(this, clsLdr);
+                    return ctx.jdkMarshaller().unmarshal(this, clsLdr);
                 }
                 catch (IgniteCheckedException e) {
                     IOException ioEx = e.getCause(IOException.class);
@@ -338,7 +337,7 @@ class OptimizedObjectInputStream extends ObjectInputStream {
                 int typeId = readInt();
 
                 OptimizedClassDescriptor desc = typeId == 0 ?
-                    classDescriptor(clsMap, U.forName(readUTF(), clsLdr), ctx, mapper):
+                    classDescriptor(clsMap, U.forName(readUTF(), clsLdr, ctx.classNameFilter()), ctx, mapper):
                     classDescriptor(clsMap, typeId, clsLdr, ctx, mapper);
 
                 curCls = desc.describedClass();

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectOutputStream.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectOutputStream.java b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectOutputStream.java
index 092d6a4..8a323a7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectOutputStream.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedObjectOutputStream.java
@@ -47,7 +47,6 @@ import org.apache.ignite.marshaller.MarshallerContext;
 
 import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.HANDLE;
 import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.JDK;
-import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.JDK_MARSH;
 import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.NULL;
 import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.classDescriptor;
 import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.getBoolean;
@@ -185,7 +184,7 @@ class OptimizedObjectOutputStream extends ObjectOutputStream {
                 writeByte(JDK);
 
                 try {
-                    JDK_MARSH.marshal(obj, this);
+                    ctx.jdkMarshaller().marshal(obj, this);
                 }
                 catch (IgniteCheckedException e) {
                     IOException ioEx = e.getCause(IOException.class);

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
----------------------------------------------------------------------
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 908d5b7..2c1d91e 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
@@ -137,7 +137,7 @@ public class StandaloneGridKernalContext implements GridKernalContext {
             throw new IllegalStateException("Must not fail on empty providers list.", e);
         }
 
-        this.marshallerCtx = new MarshallerContextImpl(null);
+        this.marshallerCtx = new MarshallerContextImpl(null, null);
         this.cfg = prepareIgniteConfiguration();
 
         // Fake folder provided to perform processor startup on empty folder.

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformUtils.java
----------------------------------------------------------------------
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 2954a9e..12f70dd 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
@@ -857,7 +857,7 @@ public class PlatformUtils {
 
         BinaryMarshaller marsh = new BinaryMarshaller();
 
-        marsh.setContext(new MarshallerContextImpl(null));
+        marsh.setContext(new MarshallerContextImpl(null, null));
 
         ctx.configure(marsh, new IgniteConfiguration());
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestParser.java
----------------------------------------------------------------------
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 b4c8b7c..65eb3c3 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
@@ -72,7 +72,7 @@ public class GridTcpRestParser implements GridNioParser {
     private static final Charset UTF_8 = Charset.forName("UTF-8");
 
     /** JDK marshaller. */
-    private final Marshaller jdkMarshaller = new JdkMarshaller();
+    private final Marshaller marsh;
 
     /** Router client flag. */
     private final boolean routerClient;
@@ -81,7 +81,16 @@ public class GridTcpRestParser implements GridNioParser {
      * @param routerClient Router client flag.
      */
     public GridTcpRestParser(boolean routerClient) {
+        this(routerClient, new JdkMarshaller());
+    }
+
+    /**
+     * @param routerClient Router client flag.
+     * @param marsh Marshaller.
+     */
+    public GridTcpRestParser(boolean routerClient, Marshaller marsh) {
         this.routerClient = routerClient;
+        this.marsh = marsh;
     }
 
     /** {@inheritDoc} */
@@ -735,7 +744,7 @@ public class GridTcpRestParser implements GridNioParser {
         assert bytes != null;
 
         if ((flags & SERIALIZED_FLAG) != 0)
-            return U.unmarshal(jdkMarshaller, bytes, null);
+            return U.unmarshal(marsh, bytes, null);
 
         int masked = flags & 0xff00;
 
@@ -817,7 +826,7 @@ public class GridTcpRestParser implements GridNioParser {
             flags |= BYTE_ARR_FLAG;
         }
         else {
-            U.marshal(jdkMarshaller, obj, out);
+            U.marshal(marsh, obj, out);
 
             flags |= SERIALIZED_FLAG;
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestProtocol.java
----------------------------------------------------------------------
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 df0e569..0049dbc 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
@@ -44,17 +44,12 @@ import org.apache.ignite.internal.util.nio.GridNioFilter;
 import org.apache.ignite.internal.util.nio.GridNioParser;
 import org.apache.ignite.internal.util.nio.GridNioServer;
 import org.apache.ignite.internal.util.nio.GridNioServerListener;
-import org.apache.ignite.internal.util.nio.GridNioSession;
 import org.apache.ignite.internal.util.nio.ssl.GridNioSslFilter;
 import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.marshaller.Marshaller;
-import org.apache.ignite.marshaller.jdk.JdkMarshaller;
 import org.apache.ignite.plugin.PluginProvider;
 import org.apache.ignite.spi.IgnitePortProtocol;
 import org.jetbrains.annotations.Nullable;
 
-import static org.apache.ignite.internal.util.nio.GridNioSessionMetaKey.MARSHALLER;
-
 /**
  * TCP binary protocol implementation.
  */
@@ -62,9 +57,6 @@ public class GridTcpRestProtocol extends GridRestProtocolAdapter {
     /** Server. */
     private GridNioServer<GridClientMessage> srv;
 
-    /** JDK marshaller. */
-    private final Marshaller jdkMarshaller = new JdkMarshaller();
-
     /** NIO server listener. */
     private GridTcpRestNioListener lsnr;
 
@@ -73,27 +65,6 @@ public class GridTcpRestProtocol extends GridRestProtocolAdapter {
         super(ctx);
     }
 
-    /**
-     * @return JDK marshaller.
-     */
-    Marshaller jdkMarshaller() {
-        return jdkMarshaller;
-    }
-
-    /**
-     * Returns marshaller.
-     *
-     * @param ses Session.
-     * @return Marshaller.
-     */
-    GridClientMarshaller marshaller(GridNioSession ses) {
-        GridClientMarshaller marsh = ses.meta(MARSHALLER.ordinal());
-
-        assert marsh != null;
-
-        return marsh;
-    }
-
     /** {@inheritDoc} */
     @Override public String name() {
         return "TCP binary";
@@ -110,7 +81,7 @@ public class GridTcpRestProtocol extends GridRestProtocolAdapter {
 
         lsnr = new GridTcpRestNioListener(log, this, hnd, ctx);
 
-        GridNioParser parser = new GridTcpRestParser(false);
+        GridNioParser parser = new GridTcpRestParser(false, ctx.marshallerContext().jdkMarshaller());
 
         try {
             host = resolveRestTcpHost(ctx.config());

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
index 0f6a41a..238030a 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
@@ -8532,6 +8532,18 @@ public abstract class IgniteUtils {
      * @throws ClassNotFoundException If class not found.
      */
     public static Class<?> forName(String clsName, @Nullable ClassLoader ldr) throws ClassNotFoundException {
+        return U.forName(clsName, ldr, null);
+    }
+
+    /**
+     * Gets class for provided name. Accepts primitive types names.
+     *
+     * @param clsName Class name.
+     * @param ldr Class loader.
+     * @return Class.
+     * @throws ClassNotFoundException If class not found.
+     */
+    public static Class<?> forName(String clsName, @Nullable ClassLoader ldr, IgnitePredicate<String> clsFilter) throws ClassNotFoundException {
         assert clsName != null;
 
         Class<?> cls = primitiveMap.get(clsName);
@@ -8558,6 +8570,9 @@ public abstract class IgniteUtils {
         cls = ldrMap.get(clsName);
 
         if (cls == null) {
+            if (clsFilter != null && !clsFilter.apply(clsName))
+                throw new RuntimeException("Deserialization of class " + clsName + " is disallowed.");
+
             Class old = ldrMap.putIfAbsent(clsName, cls = Class.forName(clsName, true, ldr));
 
             if (old != null)

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java b/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java
index 8d6cd77..987e999 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerContext.java
@@ -18,6 +18,8 @@
 package org.apache.ignite.marshaller;
 
 import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
 
 /**
  * Marshaller context.
@@ -83,4 +85,16 @@ public interface MarshallerContext {
      * @return {@code true} if the type is a system one, {@code false} otherwise.
      */
     public boolean isSystemType(String typeName);
+
+    /**
+     * Returns class name filter.
+     *
+     * @return Class name filter.
+     */
+    public IgnitePredicate<String> classNameFilter();
+
+    /**
+     * Returns JDK marshaller instance.
+     */
+    public JdkMarshaller jdkMarshaller();
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java b/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
index ad63702..bec1f57 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
@@ -25,6 +25,12 @@ import org.jetbrains.annotations.Nullable;
  * Utility marshaller methods.
  */
 public class MarshallerUtils {
+    /** Jdk class names file. */
+    public static final String JDK_CLS_NAMES_FILE = "META-INF/classnames-jdk.properties";
+
+    /** Class names file. */
+    public static final String CLS_NAMES_FILE = "META-INF/classnames.properties";
+
     /** Job sender node version. */
     private static final ThreadLocal<IgniteProductVersion> JOB_SND_NODE_VER = new ThreadLocal<>();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java b/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java
index 6759c40..ae4033b 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshaller.java
@@ -27,6 +27,7 @@ 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.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.marshaller.AbstractNodeNameAwareMarshaller;
 import org.jetbrains.annotations.Nullable;
 
@@ -67,6 +68,23 @@ import org.jetbrains.annotations.Nullable;
  * For information about Spring framework visit <a href="http://www.springframework.org/">www.springframework.org</a>
  */
 public class JdkMarshaller extends AbstractNodeNameAwareMarshaller {
+    /** Class name filter. */
+    private final IgnitePredicate<String> clsFilter;
+
+    /**
+     * Default constructor.
+     */
+    public JdkMarshaller() {
+        this(null);
+    }
+
+    /**
+     * @param clsFilter Class name filter.
+     */
+    public JdkMarshaller(IgnitePredicate<String> clsFilter) {
+        this.clsFilter = clsFilter;
+    }
+
     /** {@inheritDoc} */
     @Override protected void marshal0(@Nullable Object obj, OutputStream out) throws IgniteCheckedException {
         assert out != null;
@@ -116,7 +134,7 @@ public class JdkMarshaller extends AbstractNodeNameAwareMarshaller {
         ObjectInputStream objIn = null;
 
         try {
-            objIn = new JdkMarshallerObjectInputStream(new JdkMarshallerInputStreamWrapper(in), clsLdr);
+            objIn = new JdkMarshallerObjectInputStream(new JdkMarshallerInputStreamWrapper(in), clsLdr, clsFilter);
 
             return (T)objIn.readObject();
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java b/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
index 03256e0..d9fdd3d 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/jdk/JdkMarshallerObjectInputStream.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectStreamClass;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgnitePredicate;
 
 /**
  * This class defines custom JDK object input stream.
@@ -30,17 +31,21 @@ 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.
      * @throws IOException If initialization failed.
      */
-    JdkMarshallerObjectInputStream(InputStream in, ClassLoader clsLdr) throws IOException {
+    JdkMarshallerObjectInputStream(InputStream in, ClassLoader clsLdr, IgnitePredicate<String> clsFilter) throws IOException {
         super(in);
 
         assert clsLdr != null;
 
         this.clsLdr = clsLdr;
+        this.clsFilter = clsFilter;
 
         enableResolveObject(true);
     }
@@ -51,7 +56,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 U.forName(desc.getName(), clsLdr);
+        return U.forName(desc.getName(), clsLdr, clsFilter);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
index 713bbab..51c5adf 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
@@ -55,6 +55,7 @@ import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.configuration.AddressResolver;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
+import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.X;
@@ -333,7 +334,7 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter implements DiscoverySpi {
     protected volatile long gridStartTime;
 
     /** Marshaller. */
-    private final Marshaller marsh = new JdkMarshaller();
+    private Marshaller marsh;
 
     /** Statistics. */
     protected final TcpDiscoveryStatistics stats = new TcpDiscoveryStatistics();
@@ -551,6 +552,11 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter implements DiscoverySpi {
         if (ignite != null) {
             setLocalAddress(ignite.configuration().getLocalHost());
             setAddressResolver(ignite.configuration().getAddressResolver());
+
+            if (ignite instanceof IgniteKernal) // IgniteMock instance can be injected from tests.
+                marsh = ((IgniteKernal)ignite).context().marshallerContext().jdkMarshaller();
+            else
+                marsh = new JdkMarshaller();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java b/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java
index 3f1dfad..49f0c15 100644
--- a/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java
@@ -46,7 +46,7 @@ public abstract class StreamAdapter<T, K, V> {
     private IgniteDataStreamer<K, V> stmr;
 
     /** Ignite. */
-    private Ignite ignite;
+    protected Ignite ignite;
 
     /**
      * Empty constructor.

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/main/java/org/apache/ignite/stream/socket/SocketStreamer.java
----------------------------------------------------------------------
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 f45423b..1a68206 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,6 +24,7 @@ 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;
@@ -38,6 +39,7 @@ import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.marshaller.Marshaller;
 import org.apache.ignite.marshaller.MarshallerUtils;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
 import org.apache.ignite.stream.StreamAdapter;
 import org.apache.ignite.stream.StreamTupleExtractor;
 import org.jetbrains.annotations.Nullable;
@@ -217,7 +219,7 @@ public class SocketStreamer<T, K, V> extends StreamAdapter<T, K, V> {
     /**
      * Converts message to Java object using Jdk marshaller.
      */
-    private static class DefaultConverter<T> implements SocketMessageConverter<T> {
+    private class DefaultConverter<T> implements SocketMessageConverter<T> {
         /** Marshaller. */
         private final Marshaller marsh;
 
@@ -227,7 +229,9 @@ public class SocketStreamer<T, K, V> extends StreamAdapter<T, K, V> {
          * @param igniteInstanceName Ignite instance name.
          */
         private DefaultConverter(@Nullable String igniteInstanceName) {
-            marsh = MarshallerUtils.jdkMarshaller(igniteInstanceName);
+            marsh = new JdkMarshaller(((IgniteKernal)ignite).context().marshallerContext().classNameFilter());
+
+            MarshallerUtils.setNodeName(marsh, igniteInstanceName);
         }
 
         /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/config/class_list_exploit_excluded.txt
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/class_list_exploit_excluded.txt b/modules/core/src/test/config/class_list_exploit_excluded.txt
new file mode 100644
index 0000000..d2657e8
--- /dev/null
+++ b/modules/core/src/test/config/class_list_exploit_excluded.txt
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+# Intentionally empty.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/config/class_list_exploit_included.txt
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/class_list_exploit_included.txt b/modules/core/src/test/config/class_list_exploit_included.txt
new file mode 100644
index 0000000..9a07d54
--- /dev/null
+++ b/modules/core/src/test/config/class_list_exploit_included.txt
@@ -0,0 +1,19 @@
+#
+# 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.spi.discovery.tcp.DiscoveryUnmarshalVulnerabilityTest$Exploit
+org.apache.ignite.stream.socket.SocketStreamerUnmarshalVulnerabilityTest$Exploit
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/internal/ClassSetTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/ClassSetTest.java b/modules/core/src/test/java/org/apache/ignite/internal/ClassSetTest.java
new file mode 100644
index 0000000..c51957a
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/ClassSetTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link ClassSet} class.
+ */
+public class ClassSetTest extends TestCase {
+    /**
+     * @throws Exception If failed.
+     */
+    public void testAddAndContains() throws Exception {
+        ClassSet clsSet = new ClassSet();
+
+        clsSet.add("org.apache.ignite.Ignite");
+
+        assertTrue(clsSet.contains("org.apache.ignite.Ignite"));
+        assertFalse(clsSet.contains("org.apache.ignite.NotIgnite"));
+        assertFalse(clsSet.contains("org.apache.Ignite"));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testAddWithMaskAndContains() throws Exception {
+        ClassSet clsSet = new ClassSet();
+
+        clsSet.add("org.apache.ignite.*");
+
+        assertTrue(clsSet.contains("org.apache.ignite.Ignite"));
+        assertTrue(clsSet.contains("org.apache.ignite.NotIgnite"));
+        assertFalse(clsSet.contains("org.apache.Ignite"));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testReduceOnAddWithMask() throws Exception {
+        ClassSet clsSet = new ClassSet();
+
+        clsSet.add("org.apache.ignite.Ignite");
+        clsSet.add("org.apache.ignite.Ignition");
+
+        assertTrue(clsSet.contains("org.apache.ignite.Ignite"));
+        assertTrue(clsSet.contains("org.apache.ignite.Ignition"));
+        assertFalse(clsSet.contains("org.apache.ignite.NotIgnite"));
+
+        clsSet.add("org.apache.ignite.*");
+
+        assertTrue(clsSet.contains("org.apache.ignite.Ignite"));
+        assertTrue(clsSet.contains("org.apache.ignite.Ignition"));
+        assertTrue(clsSet.contains("org.apache.ignite.NotIgnite"));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/internal/MarshallerContextLockingSelfTest.java
----------------------------------------------------------------------
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 522b941..f31a56d 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
@@ -140,7 +140,7 @@ public class MarshallerContextLockingSelfTest extends GridCommonAbstractTest {
         public void executeTest(GridTestLog4jLogger log, GridKernalContext ctx) throws Exception {
             counter.incrementAndGet();
 
-            MarshallerContextImpl marshallerContext = new MarshallerContextImpl(null);
+            MarshallerContextImpl marshallerContext = new MarshallerContextImpl(null, null);
             marshallerContext.onMarshallerProcessorStarted(ctx, null);
 
             MarshallerMappingItem item = new MarshallerMappingItem(JAVA_ID, 1, String.class.getName());

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryMarshallerCtxDisabledSelfTest.java
----------------------------------------------------------------------
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 35aa9b9..bb7c65d 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,8 +29,10 @@ import org.apache.ignite.binary.BinaryWriter;
 import org.apache.ignite.binary.Binarylizable;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.logger.NullLogger;
 import org.apache.ignite.marshaller.MarshallerContext;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 
 /**
@@ -122,6 +124,16 @@ public class GridBinaryMarshallerCtxDisabledSelfTest extends GridCommonAbstractT
         @Override public boolean isSystemType(String typeName) {
             return false;
         }
+
+        /** {@inheritDoc} */
+        @Override public IgnitePredicate<String> classNameFilter() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public JdkMarshaller jdkMarshaller() {
+            return new JdkMarshaller();
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheEntryMemorySizeSelfTest.java
----------------------------------------------------------------------
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 f18afb2..8092d9f 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
@@ -31,9 +31,10 @@ 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.internal.marshaller.optimized.OptimizedMarshaller;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
@@ -166,6 +167,14 @@ public class GridCacheEntryMemorySizeSelfTest extends GridCommonAbstractTest {
             @Override public boolean isSystemType(String typeName) {
                 return false;
             }
+
+            @Override public IgnitePredicate<String> classNameFilter() {
+                return null;
+            }
+
+            @Override public JdkMarshaller jdkMarshaller() {
+                return new JdkMarshaller();
+            }
         });
 
         return marsh;

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextSelfTest.java
----------------------------------------------------------------------
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 9df56ec..da474df 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
@@ -72,7 +72,7 @@ public class MarshallerContextSelfTest extends GridCommonAbstractTest {
      * @throws Exception If failed.
      */
     public void testClassName() throws Exception {
-        MarshallerContextImpl marshCtx = new MarshallerContextImpl(null);
+        MarshallerContextImpl marshCtx = new MarshallerContextImpl(null, null);
 
         marshCtx.onMarshallerProcessorStarted(ctx, null);
 
@@ -99,7 +99,7 @@ public class MarshallerContextSelfTest extends GridCommonAbstractTest {
     public void testMultiplatformMappingsCollecting() throws Exception {
         String nonJavaClassName = "random.platform.Mapping";
 
-        MarshallerContextImpl marshCtx = new MarshallerContextImpl(null);
+        MarshallerContextImpl marshCtx = new MarshallerContextImpl(null, null);
 
         marshCtx.onMarshallerProcessorStarted(ctx, null);
 
@@ -157,7 +157,7 @@ public class MarshallerContextSelfTest extends GridCommonAbstractTest {
      */
     public void testOnUpdated() throws Exception {
         File workDir = U.resolveWorkDirectory(U.defaultWorkDirectory(), "marshaller", false);
-        MarshallerContextImpl ctx = new MarshallerContextImpl(null);
+        MarshallerContextImpl ctx = new MarshallerContextImpl(null, null);
 
         ctx.onMarshallerProcessorStarted(this.ctx, null);
 
@@ -188,7 +188,7 @@ public class MarshallerContextSelfTest extends GridCommonAbstractTest {
      * if platform ids passed to marshaller cache were not sequential (like 0, 2).
      */
     public void testCacheStructure0() throws Exception {
-        MarshallerContextImpl ctx = new MarshallerContextImpl(null);
+        MarshallerContextImpl ctx = new MarshallerContextImpl(null, null);
 
         ctx.onMarshallerProcessorStarted(this.ctx, null);
 
@@ -221,7 +221,7 @@ public class MarshallerContextSelfTest extends GridCommonAbstractTest {
      * if platform ids passed to marshaller context were sequential.
      */
     public void testCacheStructure1() throws Exception {
-        MarshallerContextImpl ctx = new MarshallerContextImpl(null);
+        MarshallerContextImpl ctx = new MarshallerContextImpl(null, null);
 
         ctx.onMarshallerProcessorStarted(this.ctx, null);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java
----------------------------------------------------------------------
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 0a59bba..2d6383c 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);
+        super(plugins, null);
 
         this.excluded = excluded;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/DiscoveryUnmarshalVulnerabilityTest.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..448c9af
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/DiscoveryUnmarshalVulnerabilityTest.java
@@ -0,0 +1,180 @@
+/*
+ * 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.spi.discovery.tcp;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.ignite.IgniteCheckedException;
+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.marshaller.jdk.JdkMarshaller;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+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.
+ */
+public class DiscoveryUnmarshalVulnerabilityTest extends GridCommonAbstractTest {
+    /** Marshaller. */
+    private static final JdkMarshaller MARSH = new JdkMarshaller();
+
+    /** Shared value. */
+    private static final AtomicBoolean SHARED = new AtomicBoolean();
+
+    /** {@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.
+     */
+    public void testNoLists() throws Exception {
+        testExploit(true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    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);
+
+        testExploit(true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    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);
+
+        testExploit(false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    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);
+
+        testExploit(false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    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);
+
+        testExploit(true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testBothListIncluded() throws Exception {
+        String path = U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
+
+        System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
+        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+
+        testExploit(false);
+    }
+
+    /**
+     * @param positive Positive.
+     */
+    private void testExploit(boolean positive) throws Exception {
+        try {
+            startGrid();
+
+            attack(marshal(new Exploit()));
+
+            boolean res = GridTestUtils.waitForCondition(new GridAbsPredicate() {
+                @Override public boolean apply() {
+                    return SHARED.get();
+                }
+            }, 3000L);
+
+            if (positive)
+                assertTrue(res);
+            else
+                assertFalse(res);
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     * @param obj Object.
+     */
+    private static byte[] marshal(Object obj) throws IgniteCheckedException {
+        return MARSH.marshal(obj);
+    }
+
+    /**
+     * @param data Data.
+     */
+    private void attack(byte[] data) throws IOException {
+        InetAddress addr = InetAddress.getLoopbackAddress();
+
+        try (
+            Socket sock = new Socket(addr, 47500);
+            OutputStream oos = new BufferedOutputStream(sock.getOutputStream())
+        ) {
+            oos.write(U.IGNITE_HEADER);
+            oos.write(data);
+        }
+    }
+
+    /** */
+    private static class Exploit implements Serializable {
+        /**
+         * @param is Input stream.
+         */
+        private void readObject(ObjectInputStream is) throws ClassNotFoundException, IOException {
+            SHARED.set(true);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/stream/socket/SocketStreamerUnmarshalVulnerabilityTest.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..dadc5b6
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/stream/socket/SocketStreamerUnmarshalVulnerabilityTest.java
@@ -0,0 +1,222 @@
+/*
+ * 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.stream.socket;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+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.configuration.IgniteConfiguration;
+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.lang.IgniteBiTuple;
+import org.apache.ignite.marshaller.Marshaller;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
+import org.apache.ignite.stream.StreamSingleTupleExtractor;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+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.
+ */
+public class SocketStreamerUnmarshalVulnerabilityTest extends GridCommonAbstractTest {
+    /** Shared value. */
+    private static final AtomicBoolean SHARED = new AtomicBoolean();
+
+    /** Port. */
+    private static int port;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        try (ServerSocket sock = new ServerSocket(0)) {
+            port = sock.getLocalPort();
+        }
+
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        cfg.setCacheConfiguration(defaultCacheConfiguration());
+
+        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.
+     */
+    public void testNoLists() throws Exception {
+        testExploit(true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    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);
+
+        testExploit(true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    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);
+
+        testExploit(false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    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);
+
+        testExploit(false);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    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);
+
+        testExploit(true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testBothListIncluded() throws Exception {
+        String path = U.resolveIgnitePath("modules/core/src/test/config/class_list_exploit_included.txt").getPath();
+
+        System.setProperty(IGNITE_MARSHALLER_WHITELIST, path);
+        System.setProperty(IGNITE_MARSHALLER_BLACKLIST, path);
+
+        testExploit(false);
+    }
+
+    /**
+     * @param positive Positive.
+     */
+    private void testExploit(boolean positive) throws Exception {
+        try {
+            Ignite ignite = startGrid();
+
+            SocketStreamer<Exploit, Integer, String> sockStmr = null;
+
+            try (IgniteDataStreamer<Integer, String> stmr = ignite.dataStreamer(DEFAULT_CACHE_NAME)) {
+                stmr.allowOverwrite(true);
+                stmr.autoFlushFrequency(10);
+
+                sockStmr = new SocketStreamer<>();
+
+                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);
+                     OutputStream os = new BufferedOutputStream(sock.getOutputStream())) {
+                    Marshaller marsh = new JdkMarshaller();
+
+                    byte[] msg = marsh.marshal(new Exploit());
+
+                    os.write(msg.length >>> 24);
+                    os.write(msg.length >>> 16);
+                    os.write(msg.length >>> 8);
+                    os.write(msg.length);
+
+                    os.write(msg);
+                }
+                catch (IOException | IgniteCheckedException e) {
+                    throw new IgniteException(e);
+                }
+
+                boolean res = GridTestUtils.waitForCondition(new GridAbsPredicate() {
+                    @Override public boolean apply() {
+                        return SHARED.get();
+                    }
+                }, 3000L);
+
+                if (positive)
+                    assertTrue(res);
+                else
+                    assertFalse(res);
+            }
+            finally {
+                if (sockStmr != null)
+                    sockStmr.stop();
+            }
+        }
+        finally {
+                stopAllGrids();
+        }
+    }
+
+    /** */
+    private static class Exploit implements Serializable {
+        /**
+         * @param is Input stream.
+         */
+        private void readObject(ObjectInputStream is) throws ClassNotFoundException, IOException {
+            SHARED.set(true);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridTestKernalContext.java
----------------------------------------------------------------------
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 6b39faa..5b85385 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
@@ -78,7 +78,8 @@ public class GridTestKernalContext extends GridKernalContextImpl {
                 null,
                 null,
                 null,
-                U.allPluginProviders()
+                U.allPluginProviders(),
+                null
         );
 
         GridTestUtils.setFieldValue(grid(), "cfg", config());

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
index 1b4e2da..9fee224 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBasicTestSuite.java
@@ -20,6 +20,7 @@ package org.apache.ignite.testsuites;
 import java.util.Set;
 import junit.framework.TestSuite;
 import org.apache.ignite.GridSuppressedExceptionSelfTest;
+import org.apache.ignite.internal.ClassSetTest;
 import org.apache.ignite.internal.ClusterGroupHostsSelfTest;
 import org.apache.ignite.internal.ClusterGroupSelfTest;
 import org.apache.ignite.internal.GridFailFastNodeFailureDetectionSelfTest;
@@ -191,6 +192,8 @@ public class IgniteBasicTestSuite extends TestSuite {
 
         suite.addTestSuite(GridCleanerTest.class);
 
+        suite.addTestSuite(ClassSetTest.class);
+
         return suite;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java
index 626875c..6e51c36 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java
@@ -21,6 +21,7 @@ import junit.framework.TestSuite;
 import org.apache.ignite.spi.GridTcpSpiForwardingSelfTest;
 import org.apache.ignite.spi.discovery.AuthenticationRestartTest;
 import org.apache.ignite.spi.discovery.IgniteDiscoveryCacheReuseSelfTest;
+import org.apache.ignite.spi.discovery.tcp.DiscoveryUnmarshalVulnerabilityTest;
 import org.apache.ignite.spi.discovery.tcp.IgniteClientConnectTest;
 import org.apache.ignite.spi.discovery.tcp.IgniteClientReconnectMassiveShutdownTest;
 import org.apache.ignite.spi.discovery.tcp.TcpClientDiscoveryMarshallerCheckSelfTest;
@@ -111,6 +112,8 @@ public class IgniteSpiDiscoverySelfTestSuite extends TestSuite {
         // Disco cache reuse.
         suite.addTest(new TestSuite(IgniteDiscoveryCacheReuseSelfTest.class));
 
+        suite.addTest(new TestSuite(DiscoveryUnmarshalVulnerabilityTest.class));
+
         return suite;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/340569b8/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteStreamSelfTestSuite.java
----------------------------------------------------------------------
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 d7c677c..9eac277 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
@@ -19,6 +19,7 @@ package org.apache.ignite.testsuites;
 
 import junit.framework.TestSuite;
 import org.apache.ignite.stream.socket.SocketStreamerSelfTest;
+import org.apache.ignite.stream.socket.SocketStreamerUnmarshalVulnerabilityTest;
 
 /**
  * Stream test suite.
@@ -32,6 +33,7 @@ public class IgniteStreamSelfTestSuite extends TestSuite {
         TestSuite suite = new TestSuite("Ignite Stream Test Suite");
 
         suite.addTest(new TestSuite(SocketStreamerSelfTest.class));
+        suite.addTest(new TestSuite(SocketStreamerUnmarshalVulnerabilityTest.class));
 
         return suite;
     }