Replacement of sun.reflect.Reflection#getCallerClass

David M. Lloyd david.lloyd at redhat.com
Tue Sep 3 18:47:43 UTC 2013


On 09/03/2013 01:11 PM, Peter Levart wrote:
> On 09/03/2013 07:41 PM, David M. Lloyd wrote:
>>> Now for that part, the public API equivalent
>>> (StackTraceFrame.getCallerClass() or whatever it is called) need not be
>>> restricted to methods annotated with any annotation, but that means that
>>> this public API should not be used to implement security decisions since
>>> MethodHandles API allows caller to be spoofed unless looking-up a method
>>> annotated with @CallerSensitive...
>>
>> Using an annotation for security decisions is pretty far off from the
>> standard security model in any case.  Why not use a regular permission
>> check?  If performance is a concern, the check need only be made one
>> time when an instance is acquired that has these methods on it.
>
> What permission check? @CallerSensitive methods are typically public
> methods in public classes. Anyone can call them, but no-one should be
> able to spoof the caller.

Is there some place I can find more information about this (somewhat 
worrying) aspect of MethodHandles?  If this problem applies to 
getCallerClass() then I'm guessing it applies to SecurityManager's 
getClassContext() as well, which definitely is used to make security 
decisions.  And what about AccessControlContext and its interactions 
with the call stack?  Same problem?

> 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?):
>
> - 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.

I'm not sure this solves any real use case either though.  In the 
logging case, you may want to get (for example) the code source of 
everyone on the stack regardless of whether they can "see" your library. 
  In the end I think there should be a way for a (privileged) caller to 
get all the information directly.
-- 
- DML



More information about the core-libs-dev mailing list