1919 */
2020package org .xwiki .velocity .introspection ;
2121
22+ import java .io .File ;
23+ import java .util .HashMap ;
2224import java .util .HashSet ;
25+ import java .util .Map ;
2326import java .util .Set ;
2427
2528import org .apache .velocity .util .introspection .SecureIntrospectorImpl ;
3336 */
3437public class SecureIntrospector extends SecureIntrospectorImpl
3538{
36- private final Set <String > secureClassMethods = new HashSet <>();
39+ private static final String GETNAME = "getname" ;
40+ private final Map <Class , Set <String >> whitelistedMethods ;
3741
3842 /**
3943 * @param badClasses forbidden classes
@@ -44,41 +48,80 @@ public SecureIntrospector(String[] badClasses, String[] badPackages, Logger log)
4448 {
4549 super (badClasses , badPackages , log );
4650
47- this .secureClassMethods . add ( "getname" );
48- this .secureClassMethods . add ( "getName" );
49- this .secureClassMethods . add ( "getsimpleName" );
50- this . secureClassMethods . add ( "getSimpleName" );
51+ this .whitelistedMethods = new HashMap <>( );
52+ this .prepareWhitelistClass ( );
53+ this .prepareWhiteListFile ( );
54+ }
5155
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" );
56+ private void prepareWhitelistClass ()
57+ {
58+ Set <String > whitelist = new HashSet <>();
59+ whitelist .add (GETNAME );
60+ whitelist .add ("getsimpleName" );
61+ whitelist .add ("isarray" );
62+ whitelist .add ("isassignablefrom" );
63+ whitelist .add ("isenum" );
64+ whitelist .add ("isinstance" );
65+ whitelist .add ("isinterface" );
66+ whitelist .add ("islocalclass" );
67+ whitelist .add ("ismemberclass" );
68+ whitelist .add ("isprimitive" );
69+ whitelist .add ("issynthetic" );
70+ whitelist .add ("getenumconstants" );
71+ this .whitelistedMethods .put (Class .class , whitelist );
72+ }
7173
72- // TODO: add more when needed
74+ private void prepareWhiteListFile ()
75+ {
76+ Set <String > whitelist = new HashSet <>();
77+ whitelist .add ("canexecute" );
78+ whitelist .add ("canread" );
79+ whitelist .add ("canwrite" );
80+ whitelist .add ("compareto" );
81+ whitelist .add ("createtempfile" );
82+ whitelist .add ("equals" );
83+ whitelist .add ("getabsolutefile" );
84+ whitelist .add ("getabsolutePath" );
85+ whitelist .add ("getcanonicalfile" );
86+ whitelist .add ("getcanonicalpath" );
87+ whitelist .add ("getfreespace" );
88+ whitelist .add (GETNAME );
89+ whitelist .add ("getparent" );
90+ whitelist .add ("getparentFile" );
91+ whitelist .add ("getpath" );
92+ whitelist .add ("gettotalspace" );
93+ whitelist .add ("getusablespace" );
94+ whitelist .add ("hashcode" );
95+ whitelist .add ("isabsolute" );
96+ whitelist .add ("isdirectory" );
97+ whitelist .add ("isfile" );
98+ whitelist .add ("ishidden" );
99+ whitelist .add ("lastmodified" );
100+ whitelist .add ("length" );
101+ whitelist .add ("topath" );
102+ whitelist .add ("tostring" );
103+ whitelist .add ("touri" );
104+ whitelist .add ("tourl" );
105+ whitelist .add ("getclass" );
106+ this .whitelistedMethods .put (File .class , whitelist );
73107 }
74108
75109 @ Override
76110 public boolean checkObjectExecutePermission (Class clazz , String methodName )
77111 {
78- if (Class .class .isAssignableFrom (clazz ) && methodName != null && this .secureClassMethods .contains (methodName )) {
79- return true ;
80- } else {
81- return super .checkObjectExecutePermission (clazz , methodName );
112+ Boolean result = null ;
113+ if (methodName != null ) {
114+ for (Map .Entry <Class , Set <String >> classSetEntry : this .whitelistedMethods .entrySet ()) {
115+ if (classSetEntry .getKey ().isAssignableFrom (clazz )) {
116+ result = classSetEntry .getValue ().contains (methodName .toLowerCase ());
117+ break ;
118+ }
119+ }
120+ }
121+
122+ if (result == null ) {
123+ result = super .checkObjectExecutePermission (clazz , methodName );
82124 }
125+ return result ;
83126 }
84127}
0 commit comments