[
https://issues.apache.org/jira/browse/FREEMARKER-121?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Christoph Rueger updated FREEMARKER-121:
----------------------------------------
Description:
h2. Problem description
We want to "hide" certain class members (methods, fields, properties) so that
they are not accessible from templates. The problem is based on a discussion
about white-list / black-list of accessible class members.
One example is preventing that one might call
{code:java}
${obj.class}
{code}
or
{code:java}
${obj.getClass()}
{code}
h2. Why
In our plugin system, FM-templates and objects accessible in the FM-Context are
coming from external users and which are not our developers.
We need a way to forbid some methods and fields (blacklist approach) which are
considered harmful or dangerous (like .getClass()).
h2. What
We wish to be able to do two things:
* define a *whitelist* of classes, methods, fields which are allowed to be
accessed
* define a *blacklist* of classes, methods, fields which are NEVER allowed to
be accessed
** the *blacklist* also servers as a safety guard against developer mistakes,
which mistakenly whitelisted something by accident
h2. What is already there?
Freemarker currently has *MethodAppearanceFineTuner* which can be injected to
the ObjectWrapper.
It allows you to e.g. prevent access to _${obj.getClass()}_ method like this:
{code:java}
objWrapper.setMethodAppearanceFineTuner(new MethodAppearanceFineTuner() {
@Override
public void process(MethodAppearanceDecisionInput in,
MethodAppearanceDecision out) {
if(in.getMethod().getName().contains("getClass")){
// hide method
out.setExposeMethodAs(null);
}
}
});
{code}
But currently it does *not* allow you to hide the property. That means
_${obj.class}_ is still possible.
There is also something like
_freemarker.ext.beans.UnsafeMethods.isUnsafeMethod(Method)_ in the code base,
which is missing _.getClass()_ and cannot be changed because it wouldn't be
backwards compatible.
A discussion with [~ddekany] by email pointed in the direction:
?? the point that need to be customizable is
ClassIntrospector.isAllowedToExpose.??
h2. How
The how is currently up for discussion. A very simplistic POC-approach using
MethodAppearanceFineTuner can be found in this commit
[https://github.com/chrisrueger/freemarker/commit/a2ff9a7f1d474bdb7774e2d794812f1e6f7ae06b]
(only a base for discussion)
Keywords: Maybe a mix of different hooks for doing it programmatically (e.g.
_ClassIntrospector.isAllowedToExpose_ or similar to MethodAppearanceFineTuner),
.properties files, annotations are coming to mind.
h3.
h3. Side Note on OSGI / Classloaders
We are living in an OSGI-world of multiple bundles with each having a different
class loader.
So it would be good to have a way to let other bundles (with different
classloader) define their own rules / hooks too, without requiring the
objectWrapper to know about the class added to freemarker. Maybe this OSGI
part does not belong to this issue exactly but I wanted to bring it up as it
might be a constraint for the solution.
was:
h2. Problem description
We want to "hide" certain class members (methods, fields, properties) so that
they are not accessible from templates. The problem is based on a discussion
about white-list / black-list of accessible class members.
One example is preventing that one might call
{code:java}
${obj.class}
{code}
or
{code:java}
${obj.getClass()}
{code}
h2. Why
In our plugin system, FM-templates and objects accessible in the FM-Context are
coming from external users and which are not our developers.
We need a way to forbid some methods and fields (blacklist approach) which are
considered harmful or dangerous (like .getClass()).
h2. What
We wish to be able to do two things:
* define a *whitelist* of classes, methods, fields which are allowed to be
accessed
* define a *blacklist* of classes, methods, fields which are NEVER allowed to
be accessed
** the *blacklist* also servers as a safety guard against developer mistakes,
which mistakenly whitelisted something by accident
h2. What is already there?
Freemarker currently has *MethodAppearanceFineTuner* which can be injected to
the ObjectWrapper.
It allows you to e.g. prevent access to _${obj.getClass()}_ method like this:
{code:java}
objWrapper.setMethodAppearanceFineTuner(new MethodAppearanceFineTuner() {
@Override
public void process(MethodAppearanceDecisionInput in,
MethodAppearanceDecision out) {
if(in.getMethod().getName().contains("getClass")){
// hide method
out.setExposeMethodAs(null);
}
}
});
{code}
But currently it does *not* allow you to hide the property. That means
_${obj.class}_ is still possible.
There is also something like
_freemarker.ext.beans.UnsafeMethods.isUnsafeMethod(Method)_ in the code base,
which is missing _.getClass()_ and cannot be changed because it wouldn't be
backwards compatible.
A discussion with [~ddekany] by email pointed in the direction:
?? the point that need to be customizable is
ClassIntrospector.isAllowedToExpose.??
h2. How
The how is currently up for discussion. A very simplistic POC-approach using
MethodAppearanceFineTuner can be found in this commit
https://github.com/chrisrueger/freemarker/commit/a2ff9a7f1d474bdb7774e2d794812f1e6f7ae06b
Keywords: Maybe a mix of different hooks for doing it programmatically (e.g.
_ClassIntrospector.isAllowedToExpose_ or similar to MethodAppearanceFineTuner),
.properties files, annotations are coming to mind.
h3.
h3. Side Note on OSGI / Classloaders
We are living in an OSGI-world of multiple bundles with each having a different
class loader.
So it would be good to have a way to let other bundles (with different
classloader) define their own rules / hooks too, without requiring the
objectWrapper to know about the class added to freemarker. Maybe this OSGI
part does not belong to this issue exactly but I wanted to bring it up as it
might be a constraint for the solution.
> Pluggable filtering of template accessible class members, as
> unsafeMethods.properties is clearly not useful if you want to allow people
> outside the developer team to provide templates.
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: FREEMARKER-121
> URL: https://issues.apache.org/jira/browse/FREEMARKER-121
> Project: Apache Freemarker
> Issue Type: New Feature
> Components: engine
> Affects Versions: 2.3.29
> Reporter: Christoph Rueger
> Priority: Minor
>
> h2. Problem description
> We want to "hide" certain class members (methods, fields, properties) so that
> they are not accessible from templates. The problem is based on a discussion
> about white-list / black-list of accessible class members.
> One example is preventing that one might call
>
> {code:java}
> ${obj.class}
> {code}
> or
>
>
> {code:java}
> ${obj.getClass()}
> {code}
>
>
> h2. Why
> In our plugin system, FM-templates and objects accessible in the FM-Context
> are coming from external users and which are not our developers.
> We need a way to forbid some methods and fields (blacklist approach) which
> are considered harmful or dangerous (like .getClass()).
> h2. What
> We wish to be able to do two things:
> * define a *whitelist* of classes, methods, fields which are allowed to be
> accessed
> * define a *blacklist* of classes, methods, fields which are NEVER allowed
> to be accessed
> ** the *blacklist* also servers as a safety guard against developer
> mistakes, which mistakenly whitelisted something by accident
>
> h2. What is already there?
> Freemarker currently has *MethodAppearanceFineTuner* which can be injected to
> the ObjectWrapper.
> It allows you to e.g. prevent access to _${obj.getClass()}_ method like this:
>
> {code:java}
> objWrapper.setMethodAppearanceFineTuner(new MethodAppearanceFineTuner() {
>
> @Override
> public void process(MethodAppearanceDecisionInput in,
> MethodAppearanceDecision out) {
>
>
> if(in.getMethod().getName().contains("getClass")){
> // hide method
> out.setExposeMethodAs(null);
> }
> }
> });
> {code}
> But currently it does *not* allow you to hide the property. That means
> _${obj.class}_ is still possible.
> There is also something like
> _freemarker.ext.beans.UnsafeMethods.isUnsafeMethod(Method)_ in the code base,
> which is missing _.getClass()_ and cannot be changed because it wouldn't be
> backwards compatible.
>
> A discussion with [~ddekany] by email pointed in the direction:
> ?? the point that need to be customizable is
> ClassIntrospector.isAllowedToExpose.??
> h2. How
> The how is currently up for discussion. A very simplistic POC-approach using
> MethodAppearanceFineTuner can be found in this commit
> [https://github.com/chrisrueger/freemarker/commit/a2ff9a7f1d474bdb7774e2d794812f1e6f7ae06b]
> (only a base for discussion)
> Keywords: Maybe a mix of different hooks for doing it programmatically (e.g.
> _ClassIntrospector.isAllowedToExpose_ or similar to
> MethodAppearanceFineTuner), .properties files, annotations are coming to mind.
> h3.
> h3. Side Note on OSGI / Classloaders
> We are living in an OSGI-world of multiple bundles with each having a
> different class loader.
> So it would be good to have a way to let other bundles (with different
> classloader) define their own rules / hooks too, without requiring the
> objectWrapper to know about the class added to freemarker. Maybe this OSGI
> part does not belong to this issue exactly but I wanted to bring it up as it
> might be a constraint for the solution.
>
>
--
This message was sent by Atlassian Jira
(v8.3.4#803005)