This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch 2.0.X in repository https://gitbox.apache.org/repos/asf/mina.git
commit 833f3db173526e3d25f053cf81e37053b0466f2a Author: emmanuel lecharny <[email protected]> AuthorDate: Sat Jun 20 15:46:54 2026 +0200 Applied the fix for the CVE-2026-47065 that wasn't back ported by mistake --- .../apache/mina/core/buffer/AbstractIoBuffer.java | 26 +++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/mina-core/src/main/java/org/apache/mina/core/buffer/AbstractIoBuffer.java b/mina-core/src/main/java/org/apache/mina/core/buffer/AbstractIoBuffer.java index 0baf9db3d..771885caf 100644 --- a/mina-core/src/main/java/org/apache/mina/core/buffer/AbstractIoBuffer.java +++ b/mina-core/src/main/java/org/apache/mina/core/buffer/AbstractIoBuffer.java @@ -28,6 +28,7 @@ import java.io.ObjectStreamClass; import java.io.OutputStream; import java.io.Serializable; import java.io.StreamCorruptedException; +import java.lang.reflect.Proxy; import java.nio.BufferOverflowException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; @@ -2220,6 +2221,30 @@ public abstract class AbstractIoBuffer extends IoBuffer { return super.resolveClass(desc); } } + + + @Override + protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException { + Class<?>[] classes = new Class<?>[interfaces.length]; + int i = 0; + + for (String interfaceName : interfaces) { + // Apply the acceptMatchers filter to EVERY proxy interface name before + // any Class.forName() call. The JDK default resolveProxyClass() bypasses + // resolveClass()/readClassDescriptor() entirely, so without this override + // an attacker can deserialize a java.lang.reflect.Proxy implementing + // arbitrary interfaces regardless of the configured allow-list. + if (!acceptMatchers.stream().anyMatch(m -> m.matches(interfaceName))) { + throw new ClassNotFoundException("Interface not in accept list " + interfaceName); + } + + // Use Class.forName(name, false, loader) - initialize=false - and load via + // the configured classLoader, NOT latestUserDefinedLoader(). + classes[i++] = Class.forName(interfaceName, false, classLoader); + } + + return Proxy.getProxyClass(classLoader, classes); + } }) { return in.readObject(); } catch (IOException e) { @@ -2251,7 +2276,6 @@ public abstract class AbstractIoBuffer extends IoBuffer { } super.writeClassDescriptor(desc); - } }) { out.writeObject(o);
