Indeed if giving access to arbitrary Class<?> is going to introduce such headaches as exposing sun.* and trying to support arbitrary class loaders then Ralph has the right point. It's also an example of the advantages or mirrors that Gilad is talking about here:http://gbracha.blogspot.com/2010/03/through-looking-glass-darkly.html
So how about replace Class<?> getDeclaringClass() With DeclaringType getDeclaringType() Where DeclaringType is package java.lang.reflect( public interface DeclaringType extends Type { public ClassLoader getClassLoader() throws SecurityException; public String getName(); public ProtectionDomain getProductionDomain() throws SecurityException; public Package getPackage(); For convenience java.lang.Class could implement this interface but security sensitive contexts could return a much more limited type when appropriate. On Sep 3, 2013, at 3:45 PM, Ralph Goers <ralph.go...@dslextreme.com> wrote: > In Log4j's case the information we want from each StackTraceFrame is: > > a) the class name, > b) the jar or directory where the class resided. > c) the version of the jar. > d) the ClassLoader associated with the class. > > Having the actually Class object allows us to get all of this information but > if it is deemed more secure to just include all the individual information > instead that would be fine. > > Ralph > > On Sep 3, 2013, at 12:21 PM, Mandy Chung wrote: > >> On 9/3/13 11:11 AM, Peter Levart wrote: >>> On 09/03/2013 07:41 PM, David M. Lloyd wrote: >>>>> What about a simple restriction on methods returning such instances that >>>>> Class objects are only returned when they are resolvable from the >>>>> ClassLoader of client code. If they are not resolvable, null is >>>>> returned. For example, the equivalent of: >>>>> >>>> >>>> I don't think this will hold up. Why would (for example) a logging API >>>> have access to every class loader that might need to log something? In >>>> any system of appreciable size, there is typically at least *some* class >>>> loader isolation, often a lot of it. Utilities like logging or security >>>> code that need to do this kind of check do not typically have direct >>>> access to classes which are "higher on the stack", so to speak. >>> >>> Ok, I understand. What about the other way around - would this be >>> acceptable from security perspective (asking Mandy?): >> >> I don't think that works for log4j either. In general we should only allow >> a ClassLoader A to access classes loaded by a ClassLoader B only if B trusts >> A (i.e A is the same or an ancestor of B); otherwise some kind of permission >> check (e.g. package access) is required. Log4j wants to access all Class >> instances on the stack for diagnosibility purpose and unless Log4j is loaded >> by the bootstrap class loader (put -Xbootclasspath) it may not be able to >> get access to all classes via Class.forName call. >> >> This would probably need a coarse-grained permission than a fine-grained >> permission check on the indivdual stack frame subject to the >> ClassLoader/Class. >> >> Mandy >> >>> >>> - If you can see me (by name), then you're exposed (I can get you): >>> >>> public class StackTraceFrame { >>> >>> private final Class<?> declaringClass; >>> >>> @CallerSensitive >>> public Class<?> getDeclaringClass() { >>> try { >>> Class<?> cc = Reflection.getCallerClass(); >>> return Class.forName(cc.getName(), >>> false, >>> declaringClass.getClassLoader()) >>> == cc ? declaringClass : null; >>> >>> } catch (ClassNotFoundException ignore) {} >>> return null; >>> } >>> >>> >>> This would not present a problem for JDK system classes since they can not >>> see client code. >> >