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 <[email protected]> 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.
>>
>