You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@velocity.apache.org by Paulo Gaspar <pa...@krankikom.de> on 2001/03/19 17:26:52 UTC

The introspection / security issue and possible solution [WAS: cvs commit: jakarta-velocity/src/java/org/apache/velocity/servletVelocityServlet.java]

The issue is related with template side access to methods of an 
object pushed into its context being determined by the underlying
object class and not by the interface (that references that 
underlying object) used to push it into the context.

I think it is not a bug, just a limitation of Java and Velocity 
introspection.


Let's RTFM:

>From the JDK 1.3 javadocs, for java.lang.reflect.Method.invoke():

  public Object invoke(Object obj,
                       Object[] args)
                throws IllegalAccessException,
                       IllegalArgumentException,
                       InvocationTargetException

  Invokes the underlying method represented by this Method object, on 
  the specified object with the specified parameters.

  ...

  If this Method object enforces Java language access control and the
  underlying method is inaccessible, the invocation throws an 
  IllegalAccessException. 


The 1st key sentence to understand what is going on is
  "Invokes the underlying method represented by this Method object, on 
  the specified object..."

The "underlying method" and "specified object" expressions together with 
the 1st invoke() parameter being of type Object ("Object obj") strongly
suggest that Java doesn't give a sh** about what is the type of the 
variable that you use to pass the object to which the invoked method 
belongs.

What java does care about is the underlying object. It directly 
introspects - extracts Runtime Type Information - from the underlying
object. 

So, Java jumps over any interface you use to reference an Object X and 
goes straight to that Object X - with all the access right consequences
this involves.


* Even if this is not completely correct and the access to a method 
  depends on it being obtained from the underlying object class's Class
  or from the used interface's Class, the fact is that Velocity 
  introspection code will find the underlying object class's Class and 
  not the one of the interface the user used to push an object into the 
  context.

(Aren't you lost yet?)


However, the JDK javadocs text above also states:
  "If this Method object enforces Java language access control..."

and the Method class descends from the AccessibleObject class! Let's
see what the JDK says about this one:
  The AccessibleObject class is the base class for Field, Method and
  Constructor objects. It provides the ability to flag a reflected 
  object as suppressing default Java language access control checks
  when it is used. The access checks--for public, default (package)
  access, protected, and private members--are performed when Fields,
  Methods or Constructors are used to set or get fields, to invoke
  methods, or to create and initialize new instances of classes,
  respectively. 

  Setting the accessible flag in a reflected object permits 
  sophisticated applications with sufficient privilege, such as Java 
  Object Serialization or other persistence mechanisms, to manipulate 
  objects in a manner that would normally be prohibited. 

This last paragraph is especially clear about the possibilities.

And the method "setAccessible(boolean flag)" looks interesting too:
  public void setAccessible(boolean flag)
                   throws SecurityException
  Set the accessible flag for this object to the indicated boolean
  value. A value of true indicates that the reflected object should 
  suppress Java language access checking when it is used. A value of 
  false indicates that the reflected object should enforce Java 
  language access checks. 


So, this could be a way to go around the security limitations of 
introspection... 
 - But do we really want to do this? Do we really want to expose all 
   the internals of a passed object to the template code? Even those 
   that are not exposed by public interfaces?
 - And when not, how do we tell to Velocity introspection code which
   methods it should allow public access and which it should not? One
   can set access method by method, but how can Velocity 
   introspection code "know" which methods access rights it should 
   override?
   (One would have to pass at least another parameter to the context
   associated with the Object value -> a reference to the interface 
   that Velocity should use to access it.)


In the end, maybe the wrapper is the right/simple solution.


Have fun,
Paulo Gaspar