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