1919 */
2020package org .xwiki .velocity .introspection ;
2121
22+ import java .io .File ;
23+ import java .util .Arrays ;
24+ import java .util .HashMap ;
2225import java .util .HashSet ;
26+ import java .util .Map ;
2327import java .util .Set ;
2428
2529import org .apache .velocity .util .introspection .SecureIntrospectorImpl ;
3337 */
3438public class SecureIntrospector extends SecureIntrospectorImpl
3539{
36- private final Set <String > secureClassMethods = new HashSet <>();
40+ private static final String GETNAME = "getname" ;
41+ private final Map <Class , Set <String >> whitelistedMethods ;
3742
3843 /**
3944 * @param badClasses forbidden classes
@@ -44,41 +49,82 @@ public SecureIntrospector(String[] badClasses, String[] badPackages, Logger log)
4449 {
4550 super (badClasses , badPackages , log );
4651
47- this .secureClassMethods . add ( "getname" );
48- this .secureClassMethods . add ( "getName" );
49- this .secureClassMethods . add ( "getsimpleName" );
50- this . secureClassMethods . add ( "getSimpleName" );
52+ this .whitelistedMethods = new HashMap <>( );
53+ this .prepareWhitelistClass ( );
54+ this .prepareWhiteListFile ( );
55+ }
5156
52- this .secureClassMethods .add ("isarray" );
53- this .secureClassMethods .add ("isArray" );
54- this .secureClassMethods .add ("isassignablefrom" );
55- this .secureClassMethods .add ("isAssignableFrom" );
56- this .secureClassMethods .add ("isenum" );
57- this .secureClassMethods .add ("isEnum" );
58- this .secureClassMethods .add ("isinstance" );
59- this .secureClassMethods .add ("isInstance" );
60- this .secureClassMethods .add ("isinterface" );
61- this .secureClassMethods .add ("isInterface" );
62- this .secureClassMethods .add ("islocalClass" );
63- this .secureClassMethods .add ("isLocalClass" );
64- this .secureClassMethods .add ("ismemberclass" );
65- this .secureClassMethods .add ("isMemberClass" );
66- this .secureClassMethods .add ("isprimitive" );
67- this .secureClassMethods .add ("isPrimitive" );
68- this .secureClassMethods .add ("issynthetic" );
69- this .secureClassMethods .add ("isSynthetic" );
70- this .secureClassMethods .add ("getEnumConstants" );
57+ private void prepareWhitelistClass ()
58+ {
59+ Set <String > whitelist = new HashSet <>(Arrays .asList (
60+ GETNAME ,
61+ "getsimpleName" ,
62+ "isarray" ,
63+ "isassignablefrom" ,
64+ "isenum" ,
65+ "isinstance" ,
66+ "isinterface" ,
67+ "islocalclass" ,
68+ "ismemberclass" ,
69+ "isprimitive" ,
70+ "issynthetic" ,
71+ "getenumconstants"
72+ ));
73+ this .whitelistedMethods .put (Class .class , whitelist );
74+ }
7175
72- // TODO: add more when needed
76+ private void prepareWhiteListFile ()
77+ {
78+ Set <String > whitelist = new HashSet <>(Arrays .asList (
79+ "canexecute" ,
80+ "canread" ,
81+ "canwrite" ,
82+ "compareto" ,
83+ "createtempfile" ,
84+ "equals" ,
85+ "getabsolutefile" ,
86+ "getabsolutepath" ,
87+ "getcanonicalfile" ,
88+ "getcanonicalpath" ,
89+ "getfreespace" ,
90+ GETNAME ,
91+ "getparent" ,
92+ "getparentfile" ,
93+ "getpath" ,
94+ "gettotalspace" ,
95+ "getusablespace" ,
96+ "hashcode" ,
97+ "isabsolute" ,
98+ "isdirectory" ,
99+ "isfile" ,
100+ "ishidden" ,
101+ "lastmodified" ,
102+ "length" ,
103+ "topath" ,
104+ "tostring" ,
105+ "touri" ,
106+ "tourl" ,
107+ "getclass"
108+ ));
109+ this .whitelistedMethods .put (File .class , whitelist );
73110 }
74111
75112 @ Override
76113 public boolean checkObjectExecutePermission (Class clazz , String methodName )
77114 {
78- if (Class .class .isAssignableFrom (clazz ) && methodName != null && this .secureClassMethods .contains (methodName )) {
79- return true ;
80- } else {
81- return super .checkObjectExecutePermission (clazz , methodName );
115+ Boolean result = null ;
116+ if (methodName != null ) {
117+ for (Map .Entry <Class , Set <String >> classSetEntry : this .whitelistedMethods .entrySet ()) {
118+ if (classSetEntry .getKey ().isAssignableFrom (clazz )) {
119+ result = classSetEntry .getValue ().contains (methodName .toLowerCase ());
120+ break ;
121+ }
122+ }
123+ }
124+
125+ if (result == null ) {
126+ result = super .checkObjectExecutePermission (clazz , methodName );
82127 }
128+ return result ;
83129 }
84130}
0 commit comments