From c7ee2295540d1613e8b3e3803415d888ef74bcb3 Mon Sep 17 00:00:00 2001 From: Vlad Rozov Date: Fri, 18 Jun 2021 14:24:23 -0700 Subject: [PATCH] Replace opensearch class names with opendistro class names during serialization and restore them back during deserialization --- .../security/support/Base64Helper.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/main/java/org/opensearch/security/support/Base64Helper.java b/src/main/java/org/opensearch/security/support/Base64Helper.java index aaf0da2197..5b7f7d8ba0 100644 --- a/src/main/java/org/opensearch/security/support/Base64Helper.java +++ b/src/main/java/org/opensearch/security/support/Base64Helper.java @@ -31,6 +31,9 @@ package org.opensearch.security.support; import com.amazon.dlic.auth.ldap.LdapUser; +import org.apache.commons.lang3.SerializationUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.ldaptive.AbstractLdapBean; import org.ldaptive.LdapAttribute; import org.ldaptive.LdapEntry; @@ -46,6 +49,7 @@ import java.io.ObjectStreamClass; import java.io.OutputStream; import java.io.Serializable; +import java.lang.reflect.Field; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; @@ -70,6 +74,7 @@ import com.google.common.io.BaseEncoding; public class Base64Helper { + private static final Logger logger = LogManager.getLogger(Base64Helper.class); private static final Set> SAFE_CLASSES = ImmutableSet.of( String.class, @@ -138,6 +143,7 @@ static ObjectOutputStream create(ByteArrayOutputStream out) throws IOException { private SafeObjectOutputStream(OutputStream out) throws IOException { super(out); + //useProtocolVersion(PROTOCOL_VERSION_2); SecurityManager sm = System.getSecurityManager(); if (sm != null) { @@ -149,6 +155,24 @@ private SafeObjectOutputStream(OutputStream out) throws IOException { ); } + @Override + protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException { + if (desc.getName().equals(User.class.getName())) { + final Field name; + try { + desc = SerializationUtils.clone(desc); + name = desc.getClass().getDeclaredField("name"); + name.setAccessible(true); + name.set(desc, "com.amazon.opendistroforelasticsearch.security.user.User"); + logger.warn("Changed desc {}", desc); + } catch (ReflectiveOperationException e) { + logger.error("Failed to change desc {} name", desc, e); + } + //desc = ObjectStreamClass.lookup(com.amazon.opendistroforelasticsearch.security.user.User.class); + } + super.writeClassDescriptor(desc); + } + @Override protected Object replaceObject(Object obj) throws IOException { Class clazz = obj.getClass(); @@ -202,5 +226,17 @@ protected Class resolveClass(ObjectStreamClass desc) throws IOException, Clas throw new InvalidClassException("Unauthorized deserialization attempt ", clazz.getName()); } + + @Override + protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { + ObjectStreamClass desc = super.readClassDescriptor(); + + if (desc.getName().equals("com.amazon.opendistroforelasticsearch.security.user.User")) { + desc = ObjectStreamClass.lookup(org.opensearch.security.user.User.class); + logger.warn("replaced class desc {}", desc); + } + + return desc; + } } }