Replacement of sun.reflect.Reflection#getCallerClass
Nick Williams
nicholas+openjdk at nicholaswilliams.net
Tue Sep 3 14:39:12 UTC 2013
On Sep 3, 2013, at 9:30 AM, Mandy Chung wrote:
>
> On 9/3/2013 5:52 AM, Nick Williams wrote:
>> Do, I don't understand the rationale. Alan said the security issues couldn't be discussed openly. I can get a Class object MANY different ways without a security check. I don't see or understand any vulnerabilities here. I'm going to need much more information in order to contribute to the discussion in an informed manner.
>
> The Java security guideline is a good starting point.
> http://www.oracle.com/technetwork/java/seccodeguide-139067.html#4
>> And, has been stated many, many times, this non-goal is incompatible with the community's needs. Now, there /is/ a way to avoid making @CallerSensitive public (which the community doesn't care about) while still making getCallerClass public (which is really what the community needs). In order to do so, you must remove the check that requires the method calling getCallerClass/getCallerFrame to be annotated with @CallerSensitive. Once you remove that check, you don't need @CallerSensitive to be public. To be clear, though, once you remove that check, you don't need @CallerSensitive /at all/. It can simply go away.
>
> Do you mean sun.reflect.CallerSensitive can go away? This is very important part of the design that we need to detect which methods are caller-sensitive. I keep seeing you suggest this and it is unclear to me if you only mean to remove java.lang. at CallerSensitive in your proposal.
Yes, that's what I mean. If you carefully examine the (existing) native code that backs getCallerClass, you see that @CallerSensitive is /only/ used as an enforcement mechanism. When I first read about @CallerSensitive, I /thought/ you could take a call stack like this one:
@CallerSensitive getCallerClass()
@CallerSensitive someMethod1()
@CallerSensitive someMethod2()
@CallerSensitive someMethod3()
@CallerSensitive someMethod4()
actualCallerMethod()
And calling getCallerClass would return the class for actualCallerMethod(). However, I was wrong. getCallerClass /always/ returns someMethod1(). @CallerSensitive is /not/ used to determine when to stop looking for the caller. It's just an enforcement mechanism to ensure that only built-in JVM classes can call getCallerClass. This is /not/ how I did it, this is how it already was. Because of this, you could delete the @CallerSensitive annotation completely and getCallerClass still be fully functional the way it is. It just wouldn't be restricted to annotated methods anymore.
Note: Now, to be honest, being able to keep going down the chain until you find actualCallerMethod() would be nice, but that presents its own challenges (what if actualCallerMethod is @CallerSensitive for a completely different purpose, for example?), so I don't think that would work.
Nick
More information about the core-libs-dev
mailing list