Uploaded image for project: 'Apache Freemarker'
  1. Apache Freemarker
  2. FREEMARKER-121

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.

    XMLWordPrintableJSON

Details

    • New Feature
    • Status: Resolved
    • Minor
    • Resolution: Fixed
    • 2.3.29
    • 2.3.30
    • engine
    • None

    Description

      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

       

      ${obj.class}
      

      or 

       

       

      ${obj.getClass()}
      

       

       

      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()).  

      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

       

      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:

       

      objWrapper.setMethodAppearanceFineTuner(new MethodAppearanceFineTuner() {
      			
      			@Override
      			public void process(MethodAppearanceDecisionInput in, MethodAppearanceDecision out) {
      				
      				if(in.getMethod().getName().contains("getClass")){
      					// hide method
      					out.setExposeMethodAs(null);
      				}
      			}
      		});
      

      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.

      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.

       

      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.

       

       

      Attachments

        Activity

          People

            Unassigned Unassigned
            mephiztophelez Christoph Rueger
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: