2424import org .apache .avro .io .ResolvingDecoder ;
2525import org .apache .avro .util .ClassUtils ;
2626import java .io .IOException ;
27+ import java .util .ArrayList ;
28+ import java .util .Arrays ;
29+ import java .util .List ;
2730
2831/**
2932 * {@link org.apache.avro.io.DatumReader DatumReader} for generated Java
3033 * classes.
3134 */
3235public class SpecificDatumReader <T > extends GenericDatumReader <T > {
36+
37+ public static final String [] SERIALIZABLE_PACKAGES ;
38+
39+ static {
40+ SERIALIZABLE_PACKAGES = System .getProperty ("org.apache.avro.SERIALIZABLE_PACKAGES" ,
41+ "java.lang,java.math,java.io,java.net,org.apache.avro.reflect" ).split ("," );
42+ }
43+
44+ private List <String > trustedPackages = new ArrayList <String >();
45+ private boolean trustAllPackages = false ;
46+
3347 public SpecificDatumReader () {
3448 this (null , null , SpecificData .get ());
3549 }
@@ -55,6 +69,7 @@ public SpecificDatumReader(Schema writer, Schema reader) {
5569 */
5670 public SpecificDatumReader (Schema writer , Schema reader , SpecificData data ) {
5771 super (writer , reader , data );
72+ trustedPackages .addAll (Arrays .asList (SERIALIZABLE_PACKAGES ));
5873 }
5974
6075 /** Construct given a {@link SpecificData}. */
@@ -101,12 +116,43 @@ private Class getPropAsClass(Schema schema, String prop) {
101116 if (name == null )
102117 return null ;
103118 try {
104- return ClassUtils .forName (getData ().getClassLoader (), name );
119+ Class clazz = ClassUtils .forName (getData ().getClassLoader (), name );
120+ checkSecurity (clazz );
121+ return clazz ;
105122 } catch (ClassNotFoundException e ) {
106123 throw new AvroRuntimeException (e );
107124 }
108125 }
109126
127+ private boolean trustAllPackages () {
128+ return trustAllPackages || (trustedPackages .size () == 1 && trustedPackages .get (0 ).equals ("*" ));
129+ }
130+
131+ private void checkSecurity (Class clazz ) throws ClassNotFoundException {
132+ if (trustAllPackages () || clazz .isPrimitive ()) {
133+ return ;
134+ }
135+
136+ boolean found = false ;
137+ Package thePackage = clazz .getPackage ();
138+ if (thePackage != null ) {
139+ for (String trustedPackage : getTrustedPackages ()) {
140+ if (thePackage .getName ().equals (trustedPackage ) || thePackage .getName ().startsWith (trustedPackage + "." )) {
141+ found = true ;
142+ break ;
143+ }
144+ }
145+ if (!found ) {
146+ throw new ClassNotFoundException ("Forbidden " + clazz
147+ + "! This class is not trusted to be included in Avro schema using java-class. Please set org.apache.avro.SERIALIZABLE_PACKAGES system property with the packages you trust." );
148+ }
149+ }
150+ }
151+
152+ public List <String > getTrustedPackages () {
153+ return trustedPackages ;
154+ }
155+
110156 @ Override
111157 protected Object readRecord (Object old , Schema expected , ResolvingDecoder in ) throws IOException {
112158 SpecificData data = getSpecificData ();
0 commit comments