From 4e81640868096321627deb064b3f63e48c9a9705 Mon Sep 17 00:00:00 2001 From: nickl- Date: Fri, 27 Oct 2017 07:55:08 +0200 Subject: [PATCH] Add caller class checking. The only thing remotely inforceable is caller class checking. You cannot bypass an exception with setAccesible. Oracle went and removed Reflection.getCallerClass() completely in favour of StackWalker. At least we can share the SecurityManage ClassContext, SecurityActions seems the appropriate venue for our stack trace peek to support the older versions --- .../javassist/util/proxy/DefineClassHelper.java | 15 +++++++++++++++ .../javassist/util/proxy/SecurityActions.java | 9 ++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/javassist/util/proxy/DefineClassHelper.java b/src/main/javassist/util/proxy/DefineClassHelper.java index 208a6f0c..b47f3b59 100644 --- a/src/main/javassist/util/proxy/DefineClassHelper.java +++ b/src/main/javassist/util/proxy/DefineClassHelper.java @@ -63,9 +63,14 @@ public class DefineClassHelper } } } + private final StackWalker stack = StackWalker + .getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); private final ReferencedUnsafe sunMiscUnsafe = getReferencedUnsafe(); private final ReferencedUnsafe getReferencedUnsafe() { + if (null != SecuredPrivileged.JAVA_9 + && stack.getCallerClass() != this.getClass()) + throw new IllegalAccessError("Access denied for caller."); try { Object usf = SecurityActions.getSunMiscUnsafeAnonymously(); MethodHandle meth = SecurityActions.getMethodHandle(ClassLoader.class, @@ -91,9 +96,13 @@ public class DefineClassHelper } }, JAVA_7 { + private final SecurityActions stack = SecurityActions.stack; private final MethodHandle defineClass = getDefineClassMethodHandle(); private final MethodHandle getDefineClassMethodHandle() { + if (null != SecuredPrivileged.JAVA_7 + && stack.getCallerClass() != this.getClass()) + throw new IllegalAccessError("Access denied for caller."); try { return SecurityActions.getMethodHandle(ClassLoader.class, "defineClass", new Class[] { @@ -109,6 +118,8 @@ public class DefineClassHelper protected Class defineClass(String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain) throws ClassFormatError { + if (stack.getCallerClass() != DefineClassHelper.class) + throw new IllegalAccessError("Access denied for caller."); try { return (Class) defineClass.invokeWithArguments( loader, name, b, off, len, protectionDomain); @@ -121,7 +132,11 @@ public class DefineClassHelper }, JAVA_OTHER { private final Method defineClass = getDefineClassMethod(); + private final SecurityActions stack = SecurityActions.stack; private final Method getDefineClassMethod() { + if (null != SecuredPrivileged.JAVA_OTHER + && stack.getCallerClass() != this.getClass()) + throw new IllegalAccessError("Access denied for caller."); try { return SecurityActions.getDeclaredMethod(ClassLoader.class, "defineClass", new Class[] { diff --git a/src/main/javassist/util/proxy/SecurityActions.java b/src/main/javassist/util/proxy/SecurityActions.java index ce0b5fa6..4bc10a8a 100755 --- a/src/main/javassist/util/proxy/SecurityActions.java +++ b/src/main/javassist/util/proxy/SecurityActions.java @@ -25,8 +25,15 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; +class SecurityActions extends SecurityManager +{ + public static final SecurityActions stack = new SecurityActions(); + public Class getCallerClass() + { + return getClassContext()[2]; + } + -class SecurityActions { static Method[] getDeclaredMethods(final Class clazz) { if (System.getSecurityManager() == null) -- 2.39.5